読者です 読者をやめる 読者になる 読者になる

テキストマイニングのための機械学習超入門 一夜目

 テキストマイニングに必要なパターン認識と機械学習について学びます。非常に初歩的な話から始めます。対象者は「テキストマイニングに興味があり、用いられる手法の中身を知りたい(けれど高度な数学は厳しい…)」というビジネスマンや学生さんです。数式は出来る限り「使います」。使わないと意味するところは理解できません。ただし、愚直に数式の一行一行を手計算で順を追って解いていきますし、必要な数学知識はその都度説明し、前提知識は求めませんので「数式出てくるの?じゃあついていけないのでは…」という心配は不要です。この記事の特徴は「機械学習の手法をやたら冗長な数式と過剰なまでの例を用いて、くどくどと同じ話を何度も説明する」ことです。


 筆者ことあんちべは純文系出身で、数学や統計学、プログラミングは全然学生時代やってこなかった上、業務でも機械学習を使うことなんて皆無、それどころか機械学習なんて言葉は就職してからようやく知った…という超ド素人です。それ故、自然言語処理のプロの方がお勧めしてくださる専門書籍や論文は難しくて全く読めず、かと言ってテキストマイニングのビジネス読み物では業務で活かすレベルには達せず、仕方なく高校生レベルの数学書から2年かけてちょっとずつ勉強してきました。そんな私が、今まで勉強してきたことをまとめるために記事を書くので、ひたすら冗長ですが、その分専門書籍によくある「式aを展開すると式bになる、自明である」のような「え、これ何をどうすればaからbに変形出来るの???」というジャンプを皆無にしたいと思っています。何か不明な点があればご質問ください。


 以下三冊(難易度順)を教科書として利用します。

  1. フリーソフトでつくる音声認識システム
  2. わかりやすいパターン認識
  3. 言語処理のための機械学習入門

この三冊は非常に分かりやすく、また、必要な数学は付録で説明されているため、事前知識はほとんど必要ありません(行列式偏微分くらいはわかってないと辛いですが…)。副読本として「パターン認識と機械学習」を挙げておきます。辞書がわりに使います。この記事の目標は、

  1. 言語処理のための機械学習入門の内容を理解できること
  2. パーセプトロン、ナイーブベイズ、k-meansクラスタリング程度の機械学習の基礎的な手法を実装できるようになること

です。何日かかるかわかりませんが、頑張りましょう。


 さて、そろそろパターン認識と機械学習の勉強を始めましょう。と、その前に。そもそも「パターン認識と機械学習*1とは何でしょうか?何やらテキストマイニング自然言語処理で必須らしいのですが、それの意味するところとは?教科書の定義を読んでみると、まず、パターン認識とは「観測されたパターンを特定の概念(クラスやカテゴリという)に対応させること」だそうです。…ちょっと分かりづらいですね。例を考えてみましょう。あなたが家に入ると、キッチンからスパイシーな香りが漂ってきたとしましょう。また、テーブルの上には近所のスーパーで人参やジャガイモを買ったレシートが置いてあったとします。あなたはこの二つの事実から、「今夜はカレーだな」と思いました。まとめると、「嗅覚的パターンの特徴:=キッチンからスパイシーな匂いがする」、「視覚的パターンの特徴:=人参やジャガイモを買ったレシート」という二つの観測パターンから「今晩はカレーだな」というように料理のクラスを導いたのです。もし、ツンとくる酸の匂いと沢山の刺身のレシートを観測したら「今夜はお寿司だな」と料理のクラスを認識できそうですね。このように、人間には観察されたパターンから、ある特定のクラスを認識することが可能です。これをパターン認識といいます。そして、テキストマイニングでいうところのパターン認識は、人間が行うパターン認識を機械にやってもらうことです。機械にパターン認識をしてもらえば、人間がやるよりも大量かつ高速、しかも安価にデータを処理することが出来て、人間は大変楽になります。では、パターン認識をどのようにテキストマイニングに活用するのでしょうか?例えばメールのスパム判定があります。人間が見ると、スパムメールかどうかはかなり高精度に認識できますね。しかし、人手でスパムメールと大切なメールを分類するのは面倒です。機械にスパムメールを認識する能力を持たせ、振り分け作業を任せて楽をしましょう。

 ここで一つの疑問が生まれます。「機械に人間がやるような認識能力を持たせて仕事をしてもらうのってAI(人工知能)では?」確かにそうですね。どこからどこまでが人工知能分野、パターン認識分野かは専門家でも意見はまちまちだったりします。大雑把な指針として、AIとパターン認識の違いは、

  • 人工知能:人間がする判断を「人間がするように」機械にもやらせる
  • パターン認識:人間がする判断を「機械がやりやすいように」機械にやらせる

ことです。これは「鳥のように空を飛びたい!」という欲求に対し、

  • 人工知能:鳥を模倣して羽ばたいて飛ぶ
  • パターン認識:ジェットやプロペラを作って飛ぶ

という違いです。人間や知能/知性そのものを作ることを目指すか、それらが持つ能力を作ることを目指すかの違いと言ってもいいでしょう。



●パターン認識の手順
 パターン認識がどのようなものなのか、その概要が掴めたところで、実際どのように実行するのかを追っていきましょう。次のような手順でパターン認識を進めていきます。

パターン→前処理部→特徴抽出部→識別部(識別辞書)→識別結果出力部

特徴抽出など、あまり日常では聞きなれない単語が出てきましたね。OCR(文字認識)を例にとってパターン認識の手順を考えていきましょう。OCRの場合、パターンに該当するのは手書き/印刷文字といったデータです。「前処理部」はパターンをスキャナやカメラで画像取り込みする処理です。「特徴抽出部」は文字を識別するのに役立つ特徴を抽出(=言い換えると、役に立たないデータを捨てる。例えば、文字色は、読み込んだ文字を特定するのに役立たないので捨てる)する処理です。「識別部」は読み込んだ画像の特徴と辞書の情報を比較し、最も当てはまりのよい文字を識別する処理です。「識別結果出力部」では、識別部で得られた識別結果を、ユーザーの役に立つように出力する、つまり読み込んだ文字画像に該当する文字列を出力する処理です。パターンと前処理部、識別結果出力部はまだわかりますが、特徴抽出部と識別部の処理がよくわかりませんね。ここを詳細に見ていきましょう。


●特徴抽出部とは
 パターンがどんなクラスに属するかを認識するためには、各パターンの特徴を掴む必要があります。適切な特徴を掴むことが出来れば、上手くクラスを識別することが可能になります。逆に言うと、どんなに(後で登場する)識別部で頑張っても、特徴をつかめなければ識別が上手くいきません。特徴抽出は非常に重要です。
 例として、料理を識別するにはどんな特徴を把握することが必要でしょうか?食材の種類?材料費?調理器具?色々考えることができそうですね。材料費が10万円もかかっているのに、出来た料理が目玉焼きということは恐らく無いでしょう。同じく、調理器具として土鍋を使っているのに、出来た料理が目玉焼きということもまず無いでしょう。このように、材料費や調理器具という特徴を使えば、ある程度料理を識別しやすくなるかもしれません。しかし、材料費や調理器具で料理を識別することは一般的にかなり難しいでしょう。それよりも食材を知ったほうが識別しやすそうですね。なので、料理を識別する場合は、食材の方が調理費用や器具よりも適切な特徴と言えます。あまり識別に有用でない特徴をデータとしてもたせると、計算量が増えてしまい、計算時間が伸びたり、認識精度が悪くなったりします。適切な特徴を選択するよう心掛けねばなりません(具体的にどう選択するかはまた後日)。


 さて、そろそろ数式っぽいものが登場します:D。特徴抽出部とはどのようなものなのか、教科書を参照してみましょう。

パターンからd個の特徴を抽出した場合、それをd次元のベクトルとして次のように表現できる。
\it{\mathbf{x}} = (x_1, x_2, x_3, ..., x_d)^t*2
このd次元空間を特徴空間という。また、そのベクトル\it{\mathbf{x}}を特徴ベクトルという。
特徴ベクトルは特徴空間上の一点になる。
(パターンからどんな特徴を抽出すべきか?何個の特徴を抽出すべきか?は問題やデータに依存する)

抽象的すぎて、何を言ってるのかさっぱりですね。d個とか言われてもよくわからないので、具体的に数値を入れていきましょう。

パターンから3個の特徴を抽出したとする。その場合、特徴空間は3次元であり、
あるパターンの特徴ベクトルが\it{\mathbf{x}} = (2, 3, 7)の場合、
そのパターンは特徴空間上で(2, 3, 7)地点に位置する。


…まだよくわかりませんね。我々の関心のあるテキストマイニングに話題を絞って、具体的に意味を理解するようにしましょう。「どんな特徴を抽出すべきか?」に関しては、各パターンを識別しやすいよう設定しなければなりません。先程のOCRの例では、文字色を特徴として設定するのは不適切ですね。テキストマイニングでは「文書に出てくる単語の頻度」をその文書の特徴とすることが多々あります。文書をテーマごとに分類するというタスクがあるとすると、「サッカー」や「野球」などの単語頻度が大きい文書は「スポーツ」に分類し、「選挙」や「政党」などの単語頻度が大きい文書は「政治」に分類する、というように特徴を活用することが出来そうですね。これを特徴ベクトルで表現すると、 (サッカー, 野球, 選挙, 政党)という4次元*3の特徴空間を考え、ベクトルの各要素を単語頻度だとします。つまり、文書にサッカーが5回、野球が7回、選挙が13回、政党が2回出現した場合、特徴ベクトルを\it{\mathbf{x}} = (5, 7, 13, 2)と考える、ということです。ここで、文書aがx_a = (10, 37, 1, 0)、文書bがx_b = (1, 2, 108, 47)であった場合、文書aはスポーツに、文書bは政治に分類出来るのではないかと考えることが出来ます。(※これは説明の簡便のため、非常に単純化した話であって、実際の分析では文書の長さや単語頻度に対して正規化を行うなど、様々な工夫が必要です)


●識別部の処理
 入力された特徴ベクトルが、どのクラスに属するかを識別する処理です。どのような特徴をもったパターンを各クラスに属するかを識別するために「プロトタイプ」を設定します。プロトタイプとは、クラスを代表する特徴ベクトルのことです。出身地を識別するというケースであれば、香川県民のプロトタイプは毎日うどん、大阪府民のプロトタイプは毎日たこ焼きやお好み焼きを食べるといった各クラスの典型パターンのことです。


 最も基本的な識別手法として挙げられる最近傍決定則(Nearest Neighbor Method)は、入力された特徴ベクトルがどのプロトタイプに最も近いかで判別する手法です。あなたが毎週うどんを食べ、かつ、全くたこ焼きやお好み焼きを食べない人なら、大阪府民よりも香川県民のプロトタイプに近いので、どちらかに分類するとするなら香川県民に分類するわけです。


 最近傍決定則を用いて、文書を「スポーツ」「政治」の2つのテーマに分類するタスクを考えてみましょう。クラスは「スポーツ」と「政治」の2つ、特徴空間をx = (サッカー, 野球, 選挙, 政党)とします。スポーツクラスのプロトタイプをx_{sports} = (10, 10, 0, 0)、政治クラスのプロトタイプをx_{politics} = (0, 0, 10, 10)と設定したとします。入力パターンの特徴ベクトルがx_{input} = (9, 14, 0, 2)であるとき、各プロトタイプと入力パターンの特徴ベクトルの距離を測る何らかの関数fを用意し、どのプロトタイプが最も近いかを考えます。

 ここで具体的なイメージを掴むため、関数fの中身を実際に定義してみましょう。関数fを「特徴ベクトルの各要素の差の二乗(計算の便宜上、負の符号を消すため)を合計した値を距離とする関数」であると定義します。入力パターンの特徴ベクトルがx_{input} = (9, 14, 0, 2)、スポーツクラスのプロトタイプの特徴ベクトルがx_{sports} = (10, 10, 0, 0)なので、

  1. 要素目:9 - 10 = 1
  2. 要素目:14 - 10 = 4
  3. 要素目:0 - 0 = 0
  4. 要素目:2 - 0 = 2

これで入力パターンとスポーツクラスのプロトタイプとの各要素の差を計算できました。次に、各要素の差の二乗を合計します。
1^2 + 4^2 + 0^2 + 2^2 = 21
これを入力パターンとスポーツクラスのプロトタイプとの距離だとします。

同じようにして、入力パターンの特徴ベクトルx_{input} = (9, 14, 0, 2)と政治クラスのプロトタイプの特徴ベクトルx_{politics} = (0, 0, 10, 10)の距離を測ります。

  1. 要素目:9 - 0 = 9
  2. 要素目:14 - 0 = 14
  3. 要素目:0 - 10 = -10
  4. 要素目:2 - 10 = -8

合計値、つまり両者の距離は9^2 + 14^2 + (-10)^2 + (-8)^2 = 441となりました。直感でも明らかなように、入力パターンは政治よりもスポーツの方が近いため、この入力文書はスポーツに分類されます。無事識別部の処理が完了しました。後はこの分類結果を、ユーザーに役立つように提示する識別結果出力部に渡し、終了です。というわけで、パターン認識の概要と、その手順を学びました。が、ここでまた一つ疑問が生まれます。プロトタイプってどうやって設定するのでしょうか?


機械学習
 上記の説明ではプロトタイプが与えられていましたが、実務において、どのような特徴ベクトルがプロトタイプとして相応しいかを判断することは非常に難しい問題です。どんなに上手く特徴を抽出し、識別処理を施しても、そもそものプロトタイプが誤っていれば、識別は間違ってしまいます。先程の出身地を識別する例で言うと「大阪人のプロトタイプは巨人ファンである」のように明らかに言語道断な間違った設定をしてしまえば、決して大阪人の正しい識別は出来ません、もう絶対に出来ませんね。ではどうすればいいのでしょうか?OCRであれば、手書き文字や印刷文字を用意し、どのような特徴ベクトルを持てばどのクラスに属するかという正しいデータを大量に記録しておきます。スポーツと政治の分類問題であれば、スポーツや政治について言及している文書を大量に集め、実際にどのクラスにどの単語がどのような頻度で出現しているかの分布情報を取得します。出身地識別なら、大阪人を大量に招集し、どの野球チームのファンかを聞いて回り、実際大阪人はどのチームのファンが多いのかのデータを取ります。これらのデータのことを学習データ、正解データ、教師データ、正例などといいます。大量に学習データがあれば、ある程度の文字画像の揺れを許容して正しい文字認識を行うことが出来ます。このように、各クラスを正しく判別できるようなプロトタイプを求めるため、大量の学習データを統計的に用いて、より良いプロトタイプとは何かを機械に自動で学習させていく一連の手法を(教師あり)統計的機械学習、あるいは単に機械学習といいます。人間は沢山の経験を積み、自分の判断の精度を向上させることが出来ます。その学習能力を機械に持たせるのが機械学習です。テキストマイニングは、パターン認識と機械学習を用いて、より精度の高い分析を可能にします(具体的にどのように学習していくのかはまた後日)。


●終わりに
 お疲れ様でした。本日は数式もほぼ登場せず、読み物としてパターン認識と機械学習の概念を紹介しました。明日以降、具体的な手法について学んでいきましょう。

*1:専門家の中でもパターン認識と機械学習(さらに言うと人工知能データマイニングも)を別区分とする人も居ますし、区別しない人も居ます。本稿では基本的に機械学習とパターン認識を区別しませんが、説明の便宜のため、主に識別部をパターン認識、プロトタイプの学習部を機械学習とします。なお、昔はまとめてパターン認識と呼称する方が多かった印象で、最近は機械学習と呼称するのが一般的であるように見えます(個人的見解)

*2:右肩についてるtは転置を意味する。転置とは列(縦)ベクトルを行(横)ベクトルに(あるいは逆に)する操作である。ベクトルは本来縦に要素を並べて書くが、表記の都合上、横に並べた方が書きやすいので転置を使っている。そんな操作しても問題ないのか?という点につていてはまた後日。無論ここでは問題ないので行っています

*3:次元という単語を恐れる必要はありません。単に変数が4つあるということを示しているだけに過ぎません。変数が一つなら直線上で、変数が二つなら平面上で表現することが出来ますね。変数の数だけ軸が存在し、1変数なら1次元=直線、2変数なら2次元=平面…となるだけのことです。もうちょっと細かい話をすると、線形独立な変数の数であるとか色々ありますが、線形代数の知識が必要なので、また後日にしましょう