Seicas commited on
Commit
b91289f
·
verified ·
1 Parent(s): f4c4b67

Upload advanced_term_correction.py

Browse files
Files changed (1) hide show
  1. advanced_term_correction.py +154 -0
advanced_term_correction.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import difflib
3
+ from typing import Dict, List, Tuple, Any
4
+ import spacy
5
+ from fuzzywuzzy import fuzz
6
+ from medical_terms import load_turkish_medical_terms # .medical_terms -> medical_terms
7
+
8
+ # SpaCy modelini yükle (Türkçe model kurulu olmalı)
9
+ # pip install https://github.com/explosion/spacy-models/releases/download/tr_core_news_md-3.2.0/tr_core_news_md-3.2.0.tar.gz
10
+ try:
11
+ nlp = spacy.load("tr_core_news_md")
12
+ except:
13
+ # Eğer model yüklü değilse
14
+ print("Türkçe SpaCy modeli yüklü değil. Yüklemek için: pip install https://github.com/explosion/spacy-models/releases/download/tr_core_news_md-3.2.0/tr_core_news_md-3.2.0.tar.gz")
15
+ nlp = spacy.blank("tr")
16
+
17
+ try:
18
+ import python_Levenshtein # Opsiyonel hızlandırma
19
+ except ImportError:
20
+ pass # Olmasa da çalışır
21
+
22
+ class MedicalTermCorrector:
23
+ def __init__(self, medical_terms: Dict[str, str], threshold: int = 85):
24
+ """
25
+ Tıbbi terimleri düzeltmek için gelişmiş bir düzeltici
26
+
27
+ Args:
28
+ medical_terms: Tıbbi terimler sözlüğü {yanlış_terim: doğru_terim}
29
+ threshold: Bulanık eşleşme için eşik değeri (0-100)
30
+ """
31
+ self.medical_terms = medical_terms
32
+ self.threshold = threshold
33
+
34
+ # Terimler için regex kalıpları oluştur
35
+ self.regex_patterns = self._build_regex_patterns()
36
+
37
+ # Terim varyasyonları için indeks oluştur
38
+ self.term_variations = self._build_term_variations()
39
+
40
+ def _build_regex_patterns(self) -> Dict[str, re.Pattern]:
41
+ """Tıbbi terimler için regex kalıpları oluşturur"""
42
+ patterns = {}
43
+ for term in self.medical_terms.keys():
44
+ # Basit varyasyon kalıpları: boşluk, tire, kesme işareti varyasyonları
45
+ pattern_str = term.replace(" ", r"\s*")
46
+ pattern_str = pattern_str.replace("-", r"[-\s]?")
47
+ # Türkçe karakter varyasyonları
48
+ pattern_str = re.sub(r'i', r'[iIıİ]', pattern_str)
49
+ pattern_str = re.sub(r'ü', r'[üÜuU]', pattern_str)
50
+ pattern_str = re.sub(r'ö', r'[öÖoO]', pattern_str)
51
+ pattern_str = re.sub(r'ç', r'[çÇcC]', pattern_str)
52
+ pattern_str = re.sub(r'ş', r'[şŞsS]', pattern_str)
53
+ pattern_str = re.sub(r'ğ', r'[ğĞgG]', pattern_str)
54
+ # Daha fazla esneklik için kelime sınırları
55
+ pattern = re.compile(r'\b' + pattern_str + r'\b', re.IGNORECASE)
56
+ patterns[term] = pattern
57
+ return patterns
58
+
59
+ def _build_term_variations(self) -> Dict[str, List[str]]:
60
+ """Olası terim varyasyonları oluşturur"""
61
+ variations = {}
62
+ for term in self.medical_terms.keys():
63
+ term_vars = [term]
64
+ # Boşluk/tire varyasyonları
65
+ if " " in term:
66
+ term_vars.append(term.replace(" ", "-"))
67
+ term_vars.append(term.replace(" ", ""))
68
+ if "-" in term:
69
+ term_vars.append(term.replace("-", " "))
70
+ term_vars.append(term.replace("-", ""))
71
+
72
+ # Küçük/büyük harf varyasyonları
73
+ term_vars.append(term.lower())
74
+ term_vars.append(term.upper())
75
+ term_vars.append(term.capitalize())
76
+
77
+ variations[term] = list(set(term_vars)) # Benzersiz varyasyonlar
78
+ return variations
79
+
80
+ def find_term_candidates(self, text: str) -> List[Tuple[str, str, float]]:
81
+ """
82
+ Metindeki olası tıbbi terim adaylarını bulur
83
+
84
+ Returns:
85
+ [(bulunan_terim, doğru_terim, benzerlik_skoru)]
86
+ """
87
+ candidates = []
88
+
89
+ # 1. Regex ile kesin eşleşmeleri bul
90
+ for term, pattern in self.regex_patterns.items():
91
+ matches = pattern.finditer(text)
92
+ for match in matches:
93
+ correct_term = self.medical_terms[term]
94
+ candidates.append((match.group(), correct_term, 100))
95
+
96
+ # 2. NLP analizi ile tıbbi terimleri bul
97
+ doc = nlp(text)
98
+ for ent in doc.ents:
99
+ # Eğer varlık sağlık ile ilgiliyse veya sınıflandırılamadıysa
100
+ if ent.label_ in ["DISEASE", "BODY", "CHEMICAL", "MISC", ""]:
101
+ ent_text = ent.text.lower()
102
+ best_match = None
103
+ best_score = 0
104
+
105
+ # Sözlükteki terimlerle karşılaştır
106
+ for term, correct_term in self.medical_terms.items():
107
+ # Ana terim ve varyasyonlarla karşılaştır
108
+ for term_var in self.term_variations.get(term, [term]):
109
+ score = fuzz.ratio(ent_text, term_var.lower())
110
+ if score > best_score and score >= self.threshold:
111
+ best_score = score
112
+ best_match = correct_term
113
+
114
+ if best_match:
115
+ candidates.append((ent.text, best_match, best_score))
116
+
117
+ # Eğer SpaCy modeli basit ise farklı bir yol izleyelim
118
+ if isinstance(nlp, spacy.blank):
119
+ # Basit kelime tabanlı analiz yap
120
+ words = text.split()
121
+ for word in words:
122
+ # SpaCy'ye güvenmeden basit tıbbi terim kontrolü
123
+ for term, correct_term in self.medical_terms.items():
124
+ score = fuzz.ratio(word.lower(), term.lower())
125
+ if score >= self.threshold:
126
+ candidates.append((word, correct_term, score))
127
+
128
+ # Tekrarlananları kaldır, en yüksek skorları tut
129
+ unique_candidates = {}
130
+ for found, correct, score in candidates:
131
+ if found not in unique_candidates or score > unique_candidates[found][1]:
132
+ unique_candidates[found] = (correct, score)
133
+
134
+ return [(found, correct, score) for found, (correct, score) in unique_candidates.items()]
135
+
136
+ def correct_text(self, text: str) -> str:
137
+ """Metindeki tıbbi terimleri düzeltir"""
138
+ # Terim adaylarını bul
139
+ candidates = self.find_term_candidates(text)
140
+
141
+ # En uzun terimlerden başlayarak değiştir (kısa terimlerin parçası olan uzun terimleri önceliklendir)
142
+ candidates.sort(key=lambda x: len(x[0]), reverse=True)
143
+
144
+ corrected_text = text
145
+ for found, correct, score in candidates:
146
+ # Eşleşme %100 değilse, orijinal metinde tam olarak nerede olduğunu bul
147
+ if score < 100:
148
+ # Kelimenin sınırlarını koru
149
+ corrected_text = re.sub(r'\b' + re.escape(found) + r'\b', correct, corrected_text)
150
+ else:
151
+ # Tam eşleşme durumu
152
+ corrected_text = corrected_text.replace(found, correct)
153
+
154
+ return corrected_text