はじめに
機械学習の実装はやったことがないので触ってみることにした。
かなりのボリュームがありそうなので、何回かに分けて学んだことをかみ砕いてアプトプットしていきたいと思う。
もし自分と同じように興味はあるけど、まだ詳しくは知らないっていう方は参考にして頂ければと思います。
はじめて機械学習をやってみたので解説する【一日目】はこちら
使っている教材
「pythonではじめる機械学習」という本で勉強した。
本記事は2章の2.3.2最近傍法までで学んだことをアウトプットしている。
※記載されていることをそのまま記載はしていません。かみ砕いています。
環境
pythonなので、
以下のコマンドで構築できる。
pip install jupyter notebook
pip install scikit-learn numpy scipy matplotlib ipython pandas pillow mglearn
教師あり・教師なしってなに
教師あり・なしの違いはなにかというと、学習させるデータに答えがあるかないかの違いだ。
使いどころがそれぞれ異なる。
特徴から決まった結果を特定したい → 教師あり学習
特徴から何らかの法則性を見出したい → 教師なし学習
例えばリンゴとみかんが3個ずつあったとして、教師あり・なしで表現するとこうなる。
教師ありの場合
・「赤色がリンゴ」「黄色がみかん」とデータを登録する。
・赤色はなんですか?と聞かれたらリンゴだと思う、と予想結果を答える。
教師なしの場合
・「赤色」と「黄色」をデータを登録する。
・データを分析し、赤と黄で色が違うことを発見。赤はグループ1、黄はグループ2と分類できると予想する。
機械学習のアルゴリズム
機械学習では達成したい目的が様々あり、頭の良い人たちがアルゴリズムを使うと達成できるように用意してくれている。
アルゴリズムは用途とルールがそれぞれ異なるため、事前にルールを知っておかなければならない。
覚えるのは大変だけど、使うことが出来ればものすごい威力を発揮するので頑張りたいところ。
覚える取っ掛かりとしては最も単純なアルゴリズムといわれている最近傍法を使って解説していく。
最近傍法
最近傍法とはアルゴリズムの一つ。
学習データ内に最も近似した値と紐づける。
例えば、身長と年代を使って学習モデルを作ってみる。
学習データとして以下があるとする。
| 身長 | 答え |
|---|---|
| 80 | 赤ちゃん |
| 130 | 小学生 |
| 180 | 大人 |
この時、60に最も近似した点(以降、近傍点と呼ぶ)は80なので、60も赤ちゃんであろうという予想結果になる。
120の場合は近傍点は130なので、120も小学生であろうという予想結果になる。
また近傍点は1つである必要はなく、2つ3つと複数持たせることも可能。
どういった場合に1つを使ってどういった場合に2つを使えばよいかというとケースバイケースで、
機械学習がうまくできているかどうかテストをして精度を確かめるのだが、その結果から近傍点の数を選択する。
上記をプログラムで書くとこうなる。
分かりやすいようにシンプルに書いてみた。
import numpy
from sklearn.neighbors import KNeighborsClassifier
sincho = numpy.array([[80], [120], [180]]) #学習用の身長のデータ
nendai = numpy.array([[0], [1], [2]]) #0:赤ちゃん 1:小学生 2:大人
sokutei = numpy.array([[60]]) #作成したモデルに対して与えるサンプルデータ
# モデルの作成 n_neighborsが近傍点の数になる。ここがアルゴリズム、メソッドを呼ぶだけ。
clf = KNeighborsClassifier(n_neighbors=1)
# 学習データをセット
clf.fit(sincho, nendai)
# サンプルデータを与え、学習データから予想をだす
print(clf.predict(sokutei))
# 以下は結果
[0] #0は赤ちゃんを表す
機械学習はむずかしそうなイメージがあるが、シンプルなものだと簡単だと思う。
ただ書くまでにアルゴリズムなどの知識を入れないと理解ができないので、少しずつ勉強していく必要があると思う。
分類と回帰
実は今まで記載していたのは分類といわれる機械学習だった。
理解しやすいから例に挙げていたが、もう一つの回帰といわれる機械学習もあるので紹介する。
どちらも特徴から結果を予測するものだが、出力に違いがある。
分類 → 特徴から分類を予測する(A or B or C or・・・)
回帰 → 特徴から数値を予測する(答えは一つ)
これだけの違いだ。
同じように例をあげる。
年齢から50mの足の速さの予想をたてたい。
学習させるデータはこちら。
| 年齢 | 50mのタイム |
|---|---|
| 10 | 11.9 |
| 11 | 10.3 |
| 12 | 8.9 |
| 13 | 9.1 |
| 14 | 9.8 |
| 15 | 8.5 |
| 16 | 8.2 |
| 17 | 7.0 |
本来なら近傍点が1つということは意味がないのでありえないが、
近傍点が1つの場合、与える情報が11歳ならタイムは10.3秒と予想される。
同じく、13歳なら9.1秒と予想される。
近傍点が複数ある場合は、少し考慮された値が出力される。
13歳なら13に近い三つの点は12、13、14なので、三つの値の平均の9.3が予想される。
上記をプログラムで書くとこうなる。
こちらも分かりやすいようにシンプルに書いた。
import numpy
from sklearn.neighbors import KNeighborsRegressor
age = numpy.array([[10], [11], [12], [13], [14], [15], [16], [17]]) # 年齢
run_time = numpy.array([[11.9], [10.3], [8.9], [9.1], [9.8], [8.5], [8.2], [7.0]]) #50m走のタイム
sample_age = numpy.array([[13]]) #13歳の予測データ
# モデルの作成 近傍点は3つを設定。ここがアルゴリズム、メソッドを呼ぶだけ。
clf = KNeighborsRegressor(n_neighbors=3)
# 学習データをセット
clf.fit(age, run_time)
# サンプルデータを与え、学習データから予想をだす
print(clf.predict(sample_age))
# 以下は結果
[[9.26666667]] #12歳、13歳、14歳の平均の値が出力された
なんとなくわかるだろうか。
分類と回帰でプログラムの書き方はほぼ一緒だった。
プログラミングよりも目的を達成するにはどういったモデルを使えばよいか(アルゴリズム、教師あり・なし、分類・回帰など)を考えるかが重要になりそうだということを感じてもらえたらと思う。
まとめ
最近傍法は理解のしやすさから説明によく使われるようだが、パフォーマンスが悪いため実際にはあまり使わないらしい。
とはいえ機械学習の登竜門的なアルゴリズムっぽいので、ここをしっかり理解して次につなげていけたらと思う。