今回はコード説明の後編です!解析結果はどうなったか!?
最後までどうぞお付き合いください^^
コード内容
前回の最後のデータの状態を表示します。目的変数である'state'はbool型に、説明変数である'goal'~'usdpledged'はfloat型になっています。
'main_category'と'currency'はobject型のままです。

前回インポートしたライブラリを再掲します。
import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline #matplotlibのグラフを表示する import seaborn as sns #matplotlibより美しいグラフの描画 from sklearn.preprocessing import StandardScaler #preprocessing:前処理 StandardScaler:標準化 from sklearn.model_selection import train_test_split #データを訓練データとテストデータに分割する from sklearn.linear_model import SGDClassifier #クラス分類をする from sklearn.metrics import log_loss, accuracy_score, precision_recall_fscore_support, confusion_matrix #log_loss:対数尤度 ,accuracy_score:正答率 ,precision_recall_fscore_support:適合率,再現率,F1値 ,confusion_matrix:クロス集計表 from sklearn.metrics import mean_absolute_error #平均絶対誤差 import datetime as dt #日時を扱う
前処理(後半)
相関係数と無相関化
変数それぞれの相関係数(correlation coefficient)を求めます。df.corr()
さらに相関係数をヒートマップにして可視化することで
色で相関の強さが見易くなります。
ここでsnsはseabornのこと(ライブラリのインポート時に設定)です。
sns.heatmap(df.corr()) plt.show()
相関が強い変数があると学習が不安定になり、係数の解釈性に信用性がなくなることがあります。
以上の結果から相関がとても強い'pledged'と'usdpledged'の無相関化をします。
df_pledged = pd.DataFrame({'pledged' : df['pledged'], 'usdpledged' : df['usdpledged']}) #元のdf(データフレーム)から対象の変数を抽出して新たなdfに入れる cov = np.cov(df_pledged, rowvar=0) # 分散・共分散を求める _, S = np.linalg.eig(cov) # 分散共分散行列の固有ベクトルをSへ代入 pledged_decorr = np.dot(S.T, df_pledged.T).T #データを無相関化 .Tは転置
無相関化した2つをグラフにプロットし、相関係数を求めます。
print('相関係数: {:.3f}'.format(np.corrcoef(pledged_decorr[:, 0], pledged_decorr[:, 1])[0,1])) #相関係数を表示 plt.grid(which='major',color='black',linestyle=':') #主罫線について plt.grid(which='minor',color='black',linestyle=':') #副罫線について plt.plot(pledged_decorr[:, 0], pledged_decorr[:, 1], 'o') #プロットするデータとプロットに使う記号について plt.show()
無相関化した'pledged'と'usdpledged'を元のデータフレームに戻します。
df['pledged'] = pledged_decorr[:,0] df['usdpledged'] = pledged_decorr[:,1]
ダミー変換
最後にobject型のまま残っている'main_category'と'currency'をダミー変換します。ダミー変換とは質的データを量的データに変換する方法です。
例)fruitsの中にいくつかのフルーツが入っています。
ダミー変換をすることで0と1の数値(量的)データに変換することができます。

まずは'main_category'の中身を確認します。
df['main_category'].unique()
15個のカテゴリーに分かれていることがわかります。
これをダミー変換します。
df_dummy = pd.get_dummies(df['main_category']) #ダミー変換した'main_category'をdf_dummyに入れる。 df = pd.concat([df.drop(['main_category'],axis=1),df_dummy],axis=1) #元のdfにdf_dummyを結合する。axis=1を付けると横に結合する。 df_crdf
'main_category'のダミー変換が出来ました。
同様に'currency'のダミー変換するとデータは以下のようになります。
ホールドアウト法
ホールドアウト法とは、データを予め訓練用とテスト用に分割しておき、学習させたモデルを評価データで把握し、モデルの精度を確かめる方法のことです。
y = df['state'].values #'state' の値をyに代入する X = df.drop('state', axis=1).values #'state'以外の変数をXに代入する test_size = 0.3 #テストデータの割合を決める X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size, random_state=1234) #訓練データとテストデータに分割し、それぞれ変数に代入する
標準化
標準化とは、与えられたデータを平均が0で分散が1のデータに変換することで、データスケールを揃えて、計算や比較をしやすくします。
stdsc = StandardScaler() X_train = stdsc.fit_transform(X_train) #訓練データの標準化 X_test = stdsc.transform(X_test) #テストデータの標準化
学習と結果
前処理長かったーーいよいよ学習を行います!
今回は分類問題なので、ロジスティック回帰で解析をします。
学習のインスタンス化をした後、.fitで学習を実行します。
clf = SGDClassifier(loss='log', penalty='none', max_iter=10000, fit_intercept=True) #loss:損失関数 max_iter:学習の最大回数 fit_intercept:切片を求める clf.fit(X_train, y_train)
学習が終わったら結果の表示をします。
今回表示するのは、対数尤度・正答率・適合率・再現率・F1値です。
y_prd_train = clf.predict(X_train) print('対数尤度 = {:.3f}'.format(- log_loss(y_train, y_prd_train))) # '対数尤度 を表示 print('正答率(Accuracy) = {:.3f}%'.format(100 * accuracy_score(y_train, y_prd_train))) # 正答率を表示 precision, recall, f1_score, _ = precision_recall_fscore_support(y_train, y_prd_train) #適合率・再現率・F1値を計算 print('適合率(Precision) = {:.3f}%'.format(100 * precision[0])) # 適合率を表示 print('再現率(Recall) = {:.3f}%'.format(100 * recall[0])) # 再現率を表示 print('F1値(F1-score) = {:.3f}%'.format(100 * f1_score[0])) #F1値を表示
結果はこのように表示されました。
これはどこかに誤りがあると考えられます。
次回はコードの修正をしていきたいと思います。
皆さんはどこに間違いがあったかわかりますか??わかったら教えてーー