はじめに
タイトル通りの機械学習に触れてみたという内容です。
先日、社内の勉強会で同タイトルで発表しました。
最近ブログを書いていなかったこともあり、それならブログネタにしようかと。
なお、数学や理論については書きません。
目次
環境
Google Colaboratoryを使用します。
https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja
Colaboratory(略称: Colab)は、ブラウザから Python を記述、実行できるサービスです。次の特長を備えています。
- 環境構築が不要
- GPU への無料アクセス
- 簡単に共有
機械学習のさわりを知る
何の役に立つの??
身近なものでは、迷惑メールの分類、翻訳、手書き文字の判別に使われています。
サービスのアカウント登録時に表示される「私はロボットではありません」も機械学習のようです。
機械学習とはなんぞや?
通常のシステムでは、Iuputを受けてどうOutputするか全てのパターンが考えられたプログラムが処理します。
機械学習では、欲しいOutputに沿うinputを用意し、いい感じになるよう機械学習が処理します。
機械学習の種類
- 教師あり学習
- 教師からの例題として事前にデータと正解を与え、それを元に学習します。
- 例えば、長文の解析(どの単語がどのくらいの頻度で含まれているか)をするには、どんな特徴を持っているかを表すベクトル(教師)が必要で、文字の種類はアルファベット、単語はこれですといった情報を事前に与えます。
- 教師なし学習
- 出力すべきものが予め決まっていません。
- データの背後に存在する本質的な構造を抽出するために用いられますが、どのように使えばいいのかよくわかりませんでした。
- 強化学習
- エージェント(行動の主体)と環境(状況や状態)が登場します。
- エージェントが現在の環境を観測し、それにもとづいて意思決定を行い、行動します。行動すると、エージェントの環境が変化し、エージェントは何らかの報酬(行動の結果)が得られます。この報酬が高くなるよう、より良い行動を学習します。
- 深層学習
- 調べていません。
- 教師あり学習と強化学習の違い
教師あり学習を20行で試す
よく題材に上がっているようなので、XORで教師あり学習を試します。
パターンは4パターンのみのため、学習結果が分かりやすいです。
XORの演算結果を学習し、結果を予測する
どのような処理をしているか、print文を入れて変数の中身を表示しています。
### 目的:XORの演算結果を学習し、結果を予測します import pandas as pd # データ解析を支援する機能を提供するライブラリ。データ構造と演算を提供する from sklearn import svm # scikit-learn(サイキット・ラーン) 機械学習のフレームワーク。サンプルデータも含む # XORの教師、演算結果 pre_xor_input = [ [0, 0, 0], #データA、データB、結果の順に格納 [0, 1, 1], [1, 0, 1], [1, 1, 0] ] # 入力を学習データとラベルに分ける pre_xor_df = pd.DataFrame(pre_xor_input) pre_xor_data = pre_xor_df.loc[:,0:1] # データ pre_xor_label = pre_xor_df.loc[:,2] # ラベル(=回答) # 変数の中身を表示 print("教師データpre_xor_inputを:\n", pre_xor_input) print("pre_xor_dfに整形して:") print(pre_xor_df) print("データpre_xor_dataと:") print(pre_xor_data) print("ラベルpre_xor_labelに分ける:") print(pre_xor_label) # データの学習 clf = svm.SVC() # SVM(Support Vector Machine)、機械学習モデルの一種 clf.fit(pre_xor_data, pre_xor_label) # fitの第1引数にデータ、第2引数にラベルを指定 # 予測したいデータの入力 xor_input = [ [1,1], [0,1] ] xor_df = pd.DataFrame(xor_input) xor_data = xor_df.loc[:,0:1] # データの予測 res = clf.predict(xor_data) # 予測の結果 print("\n以下の入力データのXOR結果を:") print(xor_data) print("回答する:\n", res)
コード通りに動かした結果が以下です。
教師データpre_xor_inputを: [[0, 0, 0], [0, 1, 1], [1, 0, 1], [1, 1, 0]] pre_xor_dfに整形して: 0 1 2 0 0 0 0 1 0 1 1 2 1 0 1 3 1 1 0 データpre_xor_dataと: 0 1 0 0 0 1 0 1 2 1 0 3 1 1 ラベルpre_xor_labelに分ける: 0 0 1 1 2 1 3 0 Name: 2, dtype: int64 以下の入力データのXOR結果を: 0 1 0 1 1 1 0 1 回答する: [0 1]
整形の処理もわかり、結果は想定通りでした。
学習するデータをいじってみる
- [2,2]の結果を予測してみます。
以下の入力データのXOR結果を: 0 1 0 2 2 回答する: [0]
同じ値だから、0を返したのでしょうか。
- 次は、[3,3]の結果を予測します。
以下の入力データのXOR結果を: 0 1 0 3 3 回答する: [0]
[2,2]と同じで、0を返しています。
- 少しひねって[100,100]の結果を予測します。
以下の入力データのXOR結果を: 0 1 0 100 100 回答する: [1]
1が返ってきた。決定した理由が分からない。
- 逆に教師の[1, 1, 0]を削除し、[0,0][0,1][1,0][1,1]の結果を予測してみます。
教師データpre_xor_inputを: [[0, 0, 0], [0, 1, 1], [1, 0, 1]] pre_xor_dfに整形して: 0 1 2 0 0 0 0 1 0 1 1 2 1 0 1 データpre_xor_dataと: 0 1 0 0 0 1 0 1 2 1 0 ラベルpre_xor_labelに分ける: 0 0 1 1 2 1 Name: 2, dtype: int64 以下の入力データのXOR結果を: 0 1 0 0 0 1 0 1 2 1 0 3 1 1 回答する: [0 1 1 1]
[1,1]の結果が1に変わりましたね。どこかで見たのですが、教師データ[1, 1, 0]がないため、残りの教師データで1が含まれると、1を返す学習をしているそうです。
感想
わからん。機械学習難しすぎ。
ひとまず使うだけでも大変だということがわかりました。