- ダミー変数化は、訓練データと検証データを分ける前に行う
…訓練データからカテゴリ構造を確定させ、その変換規則を検証・テストデータに適用する必要がある。
- 決定木分析では、特徴量をこちらで指定する。一方、重回帰分析では、モデルが学習を行うとき、自動で特徴量の重要度を下げる仕組みを持たないため、当たられた列をすべて利用しようとする
- そのため、特徴量として予測に大きな影響を与える列の中に、予測に影響しない列を紛れ込ませると、予測精度が低下する
- 外れ値の影響は、目的変数や特徴量の組み合わせによって変化するため、影響の大きそうな列を中心に可視化しつつ、モデル全体への影響を確認する必要がある。
col=["INDUS","NOX","RM","PTRATIO","LSTAT","PRICE"]
#予測に強い影響を与える列を絞り込む
train_val4=train_val3[col]
書き方
df.corr()
train_val4.corr()
#すべての列同士の相関係数を見る
train_cor=train_val4.corr()["PRICE"]
#PRICE列との相関係数のみ知りたいので、PRICE列との相関係数だけ出力する
train_cor
書き方 シリーズの作成
pd.Series(リスト,index=インデックスのリスト)
書き方 シリーズに関数を適用する
se.map(関数名)
#seはシリーズの変数
abs_cor=train_cor.map(abs)
#train_corは一列なのでシリーズ
#mapメソッドをつかって、abs関数をtrain_corシリーズに適用する
abs_cor
書き方 シリーズの要素を並び替える
se.sort_values(ascending=○○)
#ascending=Trueなら昇順、Falseなら降順
書き方 データフレームの行を並び替える
df.sort_values(by=”○○”,ascending=○○)
abs_cor.sort_values(ascending=False)
- 順番は、散布図で外れ値のチェック→相関係数のチェック
- 相関係数は一部の外れ値のせいで、0に近くなることがあるから
- 特徴量の標準化
- 各特徴量の分布が大きく異なるときに、その特徴量を標準化する必要がある。
- 標準化を行うと、平均値が0,標準偏差が1となる
書き方
変数1=StandardScaler()
変数1.fit(データ集合)
変数2=変数1.transform(変換前データ)
from sklearn.preprocessing import StandardScaler
sc_model_x=StandardScaler()
#標準化(平均0・分散1)を行うための処理規則を保持できるクラス StandardScaler のインスタンスを生成し、それを sc_model_x という変数に代入している。
#この時点ではまだ平均や標準偏差は計算されておらず、それらは fit() によって学習データから推定・保存される。
#同じ変換をテストデータにも使うため、StandardScaler() を変数に入れる
sc_model_x.fit(x_train)
# StandardScaler で定義されたオブジェクトsc_model_x のfitメソッドによって、引数のx_train を 各列ごとに平均値(mean)標準偏差(standard deviation)を計算
#それをsc_model_xに格納する
sc_x=sc_model_x.transform(x_train)
#fit で計算した「平均・標準偏差」を使って、x_train を標準化した新しいデータを作り、それを sc_x に代入する
sc_model_y=StandardScaler()]
#正解データを標準化する
sc_model_y.fit(y_train)
sc_y=sc_model_y.transform(y_train)
tmp_df=pd.DataFrame(sc_x,columns=x_train.columns)
#データフレーム型にする
tmp_df.mean()
#各特徴量が、本当に平均0になっているかを確認
sc_x_val=sc_model_x.transform(x_val)
#sc_model_xは、StandardScalerクラスのオブジェクト
#ここには訓練データ(x_train)の平均値や標準偏差の情報が格納されている
#それを利用して、x_val(検証用データ)も標準化する
sc_y_val=sc_model_y.transform(y_val)
model.score(sc_x_val,sc_y_val)
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
def learn (x,t):
x_train,x_val,y_train,y_val=train_test_split(x,t,test_size=0.2,random_state=0)
#訓練データと検証用(validation)データに分ける
sc_model_x=StandardScaler()
#StandardScalerクラスの空のインスタンス(オブジェクト)を作る
sc_model_x.fit(x_train)
#StandardScalerオブジェクトのfitメソッドを使って、引数x_trainの平均値と標準偏差を計算し、
#scaler に学習させて内部パラメータとしてsc_model_xに保持させる
sc_x_train=sc_model_x.transform(x_train)
#sc_model_xのデータを使ってx_trainを標準化し、sc_x_trainに代入する
model=LinearRegression()
#回帰モデルの空のインスタンスを作りmodelに格納する
model.fit(sc_x_train,y_train)
#標準化したsc_x_train,y_trainのデータを用いて、回帰モデルを作り、modelに格納する
sc_x_val=sc_model_x.transform(x_val)
#検証用データも同じように、“訓練データでfitした同じscaler”で標準化する
train_score=model.score(sc_x_train,y_train)
val_score=model.score(sc_x_val,y_val)
#訓練データと検証データを使ってスコアを出す
return train_score,val_score
x=train_val3.loc[:,["RM","LSTAT","PTRATIO"]]
t=train_val3["PRICE"]
s1,s2=learn(x,t)
print(s1,s2)
- 特徴量エンジニアリング
- 準備されたデータをもとに新しい列をつくって特徴量にくわえること
- 散布図から非線形性が疑われたため、二乗項を追加した
- 2乗した列をつくり、それを新しい特徴量にして再学習
x["RM2"]=x["RM"]**2
#RM列を2乗して新しい列に追加
s1,s2=learn(x,t)
print(s1,s2)
特徴量同士を組み合わせて新しい特徴量を作る
x["RM*LSTAT"]=x["RM"]*x["LSTAT"]
x.head(3)
s1,s2=learn(x,t)
print(s1,s2)
#訓練データと検証データを合わせて再学習
sc_model_x2=StandardScaler()
sc_model_x2.fit(x)
#StandardScalerオブジェクトのfitメソッドを使って、引数xの平均値と標準偏差を計算し、
#scaler に学習させて内部パラメータとしてsc_model_x2に保持させる
sc_x=sc_model_x2.transform(x)
#sc_model_x2のデータを使ってxを標準化し、sc_xに代入する
model=LinearRegression()
model.fit(sc_x,t)
# test データの欠損値を、学習用データ(train_val)の平均値で補完する
# 学習時と同じ基準で欠損補完を行うため
test2 = test.fillna(train_val.mean())
# 説明変数(特徴量)として使用する列だけを取り出す
x_test = test2.loc[:, ["RM", "LSTAT", "PTRATIO"]]
# 目的変数(正解データ)を取り出す
# ※ score() では Series の方が望ましいが、今回は DataFrame でも動作している
y_test = test2"PRICE"
# RM の2乗項(非線形関係を捉えるための特徴量)
x_test["RM2"] = x_test["RM"] ** 2
# LSTAT の2乗項
x_test["LSTAT2"] = x_test["LSTAT"] ** 2
# PTRATIO の2乗項
x_test["PTRATIO2"] = x_test["PTRATIO"] ** 2
# RM と LSTAT の交互作用項
# 2つの変数の組み合わせ効果をモデルに学習させるため
x_test["RM*LSTAT"] = x_test["RM"] * x_test["LSTAT"]
# StandardScaler を fit したときと「同じ列・同じ順序」に揃える
# feature_names_in_ は、sc_model_x2 が学習時に受け取った列名の一覧
x_test = x_test[sc_model_x2.feature_names_in_]
# 学習時に計算した平均・標準偏差を使って、テストデータを標準化する
sc_x_test = sc_model_x2.transform(x_test)
# 標準化済みテストデータを用いてモデルの決定係数(R^2)を計算する
model.score(sc_x_test, y_test)
感想
大分複雑になってきました。前処理やチューニングは、やっている最中はなにをしているか理解できますが、さてテストとなると、ここまでやってきたことを忘れています。手順をきっちり覚えなくてはなりません。