分布セマンティクスのパイ

数か月間、 分散セマンティクスを不思議に探していました-私は理論に精通し、 word2vecについて学び 、Python(gensim)の適切なライブラリを見つけ、ロシア語の国語コーパスに従って形成された語彙ベクトルのモデルさえも見つけました。 しかし、素材に創造的に没頭するには、十分な魂を吸収するデータがありませんでした。これは、分布セマンティクスをひねり出すのに興味深いでしょう。 同時に、彼は熱心に詩とパイ (生意気な教訓と思慮深いホクの一種)を熱心に読みました-彼の何人かは彼の知人を暗記し、時には扱いました。 そして最後に、熱意と好奇心が出会い、連想的な深層意識にインスピレーションを与えました。ビジネスと喜びを組み合わせて、手元のツールから「詩的」な検索エンジンを集めないでください。

誤った結論から

私たちは真実を加えることができます

掛け方について

2つの負の数


トークンの意味的類似性の程度を最も実数で示す分布ベクトルの生来の能力により、検索の「詩」を実現することになっていた(単語ベクトル間の角度が小さいほど、これらの単語は意味が近い可能性が高い- コサイン尺度 、ジャンルの古典、一般的に) たとえば、「王女」と「羊飼い」は「羊飼い」と「羊」よりはるかに近く、0.139対0.603です。これはおそらく論理的です-国軍団のベクトルは、G.Khの素晴らしい世界ではなく、厳しい現実を反映すべきです。 アンデルセン。 リクエストとパイの相関の深さ(拡散)を計算する方法は、リストXの各単語とリストYの各単語の類似性の正規化された合計としてほぼ単独で(安価で怒って)表示されました(ストップワードは破棄され、残りはすべて通常の形式に戻されましたが、それ以上後で)。



セマンティック拡散計算コード
def semantic_similarity(bag1, bag2: list, w2v_model, unknown_coef=0.0) -> float: sim_sum = 0.0 for i in range(len(bag1)): for j in range(len(bag2)): try: sim_sum += w2v_model.similarity(bag1[i], bag2[j]) except Exception: sim_sum += unknown_coef return sim_sum / (len(bag1) * len(bag2))
      
      







詩的な検索の結果は喜ばれ、面白くなりました。 たとえば、クエリ「music」に対して次の詩リストが発行されました。



 [('  ' '   ' '    ' '   ', 0.25434666007036322), ('   ' '    ' '    ' '   ', 0.19876923472322899), ('    ' '    ' '    ' '   ', 0.19102709737990775), ('   ' '  ' '     ' '    ', 0.15292901301609391), ('   ' '   ' '   ' '', 0.14688091047781876)]
      
      





データベースにリストされているペストリーのいずれにも「音楽」という言葉が含まれていないことは注目に値します。 ただし、すべてのパティの関連付けは非常に音楽的であり、リクエストとの意味の拡散の度合いは非常に高いです。



さて、完了した作業について順番に(GitHubのソース )。



ライブラリとリソース





データモデルの形成



テキストとして表示されるオレグ

オクサナが言うことすべて

章と段落に分かれています

そして一言


まず、韻パイ(約800 )を含むテキストファイル( poems.txt )から、実際にはこれらのパイを行の形で含むリストがカットされます。 次に、パイの各行から単語の袋が絞り出され、各単語が通常の文法形式になり、そこからノイズワードが排出されます。 その後、各バッグに対して、パイのセマンティック「密度」(内部拡散)が計算され、特定の連想リストが形成されます(分布ベクトルモデルの観点からどのセマンティックレイヤが優先されるかを理解するのに役立ちます)。 この喜びはすべて、適切なキーの下の辞書に収まり、json形式でファイルに書き込まれます。



コードを絞った言葉の袋
 def canonize_words(words: list) -> list: stop_words = ('', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '') grammars = {'NOUN': '_S', 'VERB': '_V', 'INFN': '_V', 'GRND': '_V', 'PRTF': '_V', 'PRTS': '_V', 'ADJF': '_A', 'ADJS': '_A', 'ADVB': '_ADV', 'PRED': '_PRAEDIC'} morph = pymorphy2.MorphAnalyzer() normalized = [] for i in words: forms = morph.parse(i) try: form = max(forms, key=lambda x: (x.score, x.methods_stack[0][2])) except Exception: form = forms[0] print(form) if not (form.tag.POS in ['PREP', 'CONJ', 'PRCL', 'NPRO', 'NUMR'] or 'Name' in form.tag or 'UNKN' in form.tag or form.normal_form in stop_words): # 'ADJF' normalized.append(form.normal_form + grammars.get(form.tag.POS, '')) return normalized
      
      







データモデル形成コード
 def make_data_model(file_name: str) -> dict: poems = read_poems(file_name) bags, voc = make_bags(poems) w2v_model = sem.load_w2v_model(sem.WORD2VEC_MODEL_FILE) sd = [sem.semantic_density(bag, w2v_model, unknown_coef=-0.001) for bag in bags] sa = [sem.semantic_association(bag, w2v_model) for bag in bags] rates = [0.0 for _ in range(len(poems))] return {'poems' : poems, 'bags' : bags, 'vocabulary' : voc, 'density' : sd, 'associations': sa, 'rates' : rates}
      
      







モデルの一般的な分析



最も難しいパイ:

怒りと欲望を殺す

誇りとvy望

しかし、あなたに残っているもの

容赦ない


密度、スクイーズ、連想リスト
  0.16305980883482543 ['_V', '_S', '_S', '_S', '_S', '_S', '_S', '_V', '_S', '_V'] ['_S', '_S', '_S', '_S', '_S', '_S', '_S', '_S', '_S', '_S']
      
      







パイは「しっかりした」トップになり、同義語と反意語(およびファジー)の両方の意味に近い多くの単語があり、簡単に特定のカテゴリ(この場合は感情)に一般化されます。



最も柔らかいパイ:

この船で救われる

先祖にならないでください

船をばかにしないでください

病気の


密度、スクイーズ、連想リスト
  -0.023802562235525036 ['_S', '_V', '_S', '_V', '_V', '_A'] ['_S', '_V', '_S', '_S', '_V', '_S', '_S', '_S', '_S', '_S']
      
      







ここで、負の密度は、主に「船」という言葉の病院の意味が連想リストに載っていなかったという事実によると思われます。 これは一般に、分布セマンティックモデルの弱点の1つです。原則として、語彙素の1つの意味は、人気のある他のすべてを抑制します。



モデルによる検索クエリ



実際、検索がどのように機能するかの上に書かれています-パイは、クエリ単語との拡散のレベル(一般化された意味的類似性)によってシームレスにソートされます。



コード
 def similar_poems_idx(poem: str, poem_model, w2v_model, topn=5) -> list: poem_bag = dm.canonize_words(poem.split()) similars = [(i, sem.semantic_similarity(poem_bag, bag, w2v_model)) for i, bag in enumerate(poem_model['bags'])] similars.sort(key=lambda x: x[1], reverse=True) return similars[:topn]
      
      







いくつかの例:



意識
 >> pprint(similar_poems("", pm, w2v, topn=5)) [('   ' '    ' '   ' ' ', 0.13678271365987432), ('  ' '   ' '   ' '   ', 0.1337333519127788), ('    ' '    ' '    ' '     ', 0.12728715072640368), ('   ' '     ' '    ' '   ', 0.12420312280907075), ('   ' '   ' '  ' '    ', 0.11909834879893783)]
      
      







自由意志
 >> pprint(similar_poems(" ", pm, w2v, topn=5)) [('   ' '    ' '   ' '  ', 0.12186796715891397), ('    ' '   ' '     ' '  ', 0.10667187095852899), ('   ' '      ' '   ' '    ', 0.10161426827828646), ('    ' '      ' '   ' '', 0.10136245188273822), ('     ' '    ' '      ' '     ', 0.098855948557813059)]
      
      







 >> pprint(similar_poems("", pm, w2v, topn=5)) [('  ' '    ' '    ' '  ', 0.1875936291758869), ('  ' '      ' '      ' '    ', 0.18548772093805863), ('   ' '   ' '   ' '   ', 0.16475609244668787), ('  ' '  ' '    ' '    ', 0.14671085483137575), ('      ' '    ' '   ' '', 0.13253569027346904)]
      
      







明らかに、他の分布セマンティックモデル(さまざまな軍団、学習アルゴリズム、ベクトル次元)のプリズムを検索すると、他の結果が得られます。 一般に、この技術は機能し、非常に満足のいく機能を発揮します。 ファジーセマンティック検索は、(少なくとも比較的少量のデータに対して)簡単かつ気楽に実装されます。 将来、彼らが手を伸ばし、そして最も重要なことに頭に追いつくなら、トレーニングサンプルに基づいてパイの格付けの評価を実施するつもりです。 まず、単純な加重和によって(意味的な拡散が加重係数の役割を果たします)。 それから多分機械学習から何かが便利になります。



All Articles