我正在做一些网络抓取。我遇到的一个问题是,我正在抓的表格的列标题有时会在语言上有所不同,以至于我试图使用fuzzywuzzy来检查它们的“接近度”
我的程序以标签列表开头。这些标签是我从网上抓下的表格中的所有列标题。它还要求我将“标准化列标题”分配给至少一些 - 这些作为“学习”的基础
matched_labels_dict{label_1:value_1,label_2:value_2,label_3:value_1, . . .}
字典显示label_1和label_3是同义词,label_2不是那些的同义词,但可以是字典中某些其他标签的同义词
我还有一份un_matched_labels
列表un_matched_labels=[label_324,label_325,label_326, . . .]
数字后缀只是占位符
我有一个函数使用fuzzywuzzy生成一个分数,将un_matched_labels中的每个标签与matched_labels_dict中的标签进行比较。如果匹配的max_score大于某个预定级别(假设为90),则将测试的标签添加到matched_labels_dict并分配与其匹配的标签相同的值。所以假设我在un_matched_labels中测试label_424,并且当它与label_3进行比较时发生了最大匹配分数94,然后我更新了matched_labels_dict
matched_labels_dict{label_1:value_1,label_2:value_2,label_3:value_1, label_424:value_1. . .}
现在机器学习起作用了 假设label_324将具有匹配的分数,label_424为91
但它的所有其他标签的匹配分数为value_1,其值(label_1和label_3)低于我的截止值(在本例中为90)。
只有label_424在matched_labels_dict中,label_324才会匹配。
由于标签是按顺序测试的,因此未添加label_324,因为在测试时,label_424不在matched_labels_dict中(测试按顺序进行)。
为了处理我重新运行匹配函数(在下面的代码块中称为do_machine_learning)。
这是do_machine_learning函数all_labels是一个标签列表,matched_label_dict是已知标签值匹配的字典,并且在上面的表格中
def do_machine_learning(all_labels,matched_labels_dict):
for test_label in all_labels:
if test_label not in matched_labels_dict:
temp_fuzzy_dict={label : fuzz.token_sort_ratio(label.upper(),test_label.upper()) for label in matched_labels_dict.keys()}
fuzzy_dict={key : temp_fuzzy_dict[key] for key in temp_fuzzy_dict if temp_fuzzy_dict[key] > 91}
try:
max_value=max(fuzzy_dict.values())
for label in fuzzy_dict:
if fuzzy_dict[label]== max_value:
matched_labels_dict[test_label]=matched_labels_dict[label]
break
except ValueError:
pass
return matched_labels_dict
我想重新运行匹配函数(然后将label_324添加到字典中,因为它与label_424匹配得分),直到matched_labels_dictionary在两次迭代之间保持不变。它将保持不变,因为没有找到更多的匹配。
以下是我的做法,我任意将周期限制设置为100
for number in range(1,100):
print 'cycle', number, 'number_of_matches', len(matched_labels_dict)
x=do_machine_learning(all_labels,matched_labels_dict)
if len(x)==len_matched_labels:
break
else:
len_matched_labels=len(x)
do_machine_learning函数用于比较不匹配的标签,并根据匹配的标签进行评分。一旦unmatched_labels在第一次返回matches_labels_dict时运行,程序就会将匹配标签的数量与上一次迭代中匹配标签的数量进行比较。如果数字增加,则再次发回标签以查看是否可以进行新的匹配。如果它在没有进行新匹配的情况下完成运行,那么程序就会突破循环。我被要求提出我的do_machine_learning函数,但我认为这是无关紧要的,因为我的问题是如何更加热情地循环上面的循环
所以问题是我如何更干净地设置这个迭代过程?
那么问题已经关闭了,我真的不明白为什么,但我想我想出了一个更好,更清洁的方法来处理这个至少它对我有用我从内部调用函数直到它的大小保持不变
def do_machine_learning(all_labels,matched_labels_dict, min_score):
initial_size=len(matched_labels_dict) # added this assignment
for test_label in all_labels:
if test_label not in matched_labels_dict:
temp_fuzzy_dict={label : fuzz.token_sort_ratio(label.upper(),test_label.upper()) for label in matched_labels_dict.keys()}
fuzzy_dict={key : temp_fuzzy_dict[key] for key in temp_fuzzy_dict if temp_fuzzy_dict[key] > min_score}
try:
max_value=max(fuzzy_dict.values())
for label in fuzzy_dict:
if fuzzy_dict[label]== max_value:
matched_labels_dict[test_label]['NEW_LABEL'] = matched_labels_dict[label]['NEW_LABEL']
matched_labels_dict[test_label]['FUZZ_SCORE'] = max_value
matched_labels_dict[test_label]['BEST_MATCH'] = label
break
except ValueError:
pass
if len(matched_labels_dict)!=initial_size: # added this loop
do_machine_learning(all_labels,matched_labels_dict, min_score)
return matched_labels_dict
通过那些微小的改变我可以通过
调用该函数new_matched_labels=do_machine_learning(all_labels,matched_labels_dict)
这些更改完全消除了以
开头的循环的需要for number in range(1,100):