Gensim-vector-and-model
Gensim-ベクターとモデル
ここでは、ベクトルとモデルに主に焦点を当てて、Gensimのコアコンセプトについて学びます。
ベクターとは?
コーパスの潜在構造を推測したい場合はどうなりますか? そのためには、ドキュメントを数学的に操作できるように表現する必要があります。 一般的な表現の1つは、コーパスのすべてのドキュメントを特徴のベクトルとして表現することです。 そのため、ベクトルはドキュメントの数学的に便利な表現であると言えます。
例として、上記で使用したコーパスの単一の特徴をQ-Aペアとして表現しましょう-
*Q* - *_Hello_* という単語がドキュメントに何回出現しますか?
*A* -ゼロ(0)。
*Q* -ドキュメントには段落がいくつありますか?
*A* -2つ(2)
質問は一般に整数IDで表されるため、このドキュメントの表現は(1、0.0)、(2、2.0)のような一連のペアです。 このようなベクトル表現は dense ベクトルと呼ばれます。 なぜ dense なのか、なぜなら上に書かれたすべての質問に対する明確な答えからなるからです。
すべての質問を事前に知っている場合、表現は(0、2)のような単純なものになります。 そのような一連の回答(もちろん、質問が事前にわかっている場合)は、ドキュメントの*ベクトル*です。
もう1つの人気のある表現は、* bag-of-word(BoW)*モデルです。 このアプローチでは、各ドキュメントは基本的に、辞書内のすべての単語の頻度カウントを含むベクトルによって表されます。
例として、「[Hello]、「How」、「are」、「you」」という単語を含む辞書があるとします。 文字列「How are you how」で構成されるドキュメントは、ベクトル[0、2、1、1]で表されます。 ここでは、ベクターのエントリは、「Hello」、「How」、「are」、「you」の順に表示されます。
ベクトル対ドキュメント
上記のベクトルの説明から、ドキュメントとベクトルの違いはほぼ理解できます。 しかし、より明確にするために、 document はテキストであり、 vector はそのテキストの数学的に便利な表現です。 残念ながら、多くの人がこれらの用語を同じ意味で使用しています。
たとえば、任意のドキュメントAがあり、「ドキュメントAに対応するベクトル」ではなく、「ベクトルA」または「ドキュメントA」と言っていたとします。 これは大きなあいまいさをもたらします。 ここでもう1つ重要なことは、2つの異なるドキュメントが同じベクトル表現を持つ可能性があることです。
コーパスをベクトルのリストに変換する
コーパスをベクトルのリストに変換する実装例をとる前に、コーパスの各単語を一意の整数IDに関連付ける必要があります。 このため、上記の章で取り上げた例を拡張します。
例
from gensim import corpora
dictionary = corpora.Dictionary(processed_corpus)
print(dictionary)
出力
Dictionary(25 unique tokens: ['computer', 'opinion', 'response', 'survey', 'system']...)
コーパスでは、この gensim.corpora.Dictionary に25の異なるトークンがあることを示しています。
実装例
辞書を使用して、トークン化されたドキュメントを次のようにこれらの5次元ベクトルに変換できます-
pprint.pprint(dictionary.token2id)
出力
{
'binary': 11,
'computer': 0,
'error': 7,
'generation': 12,
'graph': 16,
'intersection': 17,
'iv': 19,
'measurement': 8,
'minors': 20,
'opinion': 1,
'ordering': 21,
'paths': 18,
'perceived': 9,
'quasi': 22,
'random': 13,
'relation': 10,
'response': 2,
'survey': 3,
'system': 4,
'time': 5,
'trees': 14,
'unordered': 15,
'user': 6,
'well': 23,
'widths': 24
}
そして、同様に、次のようにドキュメントのバッグオブワード表現を作成できます-
BoW_corpus = [dictionary.doc2bow(text) for text in processed_corpus]
pprint.pprint(BoW_corpus)
出力
[
[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1)],
[(2, 1), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1), (10, 1)],
[(11, 1), (12, 1), (13, 1), (14, 1), (15, 1)],
[(14, 1), (16, 1), (17, 1), (18, 1)],
[(14, 1), (16, 1), (19, 1), (20, 1), (21, 1), (22, 1), (23, 1), (24, 1)]
]
モデルとは
コーパスをベクトル化したら、次に何をしますか? これで、モデルを使用してそれを変換できます。 モデルは、1つのドキュメント表現を別のドキュメント表現に変換するために使用されるアルゴリズムと呼ばれる場合があります。
すでに説明したように、Gensimでは、ドキュメントはベクトルとして表されるため、2つのベクトル空間間の変換としてモデル化できます。 モデルがそのような変換の詳細を学習するトレーニングフェーズが常にあります。 モデルは、トレーニングフェーズ中にトレーニングコーパスを読み取ります。
モデルの初期化
*_tf-idf_* モデルを初期化しましょう。 このモデルは、BoW(Bag of Words)表現から別のベクトル空間にベクトルを変換し、コーパス内のすべての単語の相対的希少度に従って頻度カウントに重みが付けられます。
実装例
次の例では、 tf-idf モデルを初期化します。 コーパスでトレーニングしてから、文字列「ツリーグラフ」を変換します。
例
from gensim import models
tfidf = models.TfidfModel(BoW_corpus)
words = "trees graph".lower().split()
print(tfidf[dictionary.doc2bow(words)])
出力
[(3, 0.4869354917707381), (4, 0.8734379353188121)]
これで、モデルを作成したら、tfidfを介してコーパス全体を変換してインデックス付けし、コーパス内の各ドキュメントに対してクエリドキュメントの類似性をクエリできます(クエリドキュメントの「ツリーシステム」)-
例
from gensim import similarities
index = similarities.SparseMatrixSimilarity(tfidf[BoW_corpus],num_features=5)
query_document = 'trees system'.split()
query_bow = dictionary.doc2bow(query_document)
simils = index[tfidf[query_bow]]
print(list(enumerate(simils)))
出力
[(0, 0.0), (1, 0.0), (2, 1.0), (3, 0.4869355), (4, 0.4869355)]
上記の出力から、ドキュメント4とドキュメント5の類似度スコアは約49%です。
さらに、次のように読みやすくするためにこの出力をソートすることもできます-
例
for doc_number, score in sorted(enumerate(sims), key=lambda x: x[1], reverse=True):
print(doc_number, score)
出力
2 1.0
3 0.4869355
4 0.4869355
0 0.0
1 0.0