自分でカスタマイズしたMeCabの辞書を使ってWikipediaの記事を形態素解析しWord2Vecを作りたくなったので、やってみました。
本記事ではまず、Wikiextractorを使ってWikipediaの日本語記事から本文を抽出し、形態素解析したのちにGoogle Colaboratory上でWord2Vecを学習させます。
- 環境
- Wikipediaの全日本語記事の用意
- WikiExtractorで抽出からのBeautifulSoup、そして形態素解析へ
- Google Colaboratoryを使います。
- 学習したモデルを使ってみる。
- おわりに
- Q&A
環境
私はWindows 10で作業していますがLinuxでもMacでも同じようにできると思います。今回使うライブラリでインストールに手間取りそうなものはMeCabくらいですね。
ほかはpip install
で楽にインストールできると思います。
Wikipediaの全日本語記事の用意
こちらからjawiki-latest-pages-articles.xml.bz2
をダウンロードします。
ダウンロードには少々時間がかかります。
WikiExtractorで抽出からのBeautifulSoup、そして形態素解析へ
こちらからWikiExtractor.py
をjawiki-latest-pages-articles.xml.bz2
があるディレクトリにコピペし以下のコマンドを実行する。
python WikiExtractor.py jawiki-latest-pages-articles.xml.bz2 -b 10M -o articles
ここでやっていることは抽出した記事を1つのファイルに10Mに分けて出力。出力先にはarticles
というフォルダが作成される。さらにその中にはAA
, AB
, AC
というフォルダが作成され抽出された記事の中身がファイルに書き込まれています。
作業ディレクトリの中身
WikiExtractor.py
articles
AA
wiki_00 ~ wiki_99
AB
wiki_00 ~ wiki_99
AC
wiki_00 ~ wiki_71
私のPCの場合抽出作業には約2時間かかり生成されたファイルのサイズはおよそ2.6GBになりました。
抽出されたファイルは以下のようにdoc
要素の集まりになっています。
<doc id="0" url="https://ja.wikipedia.org/wiki?curid=0" title="社会">
タイトル
本文
</doc>
<doc id="1" url="https://ja.wikipedia.org/wiki?curid=1" title="生物学">
タイトル
本文
</doc>
ここで、不必要なdoc
タグとタイトルを取り除きます。
BeautifulSoupを使って抽出したdoc
要素から本文のみを取り出してから、形態素解析しファイルに書き込んでいきます。
コードにするとこんな感じ。
このコードでやっていることはこんな感じ。
- globを使って
articles
にある3つのフォルダのパスを取得。 - 3つのフォルダ
AA
,AB
,AC
のなかの全てのファイルのパスを取得。 - ファイルをひとつずつ処理していく。(本文を抽出ー>形態素解析ー>
contents
フォルダにファイルを保存。)
Google Colaboratoryを使います。
これからやろうとすることはGoogle Colaboratoryを使わなくてもできると思います。ですが、個人的な理由によりGoogle Colaboratoryを使って作業を進めていきます。
contents
フォルダに形態素解析済みのファイルを用意できたので、これからWord2Vecの学習を進めていきますが、ここで大きな問題があるのですがとりあえずこのまま進めます。(※今からやることはGoogle Colaboratoryで試してみてください。)
まずはGoogle Colaboratoryを開き、さきほど用意した形態素解析済みのファイルが入ったcontents
フォルダをGoogle Driveにアップロードします。
Google Driveにあるファイルを読み込むには以下のようにマウントする必要があります。セルを実行するには▷をクリックするか、shift-EnterでOkです。
作業ディレクトリに移動。cd drive/My \Drive/
ちなみに、私はGoogle Driveの一番上のマイドライブで作業をしています。
必要なライブラリのインポート。
それでは用意したファイルを使ってWord2Vecを学習させていきたいと思います。
gensimのWord2Vecには学習データを以下の形にして渡します。
[
['単語', '単語', '単語'],
['単語', '単語', '単語', '単語']
]
- 関連記事 - gensimのWord2Vecを使ってみる。
リストの中に単語が入ったリストの状態になっているので、コードにするとこんな感じになります。
このコードをセルにコピペして実行すると、ようやくWikipediaの記事をWord2Vecで学習することが、できません。
もう一度言いますが、できません。\(^o^)/
メモリ不足が原因でセッションがクラッシュしますよね?
そりゃメモリ不足にもなりますよね。下のような大量のテキストをリストにぶち込もうとしたら。
ということで、Wikipediaの全日本語記事からWord2Vecを作ることはできませんでした(^^
はい、冗談です。
じゃあ、どうすればメモリ不足という問題を解決できるのか?
自分が導き出した答えは単語辞書を作る、です。(※gensimのText8Corpus
やLineSentence
を使うとこんなことする必要がないみたいです、、)
Wikipedia全記事に出てくる全ての単語に固有のIDを割り当てます。
例えば、このような辞書があった場合、
{'織田信長': 1, 'は': 2, '尾張': 3, 'の': 4, '大名': 5}
下のリストは
['織田信長', 'は', '尾張', 'の', '大名']
このように単語辞書から単語をIDに変換できメモリ使用量を抑えることができます。
[1, 2, 3, 4, 5]
なので、まずは単語辞書を作ります。引き続きGoogle Colaboratoryを使って作業を進めていきます。
改めて必要なライブラリをインポート。word2sid
を単語辞書にする。
単語辞書の作成。
gensimのWord2Vecにはint
ではなくstr
を渡す必要があるので固有のIDをstr
に変換。
後で使えるようにpickleで辞書を保存。
Wikipediaの記事を単語辞書をもとに固有のIDに変換。
作業ディレクトリにmodel
フォルダを作ってから、パラメータの設定とモデルの保存先を決める。
学習の開始。(※学習にはめちゃくちゃ時間がかかります。)
iter
を1にすると1時間くらいで学習が完了するかも?
学習したモデルを使ってみる。
学習が完了したので試してみます。
このコードは単語辞書とWord2Vecのモデルを読み込んで与えられた単語のベクトルの中身を見たり、似ている単語を見ることができます。
以下のコードを実行すると与えた単語と似ている単語を見ることができます。
おわりに
ここまでWikipediaの全日本語記事からWord2Vecのモデルを作って試してみました。
今後このモデルを使ってテキスト分類や他のアプリケーションで使っていきたいと思います。
Q&A
pickleを読み込むには?
今回作った辞書を読み込むにはこうする。
word2vecを再学習するには?
再学習するには、
- モデルを読み込む。
train()
で学習。- モデルの保存。