自然言語処理勉強結果「機械学習の分類器」

自然言語処理学習結果

前々回は、そもそもの自然言語処理とは何かと、
それによく使われる機械学習の概要を説明した。

自然言語処理勉強結果「機械学習って何?」 | Shino’s Mind Archive

ただ、これだけだとまだ具体的なものがないため、
イメージも湧きづらい。

というわけで、
今回は早速具体的なものを扱っていこう。

機械学習のうち、
教師あり学習の中の「分類」というものを
解説していく。

なお、本講座は以下の本を参考に進めている。

もしよかったら、中身を覗いてみて欲しい。

Amazon.co.jp: Javaで学ぶ自然言語処理と機械学習 : 杉本 徹, 岩下志乃: 本
Amazon.co.jp: Javaで学ぶ自然言語処理と機械学習 : 杉本 徹, 岩下志乃: 本
スポンサーリンク

分類器

軽く、前回の復習をしておこう。

機械学習にはその手法によって大きく
4つの内容に枝分かれしていた。

  • 教師あり学習
  • 教師なし学習
  • 強化学習
  • 深層学習

その中で、今回は一番上の教師あり学習
学習時に入力とその正解の対を利用するもの
深堀りしていく。

これには、
入力データをグループに分ける分類
数値を得る回帰などがある。

で、この章のタイトルになっている分類器は、
そのまま分類を行うものだ。

これは分類先によっても呼び方が分けられていて、
2つに分類するものを二値分類
3つ以上に分類するものを多値分類と呼ぶ。

分類器の処理流れ

分類器では、大きく3つの項目で処理を行う。

  1. データの用意
  2. 学習
  3. 適用、評価

データの用意

まず、学習するためのデータを用意しなければならない

で、このデータには、実はポイントがある。

何かというと、
通常であれば、そのままのデータは使用できない
ということだ。

どういうことかというと、
例えばWebページを何か分類したいとしよう。

そのときに、
ただそのHTMLファイルを持ってくるだけでは
適用できない。

そのために何をするかというと、
そのHTMLファイルの特徴を数値で表す必要がある

もちろん、ただ一つの特徴のこともあれば、
複数の特徴を考えなければいけないこともある。

多くは、複数の特徴になるだろう。

この、複数の特徴を数値列にしたものを、
特徴ベクトルと呼ぶ。

実際に学習する際には、
この特徴ベクトルを入力する必要があるのだ。

なお、ベクトルという言葉が出てきているが、
高校の時に勉強した向きと大きさではなく、
単なる数値列と思ってくれていい。

ただ、計算にはベクトルの内容を使ったりもするので、
その時は適宜解説を入れよう。

この、一つ一つの数値のことを
特徴量素性と呼んだりもする。

というわけで、データを用意する段階で、
純粋なデータから、この特徴ベクトルを
求めなければいけない

この処理のことを特徴抽出と呼び、
これを求める、あるいは
求めるために行う処理前処理と呼ぶ。

さらに、特徴量の数(特徴ベクトルの次元)は
多ければ多いというわけでもない

これも、本当に学習に必要なものを
取捨選択する必要がある。

この取捨選択を、特徴選択という。

長々と書いてきたが、
まとめると以下のような流れだ。

  • 入力の元となるデータを持ってくる
  • そこから前処理をして、特徴ベクトルを求める
  • 求めた特徴ベクトルから、本当に必要な特徴を選択する

ここまでやって、ようやく学習データが得られる。

学習

ここからが本番だ。

用意した学習データを実際に入力して、学習を行う。

と、そろそろこの学習で具体的に
何をしているかも解説しよう。

分類器にもよるが、
数式に含まれるパラメータを調節する(=求める)方法が
よく使われる。

この具体的な内容は、本記事後半で解説する
ナイーブベイズ分類器というもので詳しく見ていこう。

なお、これ以外にも
学習によっては変化しないハイパーパラメータと呼ばれる
パラメータが存在することもある。

こちらは、学習の状況に応じて、
人の手によって変える必要がある。

適用、評価

学習したら終わりではない。

それがどのくらいの精度で分類できるか
という評価も必要になる。

この評価にも色々と計算等があるのだが、
今回入れてしまうと長くなってしまうので、
次回に回そう。

で、それが済んだとして、
実際に答えが分からないデータを入力して分類する、
という形になる。

これが、大雑把ではあるが分類器で行う処理の流れだ。

では、具体的な分類器を見ていこう。

今回は、ナイーブベイズ分類器というものを解説する。

ナイーブベイズ分類器

これは、主に確率の考え方を使った分類器だ。

他と比べれば単純なので、
最初の説明にはもってこいだろう。

…あくまで他と比べれば。

最初に前提と結論を出してしまおう。

まず、前提は、

  • 入力となる特徴ベクトルの、各特徴量は互いに独立している
    (ある値が、他の値に影響されない)
  • 各特徴量は、0もしくは1の値を取る
    ※今回の説明用

この二つだ。

で、入力データを\(x\)、
出力となる分類のラベルを\(c\)と置く。

そして、\(x\)が入力されたときに、
ラベルが\(c\)となる条件付き確率\(P(c|x)\)を最大にする
というのが結論だ。

…私が最初わけがわからなかったので、
もうちょっと補足しよう。

言葉を付け加えて書くと、
まず入力は特徴ベクトル\(x = (x_1, x_2, …, x_n)\)であり、
これがある\(c\)というグループに分類される。

学習時には、この組み合わせが入力されるわけだ。

で、このときに
ある特徴量\(x_i\)が取る値について、
それがどのくらいの確率で\(c\)に分類されるのか
という確率に注目する。

これを学習によって算出し、実際の判定では、
確率が最も高くなる\(c\)を選べばいい
ということになるのだ。

ものすごく簡単に言うと、
確率的にこれっぽいよというものを出力することになる。

計算してみよう

では、具体的にどんな確率を出すのかを見ていこう。

なお、これから使う確率の話は、
別記事で解説を行った。

適宜、参照しながら進めて欲しい。

ナイーブベイズ分類器を理解するための数学「確率」 | Shino’s Mind Archive

まず、最初にも書いた通り、
ある入力データ\(x\)が入力されたとき、
ラベルが\(c\)となる確率は、
条件付き確率\(P(c|x)\)で表される。

これが一番大きくなる\(c\)を求めればいいのだが、
このままでは計算が非常にしづらい。

というわけで、

まずはこれをベイズの定理で書き直そう。

$$P(c|x) = \frac{P(c)P(x|c)}{P(x)}$$

右辺の分母\(P(x)\)は\(c\)によって動くことはないので、
分子の\(P(c)P(x|c)\)を最大にすればいい
という問題に置き換えることができる。

なお、出力が\(c\)となる確率\(P(c)\)は、
以下の式で出すことができる。

$$P(c) = \frac{正解ラベルがcである学習データ数}{全学習データ数}$$

あとは\(P(x|c)\)の部分だ。

ここで、左にあるベクトル\(x\)なのだが、
これは意味を考えると
特徴量\(x_1\)かつ特徴量\(x_2\)かつ…
と連なっていることが分かる。

そして、前提からこれらは互いに独立していたはずだ。

というわけで、
バラバラにして掛け算することで表せる。

$$P(x|c) = P(x_1|c) \times P(x_2|c) \times … \times P(x_n|c)$$

掛け算が並んでいるので、
記号\(\Pi\)を使ってまとめてしまおう。

$$P(x|c) = \Pi_{i = 1}^{n}P(x_i|c)$$

これで、ラベルが\(c\)となるような各特徴量\(x_i\)が
どのくらいの確率で出てくるかを見ればいいことになる。

ここも、もうちょっと深掘りしていこう。

もう一つの前提で、
各特徴量は0もしくは1のどちらかだった。

というわけで、ラベル\(c\)となる入力の
特徴量\(x_i\)が1である確率を\(p(x_i, c)\)と置こう。

すると、具体的には
以下のような計算式で求めることができる。

$$p(x_i, c) = \frac{正解ラベルがcかつ特徴量x_iが1である学習データ数}{正解ラベルがcである学習データ数}$$

あとは、
これをゴリゴリ計算していけばいいということになる。

学習データによってこれを求めた後、
実際にデータ\(y = (y_1, y_2, …, y_n)\)を分類するときは、

$$
\begin{equation}
P(y_i|c) = \left \{
\begin{array}{l}
p(x_i, c) \; (y_i = 1) \\
1-p(x_i, c) \; (y_i = 0)
\end{array}
\right.
\end{equation}
$$

として、\(P(y|c)\)を求めればよい。

…だけで上手くいけばよかったのだが、
実はこれで上手くいかないパターンが存在する。

ゼロ頻度問題

上で、ラベルが\(c\)であるような
各特徴量\(x_i\)の確率(=割合)を考えたのだが、
ちょっと問題がある。

たまたま、学習データの全てで、
\(i\)番目の特徴量が0だった場合だ。

こうすると、上式の\(p_(x_i, c)\)が0となり、
\(P(x|c)\)の値も0…つまり、
その特徴量が1だった時点で判定が確定してしまう

こういった状態を、ゼロ頻度問題という。

これは極端な例なので、避けたい。

そのため、学習によって変化しない
ハイパーパラメータ\(\alpha\)を導入して、
\(p_(x_i, c)\)と\(P(c)\)を以下のように直す。

$$p(x_i, c) = \frac{正解ラベルがcかつ特徴量x_iが1である学習データ数 + \alpha}{正解ラベルがcである学習データ数 + 2\alpha}$$

$$P(c) = \frac{正解ラベルがcである学習データ数 + \alpha}{全学習データ数 + ラベル種類数 \times \alpha}$$

ハイパーパラメータ\(\alpha\)は、
上でもちらっと書いた通り、
学習によって求める数値ではない。

何度か繰り返し学習と評価を行って、
手動で数値を調整する必要がある。

具体例で計算してみよう

やたらと色々数式を書いてみたが、
具体的なデータで試してみよう。

20個のデータを用意しておいて、
うち19個を学習データとして学習し、
残り1個を分類してみる。

用いるデータは、参考にしている本から引用している。

表に直すと以下の通りだ。

なお、空欄は0としよう。

データ名正解ラベル\(x_1\)\(x_2\)\(x_3\)\(x_4\)\(x_5\)\(x_6\)\(x_7\)
データ1111
データ221111
データ31111
データ41111111
データ51111
データ6211
データ71111111
データ821
データ91111
データ10211
データ112111
データ1211111
データ1311111
データ141111
データ152111
データ16211
データ17211
データ1821
データ1921111
データ20111

ハイパーパラメータである\(\alpha\)は1としておこう。

これで、まずデータ1からデータ19までで
\(P(c)\)と\(P(x|c)\)を求める。

\(P(c)\)について、以下の式で求めることができた。

$$P(c) = \frac{正解ラベルがcである学習データ数 + \alpha}{全学習データ数 + ラベル種類数 \times \alpha}$$

まず、\(c\)に依らない分母から。

全学習データ数は19、ラベル種類数は2、\(\alpha\)は1。

計算すると、\(19 + 2 \times 1 = 21\)になる。

次に分子。

正解ラベルが1について、
学習データ数は9個なので、\(9 + 1 = 10\)。

正解ラベルが2について、
学習データ数は10個なので、\(10 + 1 = 11\)。

よって、\(P(c)\)は、

$$P(c = 1) = \frac{10}{21}$$

$$P(c = 2) = \frac{11}{21}$$

となる。

次に、\(P(x|c)\)を求めるために、
\(p(x_i, c)\)を出していこう。

とはいえ、全部計算していると長くなりすぎるので、
一個だけ具体的に計算し、他は計算結果のみを載せる。

というわけで、\(i = 1\)、\(c = 1\)について見ていこう。

\(p(x_1, c=1)\)は以下のように計算できた。

$$p(x_1, c=1) = \frac{正解ラベルが1かつ特徴量x_1が1である学習データ数 + \alpha}{正解ラベルが1である学習データ数 + 2\alpha}$$

同じように、分母から見ていこう。

正解ラベルが1のデータ数は9、
\(\alpha\)は1なので、\(9 + 2 \times 1 = 11\)。

分子について、正解ラベルが1かつ
特徴量\(x_1\)が1のデータ数は7個。

\(\alpha\)の1を足すので、分子は8だ。

よって、

$$p(x_1, c=1) = \frac{8}{11}$$

と分かった。

同じように計算すると、以下の表のようになる。

\(p(x_i, c)\)\(i = 1\)\(i = 2\)\(i = 3\)\(i = 4\)\(i = 5\)\(i = 6\)\(i = 7\)
\(c = 1\)\(\frac{8}{11}\)\(\frac{8}{11}\)\(\frac{6}{11}\)\(\frac{7}{11}\)\(\frac{6}{11}\)\(\frac{5}{11}\)\(\frac{1}{11}\)
\(c = 2\)\(\frac{3}{12}\)\(\frac{4}{12}\)\(\frac{4}{12}\)\(\frac{8}{12}\)\(\frac{2}{12}\)\(\frac{2}{12}\)\(\frac{8}{12}\)

これで、学習完了だ。

では、データ20(これが\(y\))が
どちらになるか推測してみよう。

\(P(c)P(y|c)\)を計算すればよかった。

\(P(c)\)は入力に依らないので、
\(P(y|c)\)だけ見ていこう。

\(P(y|c)\)は、\(P(y_1|c)\)から\(P(y_7|c)\)まで
掛け合わせればよかった。

そして、各\(P(y_i, c)\)は、

$$
\begin{equation}
P(y_i|c) = \left \{
\begin{array}{l}
p(x_i, c) \; (y_i = 1) \\
1-p(x_i, c) \; (y_i = 0)
\end{array}
\right.
\end{equation}
$$

で求めることができた。

というわけで、まず\(c = 1\)から見ていこう。

データ20を見ると、
\(i\)が4, 5, 6のときに1で他は0なので、
\(i\)が1, 2, 3, 7は1から引いたものを掛け合わせる。

すると、

$$
\begin{eqnarray}
P(y|c=1) & = & (1-\frac{8}{11}) \times (1-\frac{8}{11}) \times (1-\frac{6}{11}) \times \frac{7}{11} \times \frac{6}{11} \times \frac{5}{11} \times (1-\frac{1}{11}) \\
& = & \frac{3}{11} \times \frac{3}{11} \times \frac{5}{11} \times \frac{7}{11} \times \frac{6}{11} \times \frac{5}{11} \times \frac{10}{11} \\
& \sim & 0.004849
\end{eqnarray}$$

最後、ちょっと計算が面倒なのでExcel先生に頼った。

四捨五入して正確なイコールではないので、
\(\sim\)としている。

さて、もう一つ、今度は\(c=2\)について。

考え方は全く同じなので、結果だけにしよう。

$$P(y|c=2) \sim 0.002058$$

最後に、\(P(c)\)と掛け合わせよう。

$$P(c = 1) = \frac{10}{21}$$

$$P(c = 2) = \frac{11}{21}$$

だったので、計算すると…

$$P(c=1)P(y|c=1) \sim 0.002309$$

$$P(c=2)P(y|c=2) \sim 0.001078$$

よって、\(c=1\)の方が大きいので、
このデータは1に分類される、ということになる。

実際、参考図書ではこのラベルも提示されていて、
それは1だった。

うまく導けた、というわけだ。

長くなってしまったが、感覚は掴めただろうか。

おわりに

今回は、機械学習教師あり学習
その中の分類というものに焦点を当てて解説を行った。

その具体例として、
ナイーブベイズ分類器というものも解説した。

かなり長くなったが、
これでもう簡単な分類に関しては機械学習ができる。

…とはいえ、まだ
どの程度の精度で上手くいっているかわからない

というわけで、次回はこの評価方法を解説しよう。

…そして、次回以降はプログラムで
分類を行うことを許してほしい。

手作業でやると思いのほか面倒だった。

しかし、だからこそプログラムでやる価値がある
というものだ。

簡単なものからでいいので、まずはやってみよう。

コメント

タイトルとURLをコピーしました