Files
homeclaw/.smallclaw/databases/translate_pcsp.py
T
kimandClaude Sonnet 4.6 508d11615a Add user workspaces, dental DB scripts, server memory + code editor improvements
- cherry: orofacial/TMD PPTX presentations + 음악가 구강건강 가이드
- papa: sinus/infraoccluded PPTX, garden-monitor Arduino, MIDI files
- databases: PCSP scraper, translation scripts, vision benchmark, batch JSONs
- web-ui: code.js/companion.py/styles.css major updates, autostart installer
- src: ollama-client, session, LLMProvider, ollama-adapter patches
- .gitignore: add claude-key, SQLite WAL/SHM, __pycache__, nohup.out

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 23:13:03 +09:00

299 lines
12 KiB
Python

#!/usr/bin/env python3
"""Fast batch translate PCSP titles using pattern-based approach + key term mapping.
For case_study types, creates more detailed translations.
For commentary/response types, creates shorter descriptive translations."""
import sqlite3
import re
import html
DB_PATH = "/home/kim/homeclaw/.smallclaw/databases/psychotherapy_cases.db"
# Comprehensive term mapping (longest first for proper matching)
TERM_MAP = [
# Therapy approaches (long phrases first)
("Accelerated Experiential Dynamic Psychotherapy", "가속적경험적역동치료"),
("Accelerated Experiential Dynamic", "가속적경험적역동"),
("Emotionally Focused Couple Therapy", "정서초점부부치료"),
("Emotionally Focused Therapy", "정서초점치료"),
("Affect Phobia Therapy", "정서공포치료"),
("Affect Phobia", "정서공포"),
("Regulation Focused Psychotherapy for Children", "아동조절초점치료"),
("Regulation Focused Psychotherapy", "조절초점치료"),
("Dialectical Behavior Therapy", "변증법적행동치료"),
("Cognitive Behavioral Therapy", "인지행동치료"),
("Cognitive-Behavioral Therapy", "인지행동치료"),
("Cognitive Behavior Therapy", "인지행동치료"),
("Short-Term Psychodynamic Psychotherapy", "단기정신역동치료"),
("Short-Term Psychodynamic", "단기정신역동"),
("Written Exposure Therapy", "작성노출치료"),
("Exposure and Response Prevention", "노출및반응방지"),
("Exposure Therapy", "노출치료"),
("Prolonged Exposure", "지속노출"),
("Schema Therapy", "도식치료"),
("Narrative Therapy", "내러티브치료"),
("Solution-Focused Brief Therapy", "해결중심단기치료"),
("Solution-Focused", "해결중심"),
("Client-Centered Psychotherapy", "내담자중심치료"),
("Client-Centered Therapy", "내담자중심치료"),
("Person-Centered Therapy", "인간중심치료"),
("Psychodynamic Psychotherapy", "정신역동치료"),
("Psychodynamic Therapy", "정신역동치료"),
("Dynamic Psychotherapy", "역동치료"),
("Psychoanalytic Therapy", "정신분석치료"),
("Integrative Psychotherapy", "통합심리치료"),
("Integrative Therapy", "통합치료"),
("Group Cognitive Behavioral", "집단인지행동"),
("Group Therapy", "집단치료"),
("Couple Therapy", "부부치료"),
("Couples Therapy", "부부치료"),
("Family Therapy", "가족치료"),
("Acceptance and Commitment Therapy", "수용전념치료"),
("Paradoxical Intention", "역설적의도"),
("Mentalization", "정신화"),
("Mindfulness-Based", "마음챙김기반"),
("Mindfulness", "마음챙김"),
("Hypnosis", "최면"),
("Hypnotherapy", "최면치료"),
("Hypnotic", "최면"),
("Psychotherapy", "심리치료"),
("psychotherapy", "심리치료"),
# Disorders
("Post-Traumatic Stress Disorder", "외상후스트레스장애"),
("Posttraumatic Stress Disorder", "외상후스트레스장애"),
("Complex PTSD", "복합외상후스트레스장애"),
("Obsessive-Compulsive Disorder", "강박장애"),
("Obsessive Compulsive Disorder", "강박장애"),
("Borderline Personality Disorder", "경계선인격장애"),
("Bipolar Disorder", "양극성장애"),
("Panic Disorder", "공황장애"),
("Anxiety Disorders", "불안장애"),
("Anxiety Disorder", "불안장애"),
("Social Phobia", "사회공포증"),
("Social Anxiety", "사회불안"),
("Obsessive-Compulsive", "강박"),
("Obsessive Compulsive", "강박"),
("Alcohol Use Disorder", "알코올사용장애"),
("Alcohol Abuse", "알코올남용"),
("Body Dysmorphic", "신체이형"),
("Attention Deficit Hyperactivity Disorder", "주의력결핍과다행동장애"),
("Tourette Syndrome", "투렛증후군"),
("Agoraphobia", "광장공포증"),
("Relational Trauma", "관계적외상"),
("Developmental Disability", "발달장애"),
("Developmental Disabilities", "발달장애"),
("Executive Dysfunction", "실행기능장애"),
("Cognitive Difficulties", "인지어려움"),
("Externalizing Behavior", "외현화행동"),
("Conduct Problem", "품행문제"),
("Child Maltreatment", "아동학대"),
("Masculinity Norms", "남성성규범"),
("Inflexibly Enacted Traditional Masculinity", "경직된전통적남성성"),
("Suicide Prevention", "자살예방"),
("Psychosis", "정신병"),
("Psychotic", "정신병적"),
("Schizophrenia", "조현병"),
("Depression", "우울증"),
("Depressive", "우울"),
("Anxiety", "불안"),
("Trauma", "외상"),
("Traumatic", "외상"),
("PTSD", "외상후스트레스장애"),
("OCD", "강박장애"),
("BPD", "경계선인격장애"),
("DBT", "변증법적행동치료"),
("CBT", "인지행동치료"),
("ACT", "수용전념치료"),
("EFT", "정서초점치료"),
("AEDP", "가속적경험적역동치료"),
# Common patterns
("Case Study", "사례연구"),
("case study", "사례연구"),
("Case Formulation", "사례공식화"),
("Theory-Building", "이론구축"),
("Theory Building", "이론구축"),
("Practice-Based Evidence", "실천기반근거"),
("Evidence-Based Practice", "근거기반실천"),
("Evidence-Based", "근거기반"),
("Outcome Management", "결과관리"),
("Therapeutic Alliance", "치료적동맹"),
("Working Alliance", "작업동맹"),
("Autobiographical Memory", "자전적기억"),
("Religious Delusion", "종교적망상"),
("Altered State of Consciousness", "변된의식상태"),
("Three-Party Dialogue", "3자대화"),
("Incredible Years", "인크레더블연구"),
("Qualitative Analysis", "질적분석"),
("Qualitative", "질적"),
("Quantitative", "양적"),
("Mixed Methods", "혼합방법"),
("Short-Term", "단기"),
("Long-Term", "장기"),
("Later-Life", "노년기"),
("Late-Life", "노년기"),
("Older Adult", "노인"),
("Young Children", "영유아"),
("Commentary", "논평"),
("commentary", "논평"),
("Commentaries", "논평"),
("Reflections", "고찰"),
("Reflection", "고찰"),
("Response to Commentaries", "논평에 대한 응답"),
("Additional Perspectives", "추가 관점"),
("Introduction", "서론"),
("Clinician-Guided", "임상가안내"),
("Manualized", "매뉴얼화"),
("Self-Help", "자가도움"),
("Telepsych", "원격심리"),
("Online Therapy", "온라인치료"),
("Cultural Competence", "문화적역량"),
("Cultural", "문화적"),
("Multicultural", "다문화"),
("Feminist", "페미니스트"),
("Existential", "실존적"),
("Existentialism", "실존주의"),
("Sociocultural", "사회문화적"),
("Interpersonal", "대인관계"),
("Integrative", "통합적"),
("Integrating", "통합한"),
("Integrating", "~에 통합한"),
("Comparative", "비교"),
("Comparing", "비교"),
("Contrasting", "대조"),
("Methodological", "방법론적"),
("Methodology", "방법론"),
("Systematic", "체계적"),
("Pragmatic", "실용적"),
("Empirical", "실증적"),
("Epistemology", "인식론"),
("Objectivity", "객체성"),
("Causality", "인과성"),
("Clinical", "임상"),
("Therapeutic", "치료적"),
("Adolescent", "청소년"),
("Youth", "청소년"),
("Children", "아동"),
("Child", "아동"),
("Veterans", "참전군인"),
("Veteran", "참전군인"),
("Suicide", "자살"),
("Suicidal", "자살"),
("Treatment", "치료"),
("treatment", "치료"),
("Therapy", "치료"),
("therapy", "치료"),
("Psychotherapy", "심리치료"),
]
def clean_title(title):
"""Clean HTML entities and whitespace."""
title = html.unescape(title)
title = re.sub(r'\s+', ' ', title).strip()
return title
def translate_title(title_en, category_en, category_ko, article_type):
"""Translate title using pattern matching with category-aware fallback."""
title = clean_title(title_en)
if not title:
return ""
# Apply term replacements (longest first)
result = title
for en, ko in TERM_MAP:
# Case-sensitive for proper nouns, case-insensitive for common terms
if en[0].isupper() and len(en) > 3:
result = result.replace(en, ko)
else:
result = re.sub(re.escape(en), ko, result, flags=re.IGNORECASE)
# Clean up spacing
result = re.sub(r'\s+', ' ', result).strip()
# Check translation quality - how much Korean content
korean_chars = len(re.findall(r'[가-힣]', result))
total_chars = len(result.replace(' ', ''))
if total_chars > 0 and korean_chars / total_chars > 0.3:
# Decent translation - clean up any remaining artifacts
result = re.sub(r'\s{2,}', ' ', result).strip()
return result
else:
# Poor translation - use category prefix + original
type_prefix = {
"case_study": "사례연구:",
"commentary": "논평:",
"response": "응답:",
"article": "",
}
prefix = type_prefix.get(article_type, "")
return f"[{category_ko}] {prefix} {title}" if prefix else f"[{category_ko}] {title}"
def main():
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
# Get untranslated titles
c.execute("SELECT id, title_en, category_en, category_ko, article_type FROM cases WHERE title_ko = '' OR title_ko IS NULL ORDER BY id")
rows = c.fetchall()
print(f"Translating {len(rows)} remaining titles...")
translated = 0
partial = 0
fallback = 0
for row in rows:
id_, title_en, cat_en, cat_ko, art_type = row
title_ko = translate_title(title_en, cat_en, cat_ko, art_type)
korean_chars = len(re.findall(r'[가-힣]', title_ko))
total_chars = len(title_ko.replace(' ', ''))
if total_chars > 0 and korean_chars / total_chars > 0.5:
translated += 1
elif total_chars > 0 and korean_chars / total_chars > 0.2:
partial += 1
else:
fallback += 1
c.execute("UPDATE cases SET title_ko = ? WHERE id = ?", (title_ko, id_))
conn.commit()
# Final stats
c.execute("SELECT COUNT(*) FROM cases WHERE title_ko != '' AND title_ko IS NOT NULL")
total_done = c.fetchone()[0]
c.execute("SELECT COUNT(*) FROM cases WHERE title_ko = '' OR title_ko IS NULL")
remaining = c.fetchone()[0]
print(f"\nTranslation stats:")
print(f" Well translated: {translated}")
print(f" Partially translated: {partial}")
print(f" Fallback (category + original): {fallback}")
print(f" Total in DB: {total_done}, Remaining: {remaining}")
# Samples by quality
print("\n--- Well translated samples ---")
c.execute("""SELECT title_en, title_ko FROM cases
WHERE title_ko != '' AND title_ko IS NOT NULL
AND LENGTH(title_ko) - LENGTH(REPLACE(title_ko, ' ', '')) > 3
ORDER BY RANDOM() LIMIT 5""")
for row in c.fetchall():
print(f" EN: {row[0][:80]}")
print(f" KO: {row[1][:80]}")
print()
print("--- Fallback samples ---")
c.execute("""SELECT title_en, title_ko FROM cases
WHERE title_ko LIKE '[%'
ORDER BY RANDOM() LIMIT 5""")
for row in c.fetchall():
print(f" EN: {row[0][:80]}")
print(f" KO: {row[1][:80]}")
print()
conn.close()
if __name__ == "__main__":
main()