Iris Classification


Sikickrunが提供するペンデータを利用して品種を分類する
分類(Classification):独立変数値が与えられたときにその値と最も相関がある依存変数値
よそくもんだい
データ型:150 x 4 numpy.ndarray
862 feature:ガク長、ガク幅、花弁長、花弁幅
↳正解ラベル:3種類(Setosa、Versicolor、Virginica)
↳ data.targetはsetosa:0、versicolor:1、virginica:3にマッピングされます.
ターゲット:150個のペンデータの70%をtrain set、30%をtest setに分割し、モデルの精度出力を生成します.
データの前処理と可視化のためのパッケージとirisデータのインポート
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_iris 
irisデータのデフォルト形状を決定する
#dataset load
data = load_iris()

#separating dataset 
features = data.data    # (150, 4)의 예측변수값 
feature_names = data.feature_names #피쳐 이름 
target = data.target #정답 컬럼값 
target_names = data.target_names #정답 컬럼 이름

print(features.shape, target.shape)

(150, 4) (150,)
フィーチャーの名前とターゲットの名前を確認
feature_names

['sepal length (cm)',
 'sepal width (cm)',
 'petal length (cm)',
 'petal width (cm)']
 
target_names

array(['setosa', 'versicolor', 'virginica'], dtype='<U10')
データフレームを変換すると前処理が容易になります
all_data = pd.DataFrame(features, columns=feature_names)
all_data['target'] = target
all_data.info()

class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 5 columns):
 #   Column             Non-Null Count  Dtype  
---  ------             --------------  -----  
 0   sepal length (cm)  150 non-null    float64
 1   sepal width (cm)   150 non-null    float64
 2   petal length (cm)  150 non-null    float64
 3   petal width (cm)   150 non-null    float64
 4   target             150 non-null    int64  
dtypes: float64(4), int64(1)
memory usage: 6.0 KB
データ自体は測定値がなく、数が少ないため、可視化が可能であり、データ間の関係を容易に特定できる
sns.pairplot(all_data, hue='target', size=3)

corr()関数を用いてデータ間の相関係数を数値的に表現する
corr = all_data
corr = corr.corr(method='pearson')
corr['target'].drop(['target'])

sepal length (cm)    0.782561
sepal width (cm)    -0.426658
petal length (cm)    0.949035
petal width (cm)     0.956547
Name: target, dtype: float64

絶対値が0.3以上で、全て使用
sns.heatmap(corr, annot=True, cmap='RdYlBu_r', vmin=-1, vmax=1)

ホットグラフ出力
plt.figure(figsize = (12,6))
sns.boxplot(x='petal length (cm)', y='target', data=all_data, orient='h')
plt.figure(figsize = (12,6))
sns.boxplot(x='petal width (cm)', y='target', data=all_data, orient='h')

相関係数の高い花びらの長さと花びらの幅をboxplotに出力
出力異常値を確認できます
異常値を解決するためには、どのようなスケーラを使用するかを考慮する必要があります.
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(all_data.iloc[:,:-1], all_data.iloc[:,-1:], test_size=0.3)

print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)
現在、学習のためにデータを学習データとテストデータに分けています
関数はcykickrunが提供するtrain test splitを使用し、7:3の割合で配布されます.
from sklearn.pipeline import make_pipeline # 한 번에 처리하는 파이프라인 생성
from sklearn.linear_model import LogisticRegression # 로지스틱 회귀
from sklearn.svm import SVC # 서포트벡터머신
from sklearn.ensemble import RandomForestClassifier # 랜덤포레스트
from sklearn.neighbors import KNeighborsClassifier # k-최근접이웃
from sklearn.metrics import accuracy_score # 정확도 측정
import warnings
warnings.filterwarnings(action='ignore') # 경고창 무시
次に学習用モジュールをインポート
lr = LogisticRegression()
svc = SVC(C=1.0, kernel='linear')
rfc = RandomForestClassifier(n_estimators=100)
knn = KNeighborsClassifier(n_neighbors = 3)
モデルを生成
scv:Cはエラー許容度が小さいほど許可されるエラーが多いので、C値を複数回入力して確認する必要があります.フィットしすぎると、小さい値を指定して制限することができます.kernelは線形を指定することによって決定境界を決定する
rfc:ランダムツリーは複数の決定ツリーからなり,n推定量は分類器の個数を決定する
knn:k‐最近接は,特異点の係数に基づいて周囲ターゲットを決定し分類するモデルである.ここでは3を指定し,点に最も近い3つのターゲットを探し出して分類する.
models = [lr, svc, rfc, knn]

for model in models:
  model.fit(x_train, y_train)
  y_pred = model.predict(x_test)

  accuracy = accuracy_score(y_test, y_pred)
  print(f"modle : {model}\n accuracy : {accuracy}\n")
次にfor文を使用してモデル名とパフォーマンスを出力します
modle : LogisticRegression()
 accuracy : 0.9777777777777777

modle : SVC(kernel='linear')
 accuracy : 1.0

modle : RandomForestClassifier()
 accuracy : 0.9555555555555556

modle : KNeighborsClassifier(n_neighbors=3)
 accuracy : 0.9555555555555556
svcモデルは最良の性能を示した
ScalerとPCA
Sikickrunは、複数のデータの前処理に必要な拡張機能を提供します.

  • StandardScaler:平均値を標準化、消去し、データを分散単位に調整

  • MinMaxScale:標準化、すべてのフィーチャー値が0~1になるようにデータを再調整

  • RosbustScaler:異常影響を最小化し、中間値とIQR(25~75%の範囲のデータ)を使用します.
  • ここで注意すべき点は,学習データにのみfit()を適用することである.
    テストデータで再フィットすると、基準が再び変更されるため、正確な学習ができません.
    次元呪い:数学空間次元の増加に伴い、問題の計算方法は指数的に増加する問題である.
    データ階層は高いが、数が少なく、適切なモデルが大きすぎる.
    順調に勉強するためには、階層を縮小したり、データを多く収集したりする必要があります.
    PCA:次元縮小によるフィーチャー抽出
    データ分散を最大限に保持しながら,相互に直交する主成分を探り,高次元空間の試料を低次元空間に変換する方法を用いて,特異値分解(SVD)を用いた.
    irisデータによるpcaの応用
    このときn componentsは、維持する主成分の数または割合で、2つの主成分を残すことを指定します.
    from sklearn.preprocessing import StandardScaler
    from sklearn.decomposition import PCA
    
    x = StandardScaler().fit_transform(data.data)
    y = data.target
    
    pca = PCA(n_components=2)
    pca_x = pca.fit_transform(x)
    df = pd.DataFrame(pca_x, columns=['f1', 'f2'])
    df
    
    	f1	f2
    0	-2.264703	0.480027
    1	-2.080961	-0.674134
    2	-2.364229	-0.341908
    3	-2.299384	-0.597395
    4	-2.389842	0.646835
    ...	...	...
    145	1.870503	0.386966
    146	1.564580	-0.896687
    147	1.521170	0.269069
    148	1.372788	1.011254
    149	0.960656	-0.024332
    150 rows × 2 columns
    plt.plot(pca_x[:,0][y==0], pca_x[:,1][y==0], "ro", markersize=3, label='setosa')
    plt.plot(pca_x[:,0][y==1], pca_x[:,1][y==1], "g^", markersize=3, label='versicolor')
    plt.plot(pca_x[:,0][y==2], pca_x[:,1][y==2], "bs", markersize=3, label='virginica')
    
    plt.xlabel('feature 1')
    plt.ylabel('feature 2')
    plt.legend()
    plt.show()

    可視化結果の確認
    lr = make_pipeline(StandardScaler(), PCA(), LogisticRegression())
    svc = make_pipeline(StandardScaler(), PCA(), SVC(C=1.0, kernel='linear'))
    rfc = make_pipeline(StandardScaler(), PCA(), RandomForestClassifier(n_estimators=10))
    パイプラインを使用して標準カレンダーとPCA技術を適用して学習する
    models = [lr, svc, rfc]
    
    for model in models:
      model.fit(x_train, y_train)
      y_pred = model.predict(x_test)
    
      accuracy = accuracy_score(y_test, y_pred)
      print(f"modle : {model}\n accuracy : {accuracy}\n")
    modle : Pipeline(steps=[('standardscaler', StandardScaler()), ('pca', PCA()),
                    ('logisticregression', LogisticRegression())])
     accuracy : 0.9555555555555556
    
    modle : Pipeline(steps=[('standardscaler', StandardScaler()), ('pca', PCA()),
                    ('svc', SVC(kernel='linear'))])
     accuracy : 0.9777777777777777
    
    modle : Pipeline(steps=[('standardscaler', StandardScaler()), ('pca', PCA()),
                    ('randomforestclassifier',
                     RandomForestClassifier(n_estimators=10))])
     accuracy : 0.9555555555555556
    かえって学習率が下がった
    したがって,状況に応じて適切なスケールと特徴抽出を行ってこそ,性能の良いモデルを生成することができる.