私はいくつかのWebスクレイピングを行っています。私が遭遇した問題の 1 つは、スクレイピングしているテーブルの列見出しの言語が異なる場合があり、fuzzywuzzy を使用して「近さ」を確認しようとしているということです。
私のプログラムは、ラベルのリストから始まります。これらのラベルはすべて、私が Web からかき集めた表の列見出しです。また、少なくとも一部に「正規化された列見出し」を割り当てる必要があります。これらは「学習」の基礎として機能します。
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 と一致するスコアを持つと仮定すると、機械学習が機能します。
しかし、カットオフ値 (この場合は 90) よりも低い値 (label_1 と label_3) として value_1 を持つ他のすべてのラベルの一致スコアがあります。
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
Matched_labels_dictionary のサイズが 2 回の反復間で一定になるまで、マッチング関数を再実行します (これにより、label_424 との一致スコアであるため、label_324 が辞書に追加されます)。それ以上の一致が見つからないため、サイズは一定のままです。
これが私がこれを行う方法です。サイクルの制限を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):