KATOエンジニヤリング開発日誌

「アウトプット無きエンジニアにインプットもチャンスも無い」の精神で書いています

WEB+DB PRESS Vol.100の人工知能の記事 - 機械学習 -

前回の続きです。

www.kato-eng.info

サポートベクタマシンによる教師あり学習

教師あり学習では、まず学習データを用意してそれをコンピュータが学習するという2つのフェーズに分けられる。

  • 学習フェーズ
    • 学習データを用いてコンピュータが学習を行う
  • 推定フェーズ
    • 新しいデータを与えられた時にコンピュータが推定を行う

Wikipediaデータの分類

サポートベクタマシンを利用するためにscikit-learnというライブラリをインストールする。scikit-learnの内部でNumPyとSciPyが利用されているのでこれもインストールする。

(python3.6) [root@d8b1c523c864 /]# pip install scikit-learn numpy scipy
Collecting scikit-learn
  Downloading scikit_learn-0.19.0-cp36-cp36m-manylinux1_x86_64.whl (12.4MB)
    100% |████████████████████████████████| 12.4MB 68kB/s
Collecting numpy
  Downloading numpy-1.13.3-cp36-cp36m-manylinux1_x86_64.whl (17.0MB)
    100% |████████████████████████████████| 17.0MB 60kB/s
Collecting scipy
  Downloading scipy-0.19.1-cp36-cp36m-manylinux1_x86_64.whl (48.2MB)
    100% |████████████████████████████████| 48.2MB 18kB/s
Installing collected packages: scikit-learn, numpy, scipy
Successfully installed numpy-1.13.3 scikit-learn-0.19.0 scipy-0.19.1

Wikipedeiaのデータはカテゴリのタグが付けてあり、富士山のページには「山梨県の山」や「静岡県の山」のような「〜の山」というカテゴリ名が含まれている。今回はこれを利用して分類を行う。
カテゴリ名に関する情報は技術評論社サポートページからダウンロードした「categorylist.txt」というファイルを利用する。このファイルを利用して前回作成した分かち書きデータから対応するページを取り出す。

(python3.6) [root@d8b1c523c864 /]# cd webdb100/03/
(python3.6) [root@d8b1c523c864 03]# python wiki_category_extract.py /wikipedia_wakatied_data.txt
output to /wikipedia_wakatied_data_categories.txt

ルートディレクトリに「wikipedia_wakatied_data_categories.txt」ファイルが作成されるので確認しておく。

サポートベクタマシンによる教師あり学習の実行

ここまでで前処理は終了する。後はサポートベクタマシンを実行するためのスクリプトで実行されるがその処理は次のようになっている。

  1. 文書のベクトル化
    • サポートベクタマシンでは入力がベクトルでなければならないので文書をベクトル化する必要がある。
    • ここではバイナリ表現のベクトルに変換している。
  2. データを学習データとテストデータに9対1になるように分ける
  3. 学習データを用いて学習を行う
  4. テストデータを用いて推定を行う
  5. 学習結果から分類を行う際にどの単語が最も影響したかを抽出する
(python3.6) [root@d8b1c523c864 03]# pwd
/webdb100/03
(python3.6) [root@d8b1c523c864 03]# python svm.py /wikipedia_wakatied_data_categories.txt

トピックモデルによる教師なし学習

正解が既知である学習データの場合は教師あり学習を行えるが、このようなデータを用意できない場合には教師なし学習を行う。教師なし学習の代表的なモデルがトピックモデルである。

トピックモデルのパラメータを求める方法としては「LDA(Latent Dirichlet Allocation、潜在的ディリクリ配分法)」という手法を使う。

前回用意した「wikipedia_watatied_data.txt」から入力データを用意し、gensimをインストールする。

(python3.6) [root@d8b1c523c864 /]# bash webdb100/03/lowcorpus-from-file.sh wikipedia_wakatied_data.txt
output to wikipedia_lowcorpus.txt
(python3.6) [root@d8b1c523c864 /]# pip install gensim
Collecting gensim
  Downloading gensim-3.0.1.tar.gz (59.5MB)
    100% |████████████████████████████████| 59.5MB 23kB/s
... 中略 ...
Successfully installed boto-2.48.0 bz2file-0.98 certifi-2017.7.27.1 chardet-3.0.4 gensim-3.0.1 idna-2.6 requests-2.18.4 six-1.11.0 smart-open-1.5.3 urllib3-1.22

ファイルの読み込みとLDAの実行を行う。

(python3.6) [root@d8b1c523c864 /]# python webdb100/03/gensim_LDA_lowcorpus.py wikipedia_lowcorpus.txt
start input = wikipedia_lowcorpus.txt, n = 20
   -> output = results_raw/wikipedia_tpc20.txt
read corpus done. then LDA.
... 中略 ...
(19, '0.013*"鉄道" + 0.013*"運行" + 0.012*"路線" + 0.012*"駅" + 0.010*"列車" + 0.008*"開業" + 0.007*"区間" + 0.006*"車両" + 0.006*"建設" + 0.006*"開始"')
output to : results_raw/wikipedia_tpc20.txt
elapsed_time : 134090.78 sec

この作業は非常に時間が掛かるので注意。私のMacBook Pro late2013 Intel Core i7 メモリ8GBで37時間程度掛かりました。

計算が上手くいくと次のような結果が出力される。

(0, '0.006*"いう" + 0.005*"寺院" + 0.005*"呼ぶ" + 0.005*"行う" + 0.005*"見る" + 0.004*"描く" + 0.004*"考える" + 0.004*"遺跡" + 0.004*"寺" + 0.004*"神"')
(1, '0.010*"使用" + 0.008*"発生" + 0.007*"用いる" + 0.006*"使う" + 0.006*"場合" + 0.004*"必要" + 0.004*"大きい" + 0.004*"高い" + 0.004*"水" + 0.004*"状態"')
(2, '0.012*"販売" + 0.012*"発売" + 0.008*"株式会社" + 0.007*"シリーズ" + 0.007*"ゲーム" + 0.007*"設立" + 0.006*"行う" + 0.006*"企業" + 0.006*"会社" + 0.006*"日本"')
(3, '0.006*"教会" + 0.006*"フランス" + 0.005*"間" + 0.004*"イギリス" + 0.004*"多く" + 0.003*"ローマ" + 0.003*"都市" + 0.003*"スペイン" + 0.003*"−1" + 0.003*"行う"')
(4, '0.006*"現在" + 0.004*"その後" + 0.003*"同年" + 0.003*"江戸時代" + 0.003*"東京" + 0.003*"京都" + 0.002*"いう" + 0.002*"当時" + 0.002*"明治" + 0.002*"行う"')
(5, '0.016*"出場" + 0.011*"チーム" + 0.010*"優勝" + 0.009*"大会" + 0.009*"選手" + 0.009*"シーズン" + 0.008*"所属" + 0.008*"獲得" + 0.007*"出身" + 0.007*"−1"')
(6, '0.008*"細胞" + 0.007*"治療" + 0.006*"研究" + 0.006*"患者" + 0.006*"反応" + 0.005*"用いる" + 0.005*"場合" + 0.004*"効果" + 0.004*"持つ" + 0.004*"含む"')
(7, '0.013*"開発" + 0.010*"エンジン" + 0.009*"飛行" + 0.009*"搭載" + 0.008*"設計" + 0.008*"行う" + 0.008*"使用" + 0.007*"計画" + 0.005*"製造" + 0.005*"装備"')
(8, '0.031*"放送" + 0.020*"番組" + 0.009*"開催" + 0.009*"行う" + 0.007*"出演" + 0.006*"制作" + 0.006*"担当" + 0.006*"配信" + 0.006*"イベント" + 0.006*"開始"')
(9, '0.009*"定義" + 0.009*"持つ" + 0.007*"存在" + 0.007*"場合" + 0.006*"用いる" + 0.006*"与える" + 0.006*"次" + 0.005*"空間" + 0.005*"考える" + 0.005*"呼ぶ"')
(10, '0.012*"現在" + 0.011*"位置" + 0.011*"建設" + 0.011*"地区" + 0.010*"地域" + 0.007*"南" + 0.007*"人口" + 0.007*"北" + 0.007*"町" + 0.007*"図書館"')
(11, '0.007*"部隊" + 0.007*"攻撃" + 0.005*"戦闘" + 0.005*"行う" + 0.004*"アメリカ" + 0.004*"指揮" + 0.004*"受ける" + 0.004*"アメリカ合衆国" + 0.004*"海軍" + 0.004*"作戦"')
(12, '0.011*"映画" + 0.009*"作品" + 0.008*"アルバム" + 0.008*"活動" + 0.007*"出演" + 0.006*"日本" + 0.006*"監督" + 0.006*"シングル" + 0.006*"曲" + 0.005*"発表"')
(13, '0.009*"属" + 0.007*"植物" + 0.005*"種" + 0.005*"葉" + 0.004*"発見" + 0.004*"多い" + 0.004*"動物" + 0.004*"知る" + 0.004*"見る" + 0.004*"大きい"')
(14, '0.006*"ない" + 0.006*"作品" + 0.006*"自分" + 0.004*"言う" + 0.004*"描く" + 0.004*"女性" + 0.004*"いう" + 0.004*"登場" + 0.004*"見る" + 0.004*"思う"')
(15, '0.011*"行う" + 0.008*"日本" + 0.004*"就任" + 0.004*"受ける" + 0.004*"設立" + 0.003*"活動" + 0.003*"委員会" + 0.003*"組織" + 0.003*"当選" + 0.003*"実施"')
(16, '0.005*"中国" + 0.005*"子" + 0.005*"元年" + 0.005*"父" + 0.003*"死去" + 0.003*"受ける" + 0.003*"王" + 0.003*"将軍" + 0.002*"朝鮮" + 0.002*"任"')
(17, '0.014*"大学" + 0.014*"研究" + 0.014*"日本" + 0.012*"教授" + 0.012*"卒業" + 0.010*"務める" + 0.007*"学ぶ" + 0.007*"−1" + 0.007*"出版" + 0.006*"出身"')
(18, '0.011*"使用" + 0.011*"場合" + 0.009*"可能" + 0.007*"使う" + 0.007*"機能" + 0.006*"システム" + 0.006*"開発" + 0.006*"利用" + 0.006*"対応" + 0.006*"提供"')
(19, '0.013*"鉄道" + 0.013*"運行" + 0.012*"路線" + 0.012*"駅" + 0.010*"列車" + 0.008*"開業" + 0.007*"区間" + 0.006*"車両" + 0.006*"建設" + 0.006*"開始"')
output to : results_raw/wikipedia_tpc20.txt
elapsed_time : 134090.78 sec