[Python3] scikit-learnによる機械学習1: 足し算を学習させる

前提

以下の環境で実装、動作確認済み

要素 バージョン
debian 8.6
python 3.6.2

scikit-learnによる機械学習シリーズ

機械学習も数学もPythonもよくわからなくても機械学習はデキるシリーズ

機械学習とは

機械学習(きかいがくしゅう、英: machine learning)とは、人工知能における研究課題の一つで、人間が自然に行っている学習能力と同様の機能をコンピュータで実現しようとする技術・手法のことである。(wikipedia引用)

機械学習とは、言語やゲームなどをはじめとした人間の様々な知的活動の中で、人間が自然と行っているパターン認識や経験則を導き出したりするような活動を、コンピュータを使って実現するための技術や理論、またはソフトウェアなどの総称である。(IT用語時点引用)

まぁ人間っぽい学習をコンピュータにもやらせましょうというお話。
本シリーズでは機械学習の定義とかにあまり拘らずに、一般的に考えられる機械学習を自分でもやってみようという緩い方向で進める。

scikit-learnとは

Pythonにおける事実上標準と言っても過言ではない、機械学習のためのライブラリ。
機械学習と言えばTensorFlowというワードの知名度が高いが、TensorFlowは学習コストも高く、ディープラーニングまで幅広くできるので、本シリーズではお手軽に機械学習ができるsckit-learnを用いる

scikit-learnのインストール

sckit-learnはPythonモジュールとして公開されているので、pipなどを用いてインストールする。pipはPythonをインストールすると標準で入ってる可能性が高い。入っていない場合は別途導入する。あるいはAnacondaなどの別な手段を適用する。

$ pip install scikit-learn

Pandas/Numpyについて

Pythonで機械学習を行う上で切っても切れないライブラリに、以下の2つがある

Pandas
データ解析を支援するためのライブラリ。汎用的なデータ構造の構築や、データ内の演算などをサポートする。

Numpy
科学計算用のライブラリ。特に行列に対する計算は普通にPythonで行うより圧倒的に早い。

以上より、これらのライブラリも初めに導入しておく。

$ pip install numpy pandas

足し算の機械学習について

本記事では、機械学習の第一歩として、sckit-learnの線形回帰アルゴリズムを用いて、足し算を学習させる。

流れとしては以下のようになる

  • 足し算の式と、その答えの組み合わせをいくつか用意する
  • sckit-learnに式と答えの組み合わせを学習させ、学習モデルを生成
  • 標準入力から二種類の整数を学習モデルに与え、予測結果を標準出力する

なお、2数の足し算とは当然演算によって求められるものなので、機械学習の利用法としては適していない。
が、ここでは雰囲気を掴むためにこのテーマにした。

教師あり学習について

教師あり学習は、データの組み合わせと、それに対する答えのセットを複数セット学習させることで、データの組み合わせを与えただけでその答えを予測してもらおうという学習モデル。

今回は足し算を学習させるので、データの組み合わせが式で、答えが和と考えれば良い。

線形回帰について

Wikipediaをそのまま掲載すると以下の通り。なるほど。

何を言ってるかよくわからないが、足し算に置き換えれば非常にシンプルになる。

目的変数Yは、足し算における和である。
説明変数X1,X2は、足し算のそれぞれの数値である。

この場合、線形回帰直線は、Y = X1 + X2の形になるので、
この式を予測することが線形回帰学習である(あってるか極めて怪しい)

実装

モジュールのimport

今回は、Pandasによる学習用データの入力と、scikit-learnの線形回帰モデルを用いるので、以下のimport文を記述する。Numpyは今回出番なし。

from pandas import DataFrame
from sklearn import linear_model

学習データの用意

学習データは、PandasのDataFrameの形式で用意する。DataFrameはデータの集合を二次元で表現する。
sckit-learnでは、学習データとその答えを別々に渡す必要があるので、それぞれformulas,answersに代入する。

formulas = DataFrame([
    [0, 0],
    [0, 1],
    [0, 2],
    [1, 0],
    [1, 1],
    [1, 2],
    [2, 0],
    [2, 1],
    [2, 2]
])
answers = DataFrame([0, 1, 2, 1, 2, 3, 2, 3, 4])

コードを見ての通り、それぞれ、0 + 0 = 0, 0 + 1 = 1, 0 + 2 = 2 … のセットを用意している。
ちなみにこの段階でformulasを標準出力すると以下のようになり、DataFrameがどのようにデータ集合を持っているかのイメージが湧く

   0  1
0  0  0
1  0  1
2  0  2
3  1  0
4  1  1
5  1  2
6  2  0
7  2  1
8  2  2

学習データを学習させる

importしたlinear_modelを用いて、先程用意した学習データを予測する。
LinearRegressionメソッドで学習モデルを取得できるので、それに対してfitメソッドで学習データを割り当て、学習を開始する。

model = linear_model.LinearRegression()
model.fit(formulas, answers)

学習結果を確認する

学習が完了したmodelに対して、predictメソッドを用いることで、新たなデータに対する答えの予測値を取得することができる。
この場合、必ず入力、出力ともに配列である必要があるので注意。

例えば以下では、10 + 20の予測結果を取得する。

predected_answer = model.predict([[10, 20]])

これを用いて、標準入力から得られた2数の和の予測結果を出力し、それを繰り返すコードを以下に示す

while True:

    print('> ', end='')
    x, y = list(map(lambda x: int(x), input().split(' ')))

    predected_answer = model.predict([[x, y]])
    print("{0} + {1} = {2}".format(x, y, int(predected_answer[0][0])))

標準入力と標準出力で小難しいことをやってるように見えるが、とりあえず入力した2数の和を予測して出力していることはわかる。

動作確認

これまでのコードを以下のように整理して実行する
コード全文 (Github)

 #
 # 2つの整数の足し算を機械学習し、任意の足し算を回答させる
 #
 from pandas import DataFrame
 from sklearn import linear_model

 # 足し算の例とその答えを用意する
 formulas = DataFrame([
     [0, 0],
     [0, 1],
     [0, 2],
     [1, 0],
     [1, 1],
     [1, 2],
     [2, 0],
     [2, 1],
     [2, 2]
 ])
 answers = DataFrame([0, 1, 2, 1, 2, 3, 2, 3, 4])

 # 式と答えを線形回帰学習させる
 model = linear_model.LinearRegression()
 model.fit(formulas, answers)
 print('学習完了')

 while True:

     # 標準入力から計算式を取得
     print('> ', end='')
     x, y = list(map(lambda x: int(x), input().split(' ')))

     # 学習モデルを用いて回答を取得し、標準出力
     predected_answer = model.predict([[x, y]])
     print("{0} + {1} = {2}".format(x, y, int(predected_answer[0][0])))

実行後、2秒程度で学習が完了する。コレに対して標準入力で適当に2数を入力すると、その予測結果が出力される。

$ python addition.py
学習完了
> 1 1
1 + 1 = 2
> 10 20
10 + 20 = 30
> 777 333
777 + 333 = 1110

良い感じに計算できているように見える。

本モデルの評価について次回行う。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です