■Logistic回帰でアヤメデータの分類やっていきます。
######1.モジュールインポート
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
#####2.データセット読み込み
今回はversicolorとvirginicaを使用
データの確認
df = sns.load_dataset('iris')
df = df[(df['species']=='versicolor') |(df['species']=='virginica')]
#####3.データを可視化してみる
sns.pairplot(df, hue='species')
plt.show()
#####4.標準化 & モデル作成 & 未知データへの予測
$wに回帰係数、bに切片$
$z = w_1x_1 + w_2x_2 + w_3x_3 + w_4x_4 + b$
下記シグモイド関数により予測される。
$sigmoid(z)=\frac{1}{1 + exp(-z)}$
下記コスト関数が最小になるように回帰係数を求める。
$Loss =\frac{1}{n} \sum_{k=1}^{a}y(log(sigmoid(z)+(1-y)log(1-sigmoid(z))$
特徴量を標準化することで平均0、分散1にスケールを整える→値の大きい特徴量に引っ張られて値の小さな特徴量の寄与率低下を防ぐ。
#versicolorを0, virginicaを1に変更
df['species'] = df['species'].apply(lambda x: 0 if x == 'versicolor' else 1)
y = df['species']
#特徴量を標準化
X = df[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']]
std = StandardScaler()
df_std = std.fit_transform(X)
#データスプリット
X_train, X_test, y_train, y_test = train_test_split(df_std, y, test_size=0.2, random_state=0)
#インスタンス化
lr = LogisticRegression()
#学習
lr.fit(X_train, y_train)
print('切片:',lr.intercept_)
print('係数:',lr.coef_)
切片: [0.31092366]
回帰係数: [[-0.22945621 -0.64463112 2.25437115 2.10390759]]
#1に近づくほど0(versicolor)である確率が高い
y_proba = lr.predict_proba(X_test)[: , 0]
y_proba
array([0.80232846, 0.0083395 , 0.77687909, 0.00173345, 0.04900388,
0.0048721 , 0.84531764, 0.22558666, 0.00642644, 0.02140575,
0.05924045, 0.07914323, 0.01190993, 0.83569148, 0.99769158,
0.98796255, 0.46769446, 0.96532535, 0.29089213, 0.92908486])
######5. 結果評価
#testデータに対して予測してみる
y_test_pred = lr.predict(X_test)
#正解率を確認
accuracy_score(y_test, y_test_pred)
0.9
np.array(y_test)
array([0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0])
y_test_pred
array([0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0])
Accuracyだけでなく混同行列で真陽性、偽陽性、真陰性、真陽性の確認を行う。
混同行列を作成
陰を0、陽を1と考える
classes = [0, 1]
cm = confusion_matrix(y_test, y_test_pred, labels=classes)
# データフレーム化
cmdf = pd.DataFrame(cm, index=classes, columns=classes)
# 混同行列をプロット
sns.heatmap(cmdf, annot=True)
# 適合率、再現率、F値を出力
print(classification_report(y_test, y_test_pred))
以上より、あやめデータ(versicolor,versinica)の2値分類を行うことができました。