あやめの分類
機械学習の有名な練習問題である、あやめの分類について実施してみます。 これは、花弁や萼片のサイズに関するデータセットをもとに機械学習のモデルを作成し、あやめ(iris)の種類を判定するものです。 機械学習の練習問題として有名なあやめのデータセットはFisher1が1936年に報告した論文に載っているデータを用いたもので、 三種類のあやめ(Iris-versicolor、Iris-setosa、Iris-virginica)の花それぞれ50個体ずつの花弁の長さと幅(PetalLengthCm, PetalWidthCm)、萼片の長さと幅(SepalLengthCm, SepalWidthCm)についてまとめたものとなっています。 今回用いるデータセットは、機械学習の分野で有名なコミュニティであるkagglのIris Speciesからダウンロードしております。
データセットの取得
(1)kagglのIris Speciesのページにアクセス
(2)kagglのアカウント作成してログイン
(3)"Download"でデータセットを取得
archive.zipというフォルダがダウンロードできたかと思います。これを解凍すると、database.sqlite、Iris.csvというファイルが入っています。sqliteというのもデータベースのようですが、今回使うのはIris.csvです。
機械学習
それでは機械学習を行います。実行はGoogle Colaboratoryにて実施します。
(1)モジュールのインポート
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
import seaborn as sns
(2)データのインポート
iris_df = pd.read_csv("/{Iris.csvのディレクトリ}/Iris.csv")
iris_df.head()
iris_df.head()で最初の4行のデータの可視化をおこなっています。
(3)データの可視化/解析
(3-1)欠損値の確認
iris_df.isnull().sum()
機械学習のアルゴリズムによっては、データセットの中にNanが含まれていると解析が行えないことがあります。ここでは、最初に欠損値の確認をおこなっています。結果、今回のデータセットには欠損値が含まれていないことがわかります。
(3-2)ヒストグラム
f,ax=plt.subplots(2,2,figsize=(18,8))
sns.countplot(x="SepalLengthCm",hue='Species',data=iris_df,ax=ax[0][0])
ax[0][0].set_title('SepalLengthCm vs Species')
sns.countplot(x="SepalWidthCm",hue='Species',data=iris_df,ax=ax[1][0])
ax[1][0].set_title('SepalWidthCm vs Species')
sns.countplot(x="PetalLengthCm",hue='Species',data=iris_df,ax=ax[0][1])
ax[0][1].set_title('PetalLengthCm vs Species')
sns.countplot(x='PetalWidthCm',hue='Species',data=iris_df,ax=ax[1][1])
ax[1][1].set_title('PetalWidthCm vs Species')
plt.show()
各あやめの種類に対してそれぞれの部位の大きさの分布がどのようになっているか確認するためヒストグラムを出図しました。このヒストグラムから、全体的にIris-virginicaが大きくてIris-versicolorが中間、Iris-setosaが小さい傾向にあることが見て取れます。さらに、あやめの種類に対して、萼片(Sepal)は明瞭にサイズが分かれておらず、花弁(Petal)は比較的はっきりとサイズが分かれていそうです。次は、これを定量的に比較するために相関関係係数のヒートマップを図示してみます。
(3-3)相関関係係数のヒートマップ
iris_df2 = iris_df
iris_df2['Speacies_label_encoded'] = iris_df2['Species'].astype('category').cat.codes
sns.heatmap(iris_df2.corr(),annot=True,cmap='bwr',linewidths=0.2)
fig=plt.gcf()
fig.set_size_inches(10,8)
plt.show()
相関関係係数とは二つのデータの相関関係の強さを表す数値です。範囲は-1から1で、絶対値が大きいほど強い相関を示し、値が正であれば正の相関、値が負であれば負の相関関係にあることを示します。相関関係係数は数値のデータ同士に対して計算することができますがSpeaciesのように、各値が文字列の場合は計算することができません。Speaciesは三種類のあやめの種類に振り分けられており、このようなデータをカテゴリカルデータと呼びます。カテゴリカルデータについて解析を行いたいときによく用いられる手法として、エンコーディングがあります。これは、三種類のあやめの種類に対して0、1、2の整数値を割り振る手法です。今回Speaciesに対してエンコーディングを行い、Speacies_label_encodedという列を作成しています。Speacies_label_encodedに対してそれぞれの相関関係係数を確認すると、SepalLengthCmが0.78、SepalWidthCmが-0.42、PetalLengthCmが0.95、PetalWidthCmが0.96と花弁(Petal)が萼片(Sepal)に比べて強い相関関係を示していることがわかります。
(4)データの前処理
(4-1)特徴量とラベルの分割
X = iris_df.drop(["Id","Species"], axis=1)
y = iris_df['Species']
(4-2)データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
(4-3)データの分割
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)
データを訓練用のデータとテスト用のデータに分割します。
(5)学習
svm_model = SVC(kernel='linear', random_state=42)
svm_model.fit(X_train, y_train)
y_pred = svm_model.predict(X_test)
ここではサポートベクターマシン(SVC)というアルゴリズムを用いて学習を行います。
(6)評価
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)
今回のモデルの正解率は97.8 %でした。かなり良いです。
-
Fisher, R. A. (1936) The use of multiple measurements in taxonomic problems. Annals of Eugenics, 7(2), 179–188. ↩