Seicas commited on
Commit
4d6e765
·
verified ·
1 Parent(s): e4a7287

Update advanced_term_correction.py

Browse files
Files changed (1) hide show
  1. advanced_term_correction.py +75 -154
advanced_term_correction.py CHANGED
@@ -1,154 +1,75 @@
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
 
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]):
24
+ """
25
+ Tıbbi terim düzeltme sınıfı
26
+
27
+ Args:
28
+ medical_terms: Tıbbi terim sözlüğü (İngilizce -> Türkçe)
29
+ """
30
+ self.medical_terms = medical_terms
31
+ self.term_patterns = self._create_term_patterns()
32
+
33
+ def _create_term_patterns(self) -> List[Tuple[str, str]]:
34
+ """Terim eşleştirme desenlerini oluşturur"""
35
+ patterns = []
36
+ for eng_term, tr_term in self.medical_terms.items():
37
+ # Tam eşleşme için
38
+ patterns.append((rf'\b{re.escape(eng_term)}\b', tr_term))
39
+ # Kısmi eşleşme için (kelime sınırları olmadan)
40
+ patterns.append((eng_term, tr_term))
41
+ return patterns
42
+
43
+ def correct_text(self, text: str) -> str:
44
+ """
45
+ Metindeki tıbbi terimleri düzeltir
46
+
47
+ Args:
48
+ text: Düzeltilecek metin
49
+
50
+ Returns:
51
+ Düzeltilmiş metin
52
+ """
53
+ corrected_text = text
54
+
55
+ # Önce tam eşleşmeleri düzelt
56
+ for pattern, replacement in self.term_patterns:
57
+ corrected_text = re.sub(pattern, replacement, corrected_text, flags=re.IGNORECASE)
58
+
59
+ # Sonra bulanık eşleşmeleri kontrol et
60
+ words = corrected_text.split()
61
+ for i, word in enumerate(words):
62
+ # En iyi eşleşmeyi bul
63
+ best_match = None
64
+ best_score = 0
65
+
66
+ for eng_term, tr_term in self.medical_terms.items():
67
+ score = fuzz.ratio(word.lower(), eng_term.lower())
68
+ if score > best_score and score > 80: # 80% eşleşme eşiği
69
+ best_score = score
70
+ best_match = tr_term
71
+
72
+ if best_match:
73
+ words[i] = best_match
74
+
75
+ return ' '.join(words)