「Gensimを使ったWord2Vecのステップバイステップガイド」
Guide to Word2Vec Using Gensim, Step-by-Step
はじめに
数か月前、Office Peopleで働き始めた当初、私は言語モデル、特にWord2Vecに興味を持ちました。ネイティブのPythonユーザーとして、私は自然にGensimのWord2Vecの実装に集中し、論文やオンラインのチュートリアルを探しました。私は複数の情報源から直接コードの断片を適用し、複製しました。私はさらに深く探求し、自分の方法がどこで間違っているのかを理解しようとしました。Stackoverflowの会話、GensimのGoogleグループ、およびライブラリのドキュメントを読みました。
しかし、私は常にWord2Vecモデルを作成する上で最も重要な要素の一つが欠けていると考えていました。私の実験の中で、文をレンマ化することやフレーズ/バイグラムを探すことが結果とモデルのパフォーマンスに重要な影響を与えることを発見しました。前処理の影響はデータセットやアプリケーションによって異なりますが、この記事ではデータの準備手順を含め、素晴らしいspaCyライブラリを使って処理することにしました。
これらの問題のいくつかは私をイライラさせるので、自分自身の記事を書くことにしました。完璧だったり、Word2Vecを実装する最良の方法だったりすることは約束しませんが、他の多くの情報源よりも良いと思います。
学習目標
- 単語の埋め込みと意味的な関係の捉え方を理解する。
- GensimやTensorFlowなどの人気のあるライブラリを使用してWord2Vecモデルを実装する。
- Word2Vecの埋め込みを使用して単語の類似度を計測し、距離を算出する。
- Word2Vecによって捉えられる単語の類推や意味的関係を探索する。
- Word2Vecを感情分析や機械翻訳などのさまざまな自然言語処理のタスクに適用する。
- 特定のタスクやドメインに対してWord2Vecモデルを微調整するための技術を学ぶ。
- サブワード情報や事前学習された埋め込みを使用して未知語を処理する。
- Word2Vecの制約やトレードオフ、単語の意味の曖昧さや文レベルの意味について理解する。
- サブワード埋め込みやWord2Vecのモデル最適化など、高度なトピックについて掘り下げる。
この記事はData Science Blogathonの一部として公開されました。
Word2Vecについての概要
Googleの研究チームは2013年9月から10月にかけて2つの論文でWord2Vecを紹介しました。研究者たちは論文とともにCの実装も公開しました。Gensimは最初の論文の後すぐにPythonの実装を完了しました。
Word2Vecの基本的な仮定は、文脈が似ている2つの単語は似た意味を持ち、モデルからは似たベクトル表現が得られるというものです。例えば、「犬」、「子犬」、「子犬」は似た文脈で頻繁に使用され、同様の周囲の単語(「良い」、「ふわふわ」、「かわいい」など)と共に使用されるため、Word2Vecによると似たベクトル表現を持ちます。
この仮定に基づいて、Word2Vecはデータセット内の単語間の関係を発見し、類似度を計算したり、それらの単語のベクトル表現をテキスト分類やクラスタリングなどの他のアプリケーションの入力として使用することができます。
Word2vecの実装
Word2Vecのアイデアは非常にシンプルです。単語の意味は、それが関連する単語と共に存在することによって推測できるという仮定をしています。これは「友だちを見せて、君が誰かを教えてあげよう」という言葉に似ています。以下はword2vecの実装例です。
環境の設定
python==3.6.3
使用されるライブラリ:
- xlrd==1.1.0:
- spaCy==2.0.12:
- gensim==3.4.0:
- scikit-learn==0.19.1:
- seaborn==0.8:
import re # 前処理のため
import pandas as pd # データ処理のため
from time import time # 操作のタイミングを計測するため
from collections import defaultdict # 単語の頻度のため
import spacy # 前処理のため
import logging # gensimの監視のためのログの設定
logging.basicConfig(format="%(levelname)s - %(asctime)s: %(message)s",
datefmt= '%H:%M:%S', level=logging.INFO)
データセット
このデータセットには、1989年以降の600以上のシンプソンズのエピソードに関するキャラクター、場所、エピソードの詳細、およびスクリプトの行に関する情報が含まれています。Kaggleで利用できます。(約25MB)
前処理
前処理では、データセットからraw_character_textとspoken_wordsの2つの列のみを保持します。
- raw_character_text:発言するキャラクター(前処理のステップを追跡するのに便利)
- spoken_words:ダイアログ行からの生のテキスト
独自の前処理を行いたいため、normalized_textは保持しません。
df = pd.read_csv('../input/simpsons_dataset.csv')
df.shape
df.head()
欠損値は、何かが起こるが対話がないスクリプトのセクションから来ています。例として、「(スプリングフィールド小学校:EXT. 小学校の遊び場 – 午後)」があります。
df.isnull().sum()
クリーニング
各対話行ごとに、レンマ化し、ストップワードと非アルファベット文字を削除しています。
nlp = spacy.load('en', disable=['ner', 'parser'])
def cleaning(doc):
# レンマ化してストップワードを削除します
# docはspacyのDocオブジェクトである必要があります
txt = [token.lemma_ for token in doc if not token.is_stop]
if len(txt) > 2:
return ' '.join(txt)
非アルファベット文字を削除します:
brief_cleaning = (re.sub("[^A-Za-z']+", ' ', str(row)).lower() for row in df['spoken_words'])
spaCyのpipe()属性を使用してクリーニングプロセスを加速します:
t = time()
txt = [cleaning(doc) for doc in nlp.pipe(brief_cleaning, batch_size=5000,
n_threads=-1)]
print('全体のクリーニングにかかった時間:{}分'.format(round((time() - t) / 60, 2)))
欠損値と重複を削除し、結果をDataFrameに格納します:
df_clean = pd.DataFrame({'clean': txt})
df_clean = df_clean.dropna().drop_duplicates()
df_clean.shape
バイグラム
バイグラムは、自然言語処理とテキスト分析で使用される概念です。これは、テキストのシーケンスに現れる単語または文字の連続ペアを指します。バイグラムを分析することで、与えられたテキスト内の単語または文字の関係についての洞察を得ることができます。
例として、「I love ice cream」という文を考えましょう。この文のバイグラムを特定するために、連続する単語のペアを見ます:
「I love」
「love ice」
「ice cream」
これらのペアはそれぞれバイグラムを表しています。バイグラムはさまざまな言語処理のタスクで役立ちます。例えば、言語モデリングでは、前の単語に基づいて文の次の単語を予測するためにバイグラムを使用することができます。
バイグラムは、トリグラム(連続した3つ組)やn-gram(n個の単語または文字の連続シーケンス)に拡張することもできます。nの選択は、特定の分析やタスクによって異なります。
GensimのPhrasesパッケージは、文のリストから共通のフレーズ(バイグラム)を自動的に検出するために使用されています。 https://radimrehurek.com/gensim/models/phrases.html
これを主に行うのは、「mr_burns」や「bart_simpson」のような単語を捉えるためです!
from gensim.models.phrases import Phrases, Phraser
sent = [row.split() for row in df_clean['clean']]
以下のフレーズは、文のリストから生成されます:
phrases = Phrases(sent, min_count=30, progress_per=10000)
Phraser()の目的は、バイグラムの検出タスクに厳密に必要でないモデルの状態を破棄することで、Phrases()のメモリ消費を削減することです:
bigram = Phraser(phrases)
検出されたバイグラムに基づいてコーパスを変換します:
sentences = bigram[sent]
最も頻度の高い単語
主に、レンマ化、ストップワードの削除、およびバイグラムの追加の効果の確認のために行われます。
word_freq = defaultdict(int)
for sent in sentences:
for i in sent:
word_freq[i] += 1
len(word_freq)
sorted(word_freq, key=word_freq.get, reverse=True)[:10]
モデルのトレーニングを3つのステップに分ける
明瞭さとモニタリングのために、トレーニングを3つの異なるステップに分けることを好みます。
- Word2Vec():
- この最初のステップでは、モデルのパラメータを1つずつ設定します。
- パラメータのsentencesを提供しないことで、モデルを初期化していないことを意図的に残します。
- build_vocab():
- 文のシーケンスから語彙を構築することで、モデルを初期化します。
- 進行状況や、特にmin_countやsampleが単語コーパスに与える影響をログで追跡できます。これら2つのパラメータ、特にsampleは、モデルのパフォーマンスに大きな影響を与えることがわかりました。両方を表示することで、それらの影響をより正確かつ簡単に管理できます。
- .train():
- 最後に、モデルがトレーニングされます。
- このページのログは主に役立ちます。
import multiprocessing
from gensim.models import Word2Vec
cores = multiprocessing.cpu_count() # コンピュータのコア数をカウント
w2v_model = Word2Vec(min_count=20,
window=2,
size=300,
sample=6e-5,
alpha=0.03,
min_alpha=0.0007,
negative=20,
workers=cores-1)
word2vecのGensim実装:https://radimrehurek.com/gensim/models/word2vec.html
語彙テーブルの構築
Word2Vecは、語彙テーブルを作成する必要があります(すべての単語を消化し、ユニークな単語をフィルタリングし、基本的なカウントを行います):
t = time()
w2v_model.build_vocab(sentences, progress_per=10000)
print('語彙の構築にかかる時間:{}分'.format(round((time() - t) / 60, 2)))
語彙テーブルは、トレーニングや推論中に単語をインデックスとしてエンコードし、それらに対応する単語埋め込みを参照するために重要です。これはWord2Vecモデルのトレーニングの基礎を形成し、連続ベクトル空間で効率的な単語表現を可能にします。
モデルのトレーニング
Word2Vecモデルのトレーニングには、テキストデータのコーパスをアルゴリズムに入力し、モデルのパラメータを最適化して単語埋め込みを学習する必要があります。Word2Vecのトレーニングパラメータには、トレーニングプロセスと結果の単語埋め込みの品質に影響を与えるさまざまなハイパーパラメータと設定が含まれます。以下は、Word2Vecによく使用されるトレーニングパラメータのいくつかです:
- total_examples = int – 文の数;
- epochs = int – コーパスの反復回数(エポック) – [10, 20, 30]
t = time()
w2v_model.train(sentences, total_examples=w2v_model.corpus_count, epochs=30, report_delay=1)
print('モデルのトレーニングにかかった時間:{} 分'.format(round((time() - t) / 60, 2)))
モデルをさらにトレーニングするつもりはないので、init_sims() を呼び出してモデルをはるかにメモリ効率的にします:
w2v_model.init_sims(replace=True)
これらのパラメータは、コンテキストウィンドウのサイズ、頻出語とまれな語のトレードオフ、学習率、トレーニングアルゴリズム、ネガティブサンプルの数などの要素を制御します。これらのパラメータを調整することで、Word2Vecのトレーニングプロセスの品質、効率、メモリ要件に影響を与えることができます。
モデルの探索
Word2Vecモデルがトレーニングされたら、学習された単語埋め込みを探索して洞察を得たり、有用な情報を抽出したりすることができます。以下は、Word2Vecモデルを探索するためのいくつかの方法です:
最も類似した単語
Word2Vecでは、学習された単語埋め込みに基づいて、与えられた単語に最も類似した単語を見つけることができます。類似度は通常、コサイン類似度を使用して計算されます。以下は、Word2Vecを使用してターゲット単語に最も類似した単語を見つける例です:
番組の主要キャラクターについて見てみましょう:
similar_words = w2v_model.wv.most_similar(positive=["ホーマー"])
for word, similarity in similar_words:
print(f"{word}: {similarity}")
はっきりさせるために、「ホーマー」に最も類似した単語を見ると、必ずしも彼の家族のメンバーや個性的な特徴、さらには彼の最も記憶に残る名言が得られるわけではありません。
それに対して、bigram の「ホーマー_シンプソン」が返す結果を見てみましょう:
w2v_model.wv.most_similar(positive=["ホーマー_シンプソン"])
では、マージはどうでしょうか?
w2v_model.wv.most_similar(positive=["マージ"])
では、バートをチェックしてみましょう:
w2v_model.wv.most_similar(positive=["バート"])
意味が通じているようです!
類似点
Word2Vecを使用して2つの単語間のコサイン類似度を見つける例です:
例:2つの単語間のコサイン類似度を計算する。
w2v_model.wv.similarity("moe_'s", 'tavern')
Moe’s tavernを忘れることはできません。バーニーも忘れません。
w2v_model.wv.similarity('maggie', 'baby')
Maggieは間違いなくSimpsonsで最も有名な赤ちゃんです!
w2v_model.wv.similarity('bart', 'nelson')
バートとネルソンは友達ですが、それほど親しいわけではありません。理にかなっています!
異質なもの
ここでは、モデルにリスト内で異なる単語を教えてもらいます!
Jimbo、Milhouse、Kearneyの中で、いじめっ子ではないのは誰ですか?
w2v_model.wv.doesnt_match(['jimbo', 'milhouse', 'kearney'])
Nelson、Bart、Milhouseの友情を比較した場合はどうでしょう?
w2v_model.wv.doesnt_match(["nelson", "bart", "milhouse"])
ここではNelsonが異質な存在です!
最後に、ホーマーと彼の2人の義理の姉妹の関係はどうですか?
w2v_model.wv.doesnt_match(['homer', 'patty', 'selma'])
まったく、彼らは本当にあなたが嫌いなようです!
類推の違い
女性とホーマーの関係にある単語は何ですか?
w2v_model.wv.most_similar(positive=["woman", "homer"], negative=["marge"], topn=3)
「man」が最初の位置に来ているので、それは正しいようです!
女性とバートの関係にある単語は何ですか?
w2v_model.wv.most_similar(positive=["woman", "bart"], negative=["man"], topn=3)
Lisaはバートの姉妹で、彼の男性の対応です!
結論
Word2Vecは、自然言語処理(NLP)の分野で広く使用されているアルゴリズムであり、単語を連続したベクトル空間内の密なベクトルとして表現することで単語の埋め込みを学習します。これにより、テキストの大規模なコーパス内での共起パターンに基づいて単語間の意味的および構文的な関係を捉えることができます。
Word2Vecは、Continuous Bag-of-Words(CBOW)またはSkip-gramモデルのいずれかを利用して動作します。これらはニューラルネットワークアーキテクチャです。Word2Vecによって生成される単語の埋め込みは、意味論的および構文的情報をエンコードする単語の密なベクトル表現です。これにより、単語の類似性計算のような数学的な操作が可能になり、さまざまな自然言語処理(NLP)のタスクで特徴として使用することができます。
要点
- Word2Vecは、単語の密なベクトル表現である単語の埋め込みを学習します。
- 文脈コーパス内の共起パターンを分析して、意味的な関係を捉えます。
- CBOWまたはSkip-gramモデルを利用したニューラルネットワークを使用します。
- 単語の埋め込みは、単語の類似性の計算を可能にします。
- さまざまなNLPのタスクで特徴として使用することができます。
- 正確な埋め込みを学習するためには、大規模なトレーニングコーパスが必要です。
- Word2Vecは単語の意味の曖昧さを捉えることができません。
- Word2Vecでは単語の順序は考慮されません。
- 未知語は課題となる場合があります。
- 制約はありますが、Word2VecはNLPにおいて重要な応用があります。
Word2Vecは強力なアルゴリズムですが、いくつかの制約があります。正確な単語の埋め込みを学習するには、大量のトレーニングデータが必要です。それぞれの単語を原子的な要素として扱い、単語の意味の曖昧さを捉えることができません。未知語は事前に埋め込みが存在しないため、課題となる場合があります。
Word2Vecは、情報検索、感情分析、機械翻訳などのタスクにおいて、NLPの進歩に大きく貢献しており、貴重なツールの一つとなっています。
よくある質問と回答
この記事に掲載されているメディアはAnalytics Vidhyaの所有物ではなく、著者の裁量で使用されています。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles