python機械学習プログラミング(2章30ページのプログラム)

さて、なんかグラフが出てきました。
とりあえず分類できたんだ。
でも、分類も何も初めから分かれてるのに分類???
何してるんだろ??
そこで、再びプログラムが出てきて、、、
今度は何するの?と思ってしまったり。。。とりあえず、勉強のためだとひたすら読み続けていました。
自分なりの理解

from matplotlib.colors import ListedColormap
def plot_decision_regions(X, y, classifier, resolution=0.02):
    markers = ('s', 'x', 'o', '^','v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() +1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() +1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),np.arange(x2_min, x2_max, resolution))
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())
    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], y=X[y == cl,1],alpha=0.8, c=cmap(idx), marker=markers[idx], label=cl)

さて、読み始めて間もないころ、理解もできず目で字を追う事しかできなかったとき、各所にあるプログラムがすごく大変なことをしているという先入観から余計に目で追っていました。
30ページにあるプログラムが機械学習のためのプログラムなんだと思いながらひたすら入力して。。。

なので、このプログラムがなぜここにあって、これが意味するものは何なのか?といったことがわかるだけで、見通しが良くなると思います。なので、ここで自分なりの理解で伝えさせてもらおうと思います。

このプログラムは先ほど実行したPerceptronのプログラムが何を行ったかを理解するのに役立ちます。
29ページで実行したプログラムの結果は30ページの上の方のグラフとして表示されます。このグラフは1回目の学習で2個誤って分類、2回目も2個誤って分類、3回目は3個誤って分類、6回目には誤って分類することなく学習を完了したという事を表しています。
つまり、24ページで作成したPerceptronを使用して分類した結果、今回のケースでは6回学習すればきれいに分類できるという事になったことがわかりました。

これから作るプログラムも29ページのグラフと同様に、24ページで作成したPerceptronが何を基準に分類したかをグラフに表示して境界線を目で見てみて理解を深めようというプログラムになります。

このプログラムではグラフを色分けをして図示するので、少し長くなっているのですが、このプログラムを活用して、31ページのプログラムと連動することで、Perceptronが分類した境界線を表示します。

さて、自分なりにどう理解したかをお伝えしていきます。

  1. matplotlib.colorsにアクセスして、ListedColormapという関数をお借りしますね!!というpythonとのお約束です。
  2. 境界線を引くためのプログラムの名前をplot_decision_regionsという名前にします。
  3. プロットする点の形に何を使うか決めて、markersという変数に入れておきます。左から順に四角、バツ、丸、上三角、下三角です。
  4. 色もあらかじめ何色を使うか準備しておきます。colorsという変数に、赤、青、ライトグリーン、グレー、シアンという順番で入れておきます。
  5. 上でお借りしているListedColormapをここで使用します。先ほど作成した色のリストcolorsから色をとってきます。yの種類、つまり、1と-1の2種類をとることになります。それを変数cmapに入れておきます。
  6. 描く座標の上限と下限を決めます。ここではx軸について決めていきます。下限としてデータXの1列目の最小値を取り出します。最小値をそのまま使うと描く座標ギリギリになるので余裕をもって-1して、変数x1_minに入れておきます。上限としてデータXの1列目の最大値を取り出します。最大値をそのまま使うと描く座標ギリギリになってしまうので+1して、変数x1_maxに入れておきます。
  7. 同様にy軸について決めていきます。下限としてデータXの2列目の最小値を取り出します。最小値をそのまま使うと描く座標ギリギリになるので、余裕をもって-1して、変数x2_minに入れておきます。上限としてデータXの2列目の最大値を取り出します。最大値をそのまま使うと描く座標ギリギリになってしまうので、+1して変数x2_maxに入れておきます。
  8. ここはかなりややこしいので飛ばしてもらって、次の項目に行ってもらってもいいです。一応説明しておくと作ろうとしているグラフは分類の境界線を表示するプログラムです。31ページのグラフを見てもらうのが一番イメージがわきやすいと思います。どのように境界線を描いているかというと座標の上の適当な点を選びます。それが、1に分類されるか、-1に分類されるかを調べます。また、座標の上の適当な点を選んでどちらに分類されるかを調べます。これを何度も繰り返してグラフを色分けしているイメージです。ちなみに僕の理解が正しければこのプログラムでは70,000箇所の点を分類して色分けしています。
  9. 式の説明をするとx1_minとx1_maxの間をresolution=0.02毎に数値を取り出し、同様にx2_minとx2_maxの間をresolution=0.02毎に数値を取り出し、それぞれを組み合わせてmeshgridにかけます。それをそれぞれ、xx1とxx2に入れます。
  10. meshgridにかけたことで、xx1とxx2はいま70000か所以上の座標の位置を表す行列になっています。この70000か所以上もある点をひとつづつ色分けをしていくことで31ページのグラフを作るわけです。では、それを分類するために行数は何でもよい2列の行列の形にして24ページ~25ページで作ったperceptronの中のpredict関数を使って分類していきます。それを変数Zに入れていきます。
  11. さて、分類した70000か所以上もの点をもつZをxx1やxx2と同じ座標のような形式にするので、xx1と同じ行列の形にreshapeをかけます。
  12. xx1,xx2の座標に内容がZの行列が作成できたので、contourfを透過度0.4、cmapをcmapとしてグラフを塗り分けます。
  13. xx1の最小値、最大値をx軸の範囲として、xx2の最小値、最大値をy軸の範囲として設定。
  14. for文を使用して、enumerate関数を使ってyのユニークな値をclとして、idをidxとしてまわします。
  15. matplotlibのscatter関数を使用して散布図を描きます。x座標にはデータXのyの値がclの時の1列目、y座標にはデータXのyの値がclの時の2列目を、透過度0.8として色はcmap、markerにはうえで決めたマーカーを、ラベルにはclを使用してプロット。

以上で30ページのプログラムが完了です。こちらも31ページのプログラムと連動して動くので、このプログラム単独では動かないので「あれ?」とならないようにしてください。

最初は「あれ?」となって、なんだろなぁ。エラーか?とかで悩んでいました。