Pythonの機械学習入門(1)~アヤメの品種をSVCで判定

Pythonの機械学習ライブラリ「scikit-learn」の使い方を簡単に説明します。今回はアヤメ(花)の品種を機械学習を使用して分類してみます。

アヤメデータの入手

先ずは、機械学習で使用するアヤメのデータを入手します。こちらのリンクよりデータをダウンロードできます。

「Raw」ボタンを押すと、データが画面に表示されるので、ブラウザがChromeなら、右クリックの「名前を付けて保存」でCSVファイルを保存できます。

それ以外のブラウザの場合は、データを全選択してExcelに貼り付けましょう。ファイル名は「iris.csv」とします。

データのレコード数は150、カラム数は5です。

iris_data_csv

データには下記のような項目が存在します。今回分類するのは5番目の「Name」です。

列番号 項目名 意味
1 SepalLength がく片の長さ
2 SepalWidth がく片の幅
3 PetalLength 花びらの長さ
4 PetalWidth 花びらの幅
5 Name アヤメの品種(Iris-Setosa、Iris-Versicolor、Iris-Virginica)

データの読込み

# アヤメデータの読込み
iris_data = pd.read_csv("iris.csv")

行列データを扱うpandasライブラリを使用します。read_csvメソッドで先ほど入手したデータ(iris.csv)を読込みます。

Pythonのソースコードとデータファイルは同じフォルダ内に保存しておきます。

特徴量データと教師データに分離

# 特徴量データと教師データに分離
X = iris_data.loc[:, ["SepalLength", "SepalWidth", "PetalLength", "PetalWidth"]].values
y = iris_data.loc[:, "Name"].values

データを特徴量データ教師データに分離します。Xは特徴量データで、150×4の行列データです。

これは、4つの特徴量(SepalLength, SepalWidth, PetalLength, PetalWidth)から成るレコードが150個あることを意味します。yは教師データで、150×1の行列データです。

これは、品種(Name)のレコードが150個あることを意味します。教師データの品種の値(Iris-Setosa、Iris-Versicolor、Iris-Virginica)を「ラベル」と呼びます。

以降で、アヤメの4つの特徴量に応じて品種を分類することになります。

※locは行列データの行と列を指定して、データを抽出するメソッド

※valuesはpandasからnumpyにデータを変換するメソッド

学習データとテストデータに分割

# 学習データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)

機械学習の性能を検証するために、学習に使用するデータセット(X_train、y_train)と、テストに使用するデータセット(X_test、y_test)に分割しておきます。

今回は学習データ:テストデータ=8:2にしました。比率はパラメータのtest_sizeで自由に設定できます。テストデータは慣習的におよそ20~25%くらいに設定します。

モデルの学習

# モデルの学習
estimator = SVC()
estimator.fit(X_train, y_train)

今回はアヤメの品種を分類するために、サポートベクタマシーン分類(SVC)の学習アルゴリズムを使用しました。

機械学習の分類のアルゴリズムはいくつかあり、データ数やデータの特性に応じて最適なものを選択する必要があります。

先ずは、SVCメソッドでアルゴリズムをestimatorに設定します。次にfitメソッドにて学習データセットを与えて学習させます。

これで、学習済みの「モデル」(または「学習器」)が完成しました。以降は、このモデルを用いて性能を評価したり、未知のデータに対する分類を行います。

モデルの性能評価

# モデルの評価
y_pred = estimator.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print ("正解率 = ", accuracy)

ここで、学習済みのモデルの性能を評価します。新しいデータセットに対して、アヤメの品種をどれだけ正しく分類できるかを確認します。

predictメソッドにて特徴量のテストデータを与えて、予測した品種データをy_predに保存します。

そして、accuracy_scoreメソッドでy_predと実際の品種データy_testの正解率を算出します。値は0~1で、1は100%合致していたことを意味します。

ソースコードを実行する度に、accuracyの値が変化します。これは、学習データとテストデータに分割したtrain_test_splitメソッドがランダムにデータを分割するからです。

概ね0.9~1の値になると思います。かなり高い正解率を出すことに成功しています。

accuracy_score

未知のデータの分類

# 未知データの分類
data = [[4.2, 3.1, 1.6, 0.5]]
X_pred = np.array(data)
y_pred = estimator.predict(X_pred)
print(y_pred)

上手く学習できたモデルを使って、実際に未知のデータを分類してみましょう。実際のレコードに近い4つの特徴量の値を入力したレコードを1つ作成します。

scikit-learn上で扱えるデータフォーマットに変換するためにnumpyを適用します。そして、predictメソッドにてアヤメの品種の分類を実行しました。

実行結果を表示させると、品種ラベルを取得することができました。実際のレコードと同じ品種ラベルが得られたと思います。

predict_unkown

まとめ

今回はPythonの機械学習ライブラリ「scikit-learn」を使用して、アヤメの品種を分類するモデルを作成しました。押さえておきたいポイントとしては、

  • データを「特徴量データ」と「教師データ」に分離した
  • モデルの性能を評価するために、「学習データ」と「テストデータ」に分割した
  • 学習済みのモデルを使って、「未知のデータ」に対して分類を実行した

参考文献

すぐに使える! 業務で実践できる! Pythonによる AI・機械学習・深層学習アプリのつくり方
ソシム (2018/6/29)