[〜#〜]背景[〜#〜]
いくつかのサンプルデータを持つベクターがあり、各ベクターにはカテゴリ名(場所、色、名前)があります。
['john','jay','dan','nathan','bob'] -> 'Names'
['yellow', 'red','green'] -> 'Colors'
['tokyo','bejing','washington','mumbai'] -> 'Places'
私の目的は、新しい入力文字列を取得し、それが属するカテゴリを予測するモデルをトレーニングすることです。たとえば、新しい入力が「紫」の場合、「色」を正しいカテゴリとして予測できるはずです。新しい入力が「カルガリー」の場合、「場所」が正しいカテゴリであると予測されます。
[〜#〜]アプローチ[〜#〜]
私はいくつかの調査をして、出会いました Word2vec 。このライブラリには、私が使用できる「類似性」と「最も類似性」の関数があります。したがって、私が考えた力ずくのアプローチは次のとおりです。
たとえば、入力「ピンク」の場合、ベクトル「名前」の単語との類似度を計算して平均を取ってから、他の2つのベクトルについても同様に計算できます。私に最高の類似性平均を与えるベクトルは、入力が属する正しいベクトルです。
[〜#〜]問題[〜#〜]
NLPと機械学習に関する私の限られた知識を考えると、それが最善のアプローチであるかどうかはわからないので、問題を解決するためのより良いアプローチに関するヘルプと提案を探しています。私はすべての提案を受け入れています。また、機械学習とNLPの世界に不慣れなため、間違いがある場合は指摘してください。
最も単純で最速のソリューションを探している場合は、事前トレーニング済みの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
の単語をフィルタリングできます。モデルのサイズは、データとクエリできる単語にのみ依存することに注意してください。
また、その価値は何ですか PyTorch は最近、Gloveの優れた高速な implementation を備えています。