-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspellsuggest.py
157 lines (124 loc) · 5.58 KB
/
spellsuggest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# -*- coding: utf-8 -*-
import re
from collections import Counter
import numpy as np
import time
from trie import Trie
from test_tarea2 import dp_levenshtein_threshold
from test_tarea2 import dp_restricted_damerau_threshold
from test_tarea2 import dp_intermediate_damerau_threshold
class SpellSuggester:
"""
Clase que implementa el método suggest para la búsqueda de términos.
"""
def __init__(self, vocab_file_path):
"""Método constructor de la clase SpellSuggester
Construye una lista de términos únicos (vocabulario),
que además se utiliza para crear un trie.
Args:
vocab_file (str): ruta del fichero de texto para cargar el vocabulario.
"""
self.vocabulary = self.build_vocab(
vocab_file_path, tokenizer=re.compile("\W+"))
def build_vocab(self, vocab_file_path, tokenizer):
"""Método para crear el vocabulario.
Se tokeniza por palabras el fichero de texto,
se eliminan palabras duplicadas y se ordena
lexicográficamente.
Args:
vocab_file (str): ruta del fichero de texto para cargar el vocabulario.
tokenizer (re.Pattern): expresión regular para la tokenización.
"""
with open(vocab_file_path, "r", encoding='utf-8') as fr:
vocab = set(tokenizer.split(fr.read().lower()))
vocab.discard('') # por si acaso
return sorted(vocab)
def suggest(self, term, distance="levenshtein", threshold=2):
"""Método para sugerir palabras similares siguiendo la tarea 3.
A completar.
Args:
term (str): término de búsqueda.
distance (str): algoritmo de búsqueda a utilizar
{"levenshtein", "restricted", "intermediate"}.
threshold (int): threshold para limitar la búsqueda
puede utilizarse con los algoritmos de distancia mejorada de la tarea 2
o filtrando la salida de las distancias de la tarea 2
"""
assert distance in ["levenshtein", "restricted", "intermediate"]
results = {} # diccionario termino:distancia
function = {
"levenshtein": dp_levenshtein_threshold,
"restricted": dp_restricted_damerau_threshold,
"intermediate": dp_intermediate_damerau_threshold
}
for vocab_term in self.vocabulary:
if (abs(len(term) - len(vocab_term)) <= threshold):
dist = function[distance](term, vocab_term, threshold)
if dist <= threshold:
results[vocab_term] = dist
return results
def suggest_opt(self, term, distance="levenshtein", threshold=2):
"""Método para sugerir palabras similares siguiendo la tarea 3.
A completar.
Args:
term (str): término de búsqueda.
distance (str): algoritmo de búsqueda a utilizar
{"levenshtein", "restricted", "intermediate"}.
threshold (int): threshold para limitar la búsqueda
puede utilizarse con los algoritmos de distancia mejorada de la tarea 2
o filtrando la salida de las distancias de la tarea 2
"""
assert distance in ["levenshtein", "restricted", "intermediate"]
results = {} # diccionario termino:distancia
function = {
"levenshtein": dp_levenshtein_threshold,
"restricted": dp_restricted_damerau_threshold,
"intermediate": dp_intermediate_damerau_threshold
}
for vocab_term in self.vocabulary:
if (abs(len(term) - len(vocab_term)) <= threshold):
vocabulary = list(term+vocab_term)
vx = dict.fromkeys(vocabulary)
vy = dict.fromkeys(vocabulary)
for l in vx:
vx[l] = term.count(l)
vy[l] = vocab_term.count(l)
v = np.subtract(list(vx.values()), list(vy.values()))
dif = max(np.sum(v[v>0]), -np.sum(v[v<0]))
if dif <= threshold:
dist = function[distance](term, vocab_term, threshold)
if dist <= threshold:
results[vocab_term] = dist
return results
def test(self, spellsuggester, words, thresholds):
# bucle de palabras separadas por tabulación en filas
# casa 1 31
with open("resuls.txt", "w", encoding='utf-8') as text_file:
for word in words:
text_file.write(word + "\t" + threshold + "\t")
for threshold in thresholds:
results = spellsuggester.suggest(
word, "levenshtein", threshold)
for my_word in results:
return 0
class TrieSpellSuggester(SpellSuggester):
"""
Clase que implementa el método suggest para la búsqueda de términos y añade el trie
"""
def __init__(self, vocab_file_path):
super().__init__(vocab_file_path)
self.trie = Trie(self.vocabulary)
if __name__ == "__main__":
spellsuggester = TrieSpellSuggester("./corpora/quijote.txt")
start = time.time()
print("hello")
spellsuggester.suggest_opt("suggest")
end = time.time()
print(end - start)
start2 = time.time()
print("hello")
spellsuggester.suggest("suggest")
end2 = time.time()
print(end2 - start2)
# spellsuggester.test(spellsuggester, "hola",2)
# cuidado, la salida es enorme print(suggester.trie)