2

我正在做一些网络抓取。我遇到的一个问题是,我正在抓取的表格的列标题有时在它们的语言上有所不同,以至于我试图使用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),那么被测试的标签被添加到 match_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_324 直到 label_424 在matched_labels_dict 中才会被匹配。

由于标签是按顺序测试的,因此没有添加 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 第一次通过它,matched_labels_dict 被返回,程序将匹配标签的数量与前一次迭代中匹配的标签数量进行比较。如果数量增加,则再次将标签发回以查看是否可以进行新的匹配。如果它在没有进行新匹配的情况下完成运行,则程序会跳出循环。我被要求设置我的 do_machine_learning 函数,但我认为这无关紧要,因为我的问题是如何以更 Python 的方式循环遍历上面的循环

所以问题是我如何更干净地设置这个迭代过程?

好吧,这个问题已经结束了,我真的不明白为什么,但我想我找到了一种更好 - 更清洁的方法来处理这个问题,至少它对我有用,我从内部调用函数,直到它的大小保持不变

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):
4

0 回答 0