web-dev-qa-db-ja.com

Word2vecを使用してカテゴリ内の単語を分類する

[〜#〜]背景[〜#〜]

いくつかのサンプルデータを持つベクターがあり、各ベクターにはカテゴリ名(場所、色、名前)があります。

['john','jay','dan','nathan','bob']  -> 'Names'
['yellow', 'red','green'] -> 'Colors'
['tokyo','bejing','washington','mumbai'] -> 'Places'

私の目的は、新しい入力文字列を取得し、それが属するカテゴリを予測するモデルをトレーニングすることです。たとえば、新しい入力が「紫」の場合、「色」を正しいカテゴリとして予測できるはずです。新しい入力が「カルガリー」の場合、「場所」が正しいカテゴリであると予測されます。

[〜#〜]アプローチ[〜#〜]

私はいくつかの調査をして、出会いました Word2vec 。このライブラリには、私が使用できる「類似性」と「最も類似性」の関数があります。したがって、私が考えた力ずくのアプローチは次のとおりです。

  1. 新しい入力を受け取ります。
  2. 各ベクトルの各単語との類似度を計算し、平均を取ります。

たとえば、入力「ピンク」の場合、ベクトル「名前」の単語との類似度を計算して平均を取ってから、他の2つのベクトルについても同様に計算できます。私に最高の類似性平均を与えるベクトルは、入力が属する正しいベクトルです。

[〜#〜]問題[〜#〜]

NLPと機械学習に関する私の限られた知識を考えると、それが最善のアプローチであるかどうかはわからないので、問題を解決するためのより良いアプローチに関するヘルプと提案を探しています。私はすべての提案を受け入れています。また、機械学習とNLPの世界に不慣れなため、間違いがある場合は指摘してください。

13
Dinero

最も単純で最速のソリューションを探している場合は、事前トレーニング済みのWord埋め込み(Word2VecまたはGloVe)を使用して、その上に単純なクエリシステムを構築することをお勧めします。ベクトルは巨大なコーパスでトレーニングされており、ドメインデータに対する十分な近似が含まれている可能性があります。

以下が私の解決策です:

import numpy as np

# Category -> words
data = {
  'Names': ['john','jay','dan','nathan','bob'],
  'Colors': ['yellow', 'red','green'],
  'Places': ['tokyo','bejing','washington','mumbai'],
}
# Words -> category
categories = {Word: key for key, words in data.items() for Word in words}

# Load the whole embedding matrix
embeddings_index = {}
with open('glove.6B.100d.txt') as f:
  for line in f:
    values = line.split()
    Word = values[0]
    embed = np.array(values[1:], dtype=np.float32)
    embeddings_index[Word] = embed
print('Loaded %s Word vectors.' % len(embeddings_index))
# Embeddings for available words
data_embeddings = {key: value for key, value in embeddings_index.items() if key in categories.keys()}

# Processing the query
def process(query):
  query_embed = embeddings_index[query]
  scores = {}
  for Word, embed in data_embeddings.items():
    category = categories[Word]
    dist = query_embed.dot(embed)
    dist /= len(data[category])
    scores[category] = scores.get(category, 0) + dist
  return scores

# Testing
print(process('pink'))
print(process('frank'))
print(process('moscow'))

実行するには、事前トレーニング済みのGloVeデータを here からダウンロードして解凍する必要があります(注意、800Mb!)。実行すると、次のようになります。

{'Colors': 24.655489603678387, 'Names': 5.058711671829224, 'Places': 0.90213905274868011}
{'Colors': 6.8597321510314941, 'Names': 15.570847320556641, 'Places': 3.5302454829216003}
{'Colors': 8.2919375101725254, 'Names': 4.58830726146698, 'Places': 14.7840416431427}

かなりリーズナブルに見えます...以上です!このような大きなモデルが必要ない場合は、_ tf-idf スコアに従ってgloveの単語をフィルタリングできます。モデルのサイズは、データとクエリできる単語にのみ依存することに注意してください。

20
Maxim

また、その価値は何ですか PyTorch は最近、Gloveの優れた高速な implementation を備えています。

0
mithunpaul