単語をベクトルとして数値化する手法は幾つかあるようです。今回は「Word2vec」というpythonのライブラリを利用したWebsiteがありましたので、そのプログラムを使用して実行してみました。詳細はこちらのWebsiteをご覧ください。 → https://qiita.com/makaishi2/items/63b7986f6da93dc55edd
このWebsiteの説明だけですとわかり難いところもあるので、資料にまとめてみました。 こちら → Word2vec0
p.1 ①青空文庫にアクセスして、夏目漱石の「三四郎」をご自身のパソコンのpythronが入っているフォルダ内にテキスト形式で保存してください。②コマンドプロンプトあるいはWindows PowerShellで「pip install janome」「pip install gensim」のコマンドを入力して、ダウンロードしてください。
p.2 右側にpythonのプログラムを載せてあります。三四郎のテキストファイルを読み込むます。 このテキストファイルの前後のヘッダー、フッターを削除して文章だけにします。 上手くできたかどうかを確認するため、文章の最初と最後の百文字をプリントしたものが左中央の青字の部分です。
p.3 janomeの中のTokenizerを用いて、名詞、動詞などに分ける関数を定義します。「三四郎は京都でちょっと用があって降りたついでに。」という文章を試しに、単語リストに変換してみます。実行結果が左の縦長のリストになります。
p.4、5 テキストファイルの一部はこのように文章になっています。
p.6 word2vecというライブラリを用いて、単語リストより単語ベクトルを算出します。 この際に、パラメータを設定します。 「size」はベクトルの次元、「min_cout」は頻度が少ない単語はカットします。その頻度を設定します。「window」は注目している単語の前後の幅です。 「世間」という単語ベクトルをプリントした後、「世間」に近い単語ベクトルをリストアップさせます。 実行すると、30分間以上何も出力されないので、不安になりますが、青字の実行結果が現れます。 「世間」の単語ベクトルは次元を100にしたので、ベクトル成分が100もあります。 「世間」に近い単語ベクトル順にプリントアウトされます。 単語の右にある数値が大きいほど「世間」に近い単語ベクトルになります。 世間に全然関係ないような気もしますが。
今日はここまで。本日使用した、プログラムは以下のとおりです。#以降の文章は説明なので、消しても問題ありません。
「プログラム」
import codecs
# ファイル読込み、内部表現化
f = codecs.open('sanshiro.txt', "r", "sjis")
text = f.read()
f.close()
# ファイル整形
import re
# ヘッダ部分の除去
text = re.split('\-{5,}',text)[2]
# フッタ部分の除去
text = re.split('底本:',text)[0]
# | の除去
text = text.replace('|', '')
# ルビの削除
text = re.sub('《.+?》', '', text)
# 入力注の削除
text = re.sub('[#.+?]', '',text)
# 空行の削除
text = re.sub('\\n\\n', '\\n', text)
text = re.sub('\\r', '', text)
# 整形結果確認
# 頭の100文字の表示
print(text[:100])
# 見やすくするため、空行
print()
print()
# 後ろの100文字の表示
print(text[-100:])
## Step2 Janomeを使い三四郎テキストから単語リストを生成
# Janomeのインストール
#!pip install janome
# Janomeのロード
from janome.tokenizer import Tokenizer
# Tokenneizerインスタンスの生成
t = Tokenizer()
# テキストを引数として、形態素解析の結果、名詞・動詞原型のみを配列で抽出する関数を定義
def extract_words(text):
tokens = t.tokenize(text)
return [token.base_form for token in tokens
if token.part_of_speech.split(',')[0] in['名詞', '動詞']]
# 関数テスト
ret = extract_words('三四郎は京都でちょっと用があって降りたついでに。')
for word in ret:
print(word)
# 全体のテキストを句点('。')で区切った配列にする。
sentences = text.split('。')
# それぞれの文章を単語リストに変換(処理に数分かかります)
word_list = [extract_words(sentence) for sentence in sentences]
# 結果の一部を確認
for word in word_list[0]:
print(word)
## Step 3 準備したデータを用いてWord2Vecのモデル作成、学習実施
# Word2Vecライブラリの導入
#!pip install gensim
# Word2Vecライブラリのロード
from gensim.models import word2vec
# size: 圧縮次元数
# min_count: 出現頻度の低いものをカットする
# window: 前後の単語を拾う際の窓の広さを決める
# iter: 機械学習の繰り返し回数(デフォルト:5)十分学習できていないときにこの値を調整する
# model.wv.most_similarの結果が1に近いものばかりで、model.dict['wv']のベクトル値が小さい値ばかりの
# ときは、学習回数が少ないと考えられます。
# その場合、iterの値を大きくして、再度学習を行います。
# 事前準備したword_listを使ってWord2Vecの学習実施
model = word2vec.Word2Vec(word_list, size=100,min_count=5,window=5,iter=100)
# 結果の確認1
# 一つ一つの単語は100次元のベクトルになっています。
# 「世間」のベクトル値を確認します。
print(model.__dict__['wv']['世間'])
# 結果の確認2
# 関数most_similarを使って「世間」の類似単語を調べます
ret = model.wv.most_similar(positive=['世間'])
for item in ret:
print(item[0], item[1])