概要
昨今、ブームとなっているAI・機械学習の技術は、ハードルが高くて敬遠されている方も多いのではないでしょうか。
たしかに、実際にエンジニアとして開発や研究を行うためには、相応のスキルが必要です。
しかしながら、ソースコードを少し実行するくらいであれば、たった10行のコードで機械学習を体験することができます。
コード
先ずは、今回動かすコードを見てみましょう。このコードを1行ずつ紹介していきます。
1 | from sklearn.datasets import load_iris |
1行目
1 | from sklearn.datasets import load_iris |
scikit-learnはPythonの機械学習ライブラリです。
Deep Learningなどの最先端のアルゴリズムはほとんど実装されていませんですが、
クラシカルで実用的なアルゴリズムやそれらを扱うためのツールが数多く実装されています。
scikit-learnにはサンプルとして、いくつかのデータセットをダウンロードすることができます。その一つがフィッシャーのアヤメと呼ばれるデータで、1行目ではアヤメのデータをダウンロードするための関数load_iris
をインポートしています。
データの詳細はこちらを参照いただきたい
2行目
1 | from sklearn.model_selection import train_test_split |
データ(サンプルの集合)を学習用データとテストデータに分割する関数train_test_split
をインポートしています。データを分割する理由については、やや本題からずれますので記事の最後に補足します。
3行目
1 | from sklearn.neural_network import MLPClassifier |
クラスMLPClassifier
は多層パーセプトロン[1]を用いた分類[2]モデルのクラスです。
[1]多層パーセプトロン・・・ 多層パーセプトロンニューラルネットワーク(Deep Learning)の最もプレーンなネットワーク
[2]分類・・・機械学習のタスクには「回帰」や「分類」といったタスクがあります。分類タスクとは文字通りデータを分類するタスクのことで、例えば、画像に写っている動物が猫か犬かを判定する問題などが考えられます。
4行目
1 | iris = load_iris() |
先ほど説明したアヤメのデータを変数iris
に代入する。
5行目
1 | X = iris.data |
オブジェクトirisは属性data
を持っており、その中にはアヤメの「がくの長さ」「がくの幅」「花弁の長さ」「花弁の幅」が保持されています。こういった予測に用いるための情報を説明変数
や特徴量
と呼びます。 9行目から説明変数を使って、アヤメの分類を行うことになります。
1 | X.shape |
データの数(サンプル数)が150で説明変数の種類(次元)が4であることが確認できます。
さて、試しに1つ目のサンプルを確認してみましょう。
1 | 0] X[ |
小数で4つの説明変数が格納されていることが確認できます。
ちなみに説明変数の名前はは属性feature_names
で確認できます。
1 | iris.feature_names |
6行目
1 | y = iris.target |
オブジェクトirisは属性target
を持っており、その中には「アヤメの種類」が保持されています。こういった予測対象となる情報を目的変数
やラベル
と呼びます。説明変数を使って、目的変数を出来るだけ高い精度で予測することが機械学習の目的の一つです。
1 | y.shape |
yについてもデータの数(サンプル数)が150であり、Xの場合とサンプル数が一致していることが確認できます。
さて、試しに1つ目のサンプルを確認してみましょう。
1 | 0] y[ |
今回のtargetは0,1,2
のいずれかの数字が保持されています。これらの数字はそれぞれsetona, versicolor, virginica
という種類に対応しています。これは属性target_names
で確認できます。
1 | list(data.target_names) |
7行目
1 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0) |
train_test_split
を使ってデータを学習用データとテストデータに分割しています。それぞれに目的変数と説明変数があるため、返却されるオブジェクトは4つとなります。test_size
は分割の比率を決めるパラメータで、ここでは30%をテストデータに、残りの70%を学習用データとしています。データの形状を確認してみましょう。
1 | X_train.shape |
random_state
はデータを分割する際に利用する乱数を、プログラムの実行ごとに固定するための値です。
8行目
1 | clf = MLPClassifier() |
多層パーセプトロンを用いた分類モデルのクラスであるMLPClassifier
からインスタンスclf
を作成しています。
9行目
1 | clf.fit(X_train, y_train) |
clf
の学習を行います。引数として、学習用のデータの説明変数X_train
と目的変数y_train
を渡します。
10行目
1 | print (clf.score(X_test, y_test)) |
ここではメソッドscore
で、clf
にX_test
を入力し予測値を計算したのち、答えであるy_test
と比較を行い、平均正解率を求めています。もちろん正解率まで求めず、予測だけを行うこともできます。その際にはメソッドpredict
を使用します。
1 | clf.predict(X_test) |
(MLPClassifier
で用いる乱数の関係で、ここに記載した結果と異なる結果が出る可能性があります)
先ほど平均正解率を求めましたが、目視でも答えy_test
と比較してみましょう。
1 | y_test |
概ね一致しているのではないでしょうか。
まとめ
解説自体は少々長くなりましたが、コード自体はたった10行と非常に短く、機械学習のハードルは思ったより低く感じられた方もいらっしゃるのではないでしょうか。
より詳しくscikit-learnの勉強をしたい方は
csvデータの学習方法を知りたい方は
CSVファイルをpandasで読み込み、scikit-learnで学習させる
機械学習の入門〜NumPyによるロジスティック回帰の実装を勉強したい方は
データ分析と機械学習の関係については以下の記事でまとめています。
補足:train_test_split
でデータを分割する理由
以下の2行の値を比較してみて下さい。おそらく、1行目の方が値が高いのではないでしょうか。
1 | clf.score(X_train, y_train) |
これは、機械学習モデルに学習してほしいと期待しているアヤメのがく・花弁と種類の関係
だけではなく、本質的ではない丸暗記のようなものを学習してしまっているためです。これを過学習
と呼びます。私たちが機械学習に期待しているのは学習データの丸暗記ではなく、機械学習モデルにとって未知のデータ(ここではテストデータ)に対する高い正解率での予測です。そのため、機械学習モデルを評価する際は、学習用データに対する正解率
ではなくテストデータに対する正解率
を優先的に見るべきです。(ただし、前者も使い道はあります。)
人間の試験と一緒
人間が受ける入学試験や資格試験では、本番ではすでに公開されている問題(過去問や模試)と全く同じ問題は基本的には出ませんよね。なぜなら、同じ問題を出してしまうとなると暗記をしてしまえばよい、となるからです。逆にいえば、公開されている問題と同じ問題を出してしまうと、その試験では受験者を適切に評価することができなくなってしまいます。
記事情報
- 投稿日:2020年2月3日
- 最終更新日:2020年3月31日