PythonでGensimライブラリを使ってWord2Vecを実装する

はじめに

人間には、他の人が何を言っているか、それに対して何を言うかを理解する能力が自然に備わっています。 この能力は、長年にわたって他の人々や社会と一貫して交流することによって培われる。 人間がどのように交流するかは、言語が非常に重要な役割を果たします。 人間が相互作用のために使用する言語を自然言語と呼ぶ。

さまざまな自然言語のルールは異なっている。 しかし、自然言語には柔軟性と進化という共通点がある。

自然言語は非常に柔軟性が高い。 例えば、あなたが車を運転しているときに、友人が次の3つの発話のうち1つを言ったとしよう。 「車を止めろ」、「車を止めろ」、「止まれ」。 あなたはすぐに、彼があなたに車を止めるように頼んでいるのだと理解します。 これは、自然言語が非常に柔軟だからである。

自然言語のもう一つの重要な点は、一貫して進化しているということです。 たとえば、数年前には、Googleの検索エンジンで何かを検索することを指す「Google it」などという言葉はなかった。 自然言語は常に進化しているのです。

それに対して、コンピュータ言語は厳密な構文に従っています。 コンピュータに何かを画面に印刷するように指示したい場合、そのための特別なコマンドが存在する。 自然言語処理の課題は、コンピュータに人間の言葉を理解させ、人間と同じように生成させることです

これは大きな課題であり、多くのハードルがあります。 ミシガン大学のこのビデオ講義には、なぜ NLP が難しいのかについての非常に良い説明が含まれています。

この記事では、単語のベクトルを作成するために使用する Word2Vec の単語埋め込み技術を Python の Gensim ライブラリで実装します。

Word Embedding Approaches

自然言語処理が難しい問題である理由の1つは、人間と違ってコンピュータは数字しか理解できないことです。 コンピュータが理解できるような数値形式で言葉を表現しなければならないのです。

現在、いくつかのWord Embdingのアプローチが存在し、どれも長所と短所を持っています。 ここではそのうちの3つを取り上げる。

  1. Bag of Words
  2. TF-IDF Scheme
  3. Word2Vec

Bag of Words

単語の袋アプローチは最も簡単な単語埋め込みアプローチの1つである。 以下は、Bag of words approachを使った単語埋め込み生成の手順です。

例題を使って、Bag of words approachで生成した単語埋め込みを見ます。 例えば、3つの文からなるコーパスがあるとする。

  • S1 = I love rain
  • S2 = rain go away
  • S3 = I am away

上記の文章をbag of wordsアプローチで対応する単語埋め込み表現に変換するには、以下のステップを実行すれば良い。

S2について、辞書の「rain」の代わりに2を追加したことに注目してください。これは、S2には「rain」が2回含まれているからです。

Pros and Cons of Bag of Words

Bag of Wordsアプローチには、長所と短所がある。 Bag of Wordsアプローチの主な利点は、良い結果を得るために単語の非常に巨大なコーパスを必要としないことである。 3つの文を使って非常に基本的なBag of Wordモデルを構築しているのがわかると思います。 計算上、Bag of Word モデルはそれほど複雑ではありません。

単語の袋のアプローチの主な欠点は、メモリとスペースを消費する数(疎行列)を表すために、空のスペースで巨大なベクトルを作成する必要があるという事実です。 先ほどの例では、3つの文しかありませんでした。

何千もの記事を持つコーパスを想像してみてください。 そのような場合、辞書にあるユニークな単語の数は数千になることがあります。 もし、ある文書に10%の固有単語が含まれていたとしても、対応する埋め込みベクトルには90%のゼロが含まれることになる。

単語の袋のアプローチのもうひとつの大きな問題は、それがコンテキスト情報を保持していないという事実である。 これは、文中に現れる単語の順序を気にしない。 たとえば、”Bottle is in the car” と “Car is in the bottle” という文は同じように扱われますが、これはまったく異なる文です。

N-gram として知られる bag of words approach の一種は、単語間の関係を維持するのに役立つことがあります。 N-gramとは、連続したn個の単語の列のことである。 例えば、”You are not happy “という文の2-gramは、”You are”, “are not”, “not happy “である。 6121>

TF-IDF スキーム

TF-IDFスキームはバッグワードアプローチの一種で、埋め込みベクトルに0と1を加える代わりに、0と1に比べてより有用な情報を含む浮動小数点数を加えるものである。 TF-IDF スキームの背後にある考え方は、ある文書での出現頻度が高く、他のすべての文書での出現頻度が低い単語は、分類にとってより重要であるという事実である

TF-IDF は 2 つの値の積である。

用語頻度(TF)と逆文書頻度(IDF)。

Term frequence = (Number of Occurences of a word)/(Total words in the document)

例えば、前節の文S1、すなわち「私は雨が好きだ」を見ると、文のすべての単語は1回発生するので頻度は1である。 「

IDFとは、全文書数をその単語が存在する文書数で割った対数で、次のように計算されます。 一方、最初の文の単語 “love “を見ると、それは3つの文書のうちの1つに現れるため、そのIDF値はlog(3)で0.4771となる。

Pros and Cons of TF-IDF

TF-IDFは単純なbag of wordsアプローチより改善されて、共通のNLPタスクでより良い結果を生むが、全体の長所と短所は同じままである。 これは、単純な bag of words アプローチよりも多くの計算を必要とします。

Word2Vec

Tomas Mikolov が開発した <a target=”_blank rel=”nofollow”” href=”https://en.wikipedia.org/wiki/Word2vec”>Word2Vec 埋め込みアプローチは最先端のものとみなされています。 Word2Vec のアプローチは、ディープラーニングとニューラルネットワークベースの技術を使用して、意味的に類似したベクトルが N 次元空間で互いに近くなるように、単語を対応するベクトルに変換します(ここで N はベクトルの次元を指します)

Word2Vecはいくつかの驚くべき結果を返します。 Word2Vecの意味的な関係を維持する能力は、典型的な例として、”King “という単語のベクトルがあったとして、”King “から “Man “で表されるベクトルを取り除き、”Women “を加えた場合、”Queen “のベクトルに近いベクトルを得ることができることに反映されています。 この関係は一般に次のように表現される:

King - Man + Women = Queen

Word2Vec モデルには2つの味がある。 スキップグラムモデルと連続単語袋モデル(CBOW)である。

スキップグラムモデルでは、文脈の単語は基本単語を使用して予測される。 例えば、”I love to dance in the rain” という文が与えられると、スキップグラムモデルは、入力として “to” という単語が与えられると “love” と “dance” を予測する。

反対に、CBOWモデルは、文脈の単語 “love” と “dance” がモデルへの入力として与えられると “to” を予測する。

Pros and Cons of Word2Vec

Word2Vec は bag of words と IF-IDF スキームに対していくつかの利点を持っています。 Word2Vec は、ドキュメント内のさまざまな単語の意味的な意味を保持します。 文脈情報が失われることはない。 Word2Vecのもう一つの利点は、埋め込みベクトルが非常に小さいことである。 埋め込みベクトルの各次元は、単語の1つの側面に関する情報を含んでいます。 Bag of wordsやTF-IDFアプローチとは異なり、巨大なスパースベクトルは必要ありません。

注意: Word2Vecがどのように機能するかの数学的詳細は、ニューラルネットワークとソフトマックス確率の説明を含みますが、この記事の範囲を超えています。 Word2Vecの数学的根拠を理解したい方は、こちらの論文をお読みください。 https://arxiv.org/abs/1301.3781

Word2Vec in Python with Gensim Library

このセクションでは、PythonのGensimライブラリを使ってWord2Vecのモデルを実装していきます。 以下の手順に従ってください:

コーパスの作成

Word2Vecのモデルを作成するためには、コーパスが必要であることは先に述べました。 実際のアプリケーションでは、数十億の文書を使ってWord2Vecモデルが作成される。 例えばGoogleのWord2Vecモデルは300万の単語とフレーズを使って学習されます。 しかし、ここでは簡単のために、一つのWikipediaの記事からWord2Vecモデルを作成する。 我々のモデルはGoogleのモデルには及ばない。 しかし、Gensim ライブラリを使用して Word2Vec モデルを実装する方法を説明するには十分です。

Wikipedia の記事を要約する前に、それらを取得する必要があります。 そのために、いくつかのライブラリを使用します。 最初にダウンロードする必要があるライブラリは Beautiful Soup ライブラリで、これは Web スクレイピングのための非常に便利な Python ユーティリティです。 コマンド プロンプトで次のコマンドを実行して Beautiful Soup ユーティリティをダウンロードします。

$ pip install beautifulsoup4

また、XML と HTML をパースするために必要な重要なライブラリは lxml ライブラリです。 コマンド プロンプトで次のコマンドを実行して lxml をダウンロードします。

$ pip install lxml

これからスクレイピングする記事は、人工知能に関する Wikipedia の記事です。 Wikipediaから記事をスクレイピングするPythonスクリプトを書いてみましょう。

上記のスクリプトでは、まずurllibライブラリのrequestクラスのurlopenメソッドを使用してWikipediaの記事をダウンロードします。 その後、BeautifulSoupクラスのオブジェクトを使って記事の内容を読み、パースしている。 Wikipediaは記事のテキストをpタグの中に格納している。

最後に、すべての段落を結合し、後で使用するために article_text 変数にスクレイピングされた記事を保存します。

前処理

この時点で、記事をインポートしました。 次のステップは、Word2Vecモデル用にコンテンツを前処理することです。

上記のスクリプトでは、すべてのテキストを小文字に変換し、テキストからすべての数字、特殊文字、余分なスペースを削除しています。

Word2Vecモデルは、単語のコレクションで学習されます。 まず、記事を文に変換する必要があります。 記事を文に変換するために nltk.sent_tokenize ユーティリティを使用します。 文を単語に変換するには、nltk.word_tokenizeユーティリティを使用します。 最後の前処理として、テキストからすべてのストップワードを削除します。

スクリプトの実行が完了すると、all_words オブジェクトに記事内のすべての単語のリストが格納されます。

Word2Vecモデルの作成

Gensimでは、Word2Vecモデルを非常に簡単に作成することができます。 単語リストはgensim.modelsパッケージのWord2Vecクラスへ渡されます。 min_countパラメータに値を指定する必要があります。 min_countに2を指定すると、コーパスに2回以上出現する単語のみをWord2Vecモデルに含めることができる。

from gensim.models import Word2Vecword2vec = Word2Vec(all_words, min_count=2)

コーパス中に2回以上存在する固有単語の辞書を見るには、以下のスクリプトを実行します:

vocabulary = word2vec.wv.vocabprint(vocabulary)

上記のスクリプトを実行すると、2回以上出現する固有単語が一覧で表示されます。

単語のベクトルを見つける

我々は、Word2Vecモデルが単語をその対応するベクトルに変換することを知っています。

v1 = word2vec.wv

ベクトルv1は単語 “artificial “のベクトル表現を持っている。 Gensim Word2Vecでは、デフォルトで100次元のベクトルが作成されます。 これはbag of wordsで生成されたものと比べると、かなり小さいベクトルです。 仮にBag of wordsの手法で記事を埋め込むと、最小出現頻度2の単語が1206個あるので、それぞれのベクトルの長さは1206になります。最小出現頻度を1にすると、Bag of wordsのベクトルの大きさはさらに大きくなります。 一方、Word2Vecで生成されたベクトルは語彙の大きさに影響されない。

類似語の発見

先に、Word2Vecアプローチで単語の文脈情報が失われないと述べた。

次のスクリプトを見てください。

sim_words = word2vec.wv.most_similar('intelligence')

変数 sim_words をコンソールに出力すると、次のように “intelligence” に最も類似した単語が表示されます。 モデルによると、”ai “という単語が “intelligence “に最も似ている単語であり、これは実際に理にかなっている。 同様に、”intelligence “には “human “や “artificial “といった単語が混在していることが多いのです。 我々のモデルは、たった1つのWikipedia記事を使って、これらの関係をうまく捉えました。

結論

この記事では、PythonのGensim Libraryを使ってWord2Vec単語埋め込みモデルを実装してみました。 Wikipediaの記事をスクレイピングし、その記事をコーパスとしてWord2Vecのモデルを構築することで行いました。 また、Word2Vec との比較として、最も一般的に使用される単語埋め込みアプローチを、その長所と短所とともに簡単にレビューしました。

私は、任意のテキストコーパスの助けを借りて、あなた自身の Word2Vec モデルを作成し、単語のバッグアプローチと比較してより良い結果を得ることができるかどうかを見ることを提案したいと思います。

コメントを残す

メールアドレスが公開されることはありません。