【特訓 ver.2】 多項式回帰スタート!!
ただし、いつも上記のように、シンプルに比例するような関係でない場合もある。
・その場合に多項式回帰で考える。2次以上の関数に適用する(2次関数など)
※とはいえ、事前に多項式回帰とわかるケースは少ないらしい...。
それではスタート!!
大まかな流れ
以下、2ステップで実践。
その1:まずは、前回学習した【単回帰分析】で実装。
その2:その後、【多項式回帰】で実装し、精度の違いを見てみる。
使用データ
その1:単回帰分析
・データの確認
・データの分割→線形回帰モデルの作成
・結果の可視化、および評価
復習なのでサクッと!
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# データの読み込み
df = pd.read_csv("/content/Position_Salaries.csv")
print(df.head())
print()
# 相関の確認
print(df[["Level", "Salary"]].corr())
# 散布図の描画
plt.scatter(df["Level"], df["Salary"])
plt.title("Level vs Salary")
plt.xlabel("Level")
plt.ylabel("Salary")
plt.show()
# データの分割
X = df["Level"].values.reshape(-1, 1)
Y = df["Salary"].values
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, train_size=0.7, random_state=0)
# モデルの訓練
model = LinearRegression()
model.fit(X_train, Y_train)
# 予測
Y_pred = model.predict(X_test)
# グラフの可視化
plt.scatter(X, Y, color="blue")
plt.plot(X, model.predict(X), color="red")
plt.title("Level vs Salary Prediction")
plt.xlabel("Level")
plt.ylabel("Salary")
plt.show()
# モデルの評価
mse = mean_squared_error(Y_test, Y_pred)
r2 = r2_score(Y_test, Y_pred)
print(f"テストデータのMSE: {mse}")
print(f"テストデータのR²: {r2}")
番外編
・式の作成、モデルの予測
#式の算出
print(f"intercept(切片)は、{model.intercept_}")
print(f"coefficient(傾き)は、{model.coef_[0]}")
回帰分析から得られた回帰式は、
y = -187264.57 + 82522.42 x
完成!!!!!!
#仮にレベル12の階級があった時の給与を算出
import numpy as np
x_12 = np.array(12).reshape(-1,1)
y_pred = model.predict(x_12)
y_pred
仮にレベル12の階級があった時の給与は、だいたい800000くらい・・・。だいぶ乖離がある。
その2:多項式回帰分析
大まかな流れ
① データの準備と可視化
↓
② モデルの設定と訓練
↓
③ 結果の可視化
↓
④ 式の作成、代入して考察
① データの準備と可視化
import pandas as pd
import matplotlib.pyplot as plt
# データの読み込み
df = pd.read_csv("/content/Position_Salaries.csv")
print(df.head())
# 散布図の描画
plt.scatter(df["Level"], df["Salary"])
plt.title("Level vs Salary")
plt.xlabel("Level")
plt.ylabel("Salary")
plt.show()
ここまでは先ほどと同じ。
② モデルの設定と訓練
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
X = df["Level"].values.reshape(-1,1)
Y = df["Salary"]
# 多項式特徴量の生成
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)
# モデルの訓練
model = LinearRegression()
model.fit(X_poly, Y)
単回帰との違いについて(1次関数)。
こちらはX、Yとの関係が非常にシンプルになっているためそのままmodelに突っ込めばよかった。
一方でそれ以上の関数(2次以上の関数)の場合は、複雑になるため、まずは、Xの累乗値の値を別で求めてあげる必要になる。
※y = ax²の x²の部分
手順としては、
・X、 Yの設定をする
・modelに当てはめる が単回帰の方法だが、その間にワンクッションを挟む。
具体的には
・X、 Yの設定をする
↓
・高次数にも対応するように「PolynomialFeatures」を設定する
↓
・高次数に対応したX(今回でいうとX_poly)を用いてmodelを訓練する
【コードの説明】
・poly = PolynomialFeatures(degree=2)
これはdegree=2で2次関数を表す。
変数Xを2次関数に対応させるための前準備。
・X_poly = poly.fit_transform(X)
先ほど準備したものを、実際に対応させる(出力結果は以下)。
今回はLEVELが1~10まであるため、最後の行でx²の値を出力している。
※2行目がX、3行目がX²の値。
③ 結果の可視化
#結果の可視化
plt.scatter(X,Y,color="blue")
plt.plot(X,model.predict(X_poly),color="red")
plt.show()
# より滑らかなカーブを作成する(ために、説明変数(X)をより細かくする)
X_grid = np.arange(min(X),max(X),0.1)
X_grid = X_grid.reshape(-1,1)
plt.scatter(X, Y, color="blue")
plt.plot(X_grid, model.predict(poly.transform(X_grid)), color="red")
plt.show()
④ 式の作成、代入して考察
#式を求める
print(f"式は、y = {model.intercept_} + {model.coef_[1]}x + {model.coef_[2]}x^2")
#x=12を代入して、精度を確認
x_12 = np.array(12).reshape(-1,1)
y_pred = model.predict(poly.transform(x_12))
y_pred
a(切片)・・・intercept_
で求める
b(傾き)・・・coef_[1]
coef_[2]
で求める
※coef_[0]はintercept_と一致(xの0乗の係数を意味する。が実際には機能しない)
※coef_[1]はxの1乗の係数を意味する。
※coef_[0]はxの2乗の係数を意味する。
単回帰分析の際は、「仮にレベル12の階級があった時の給与は、だいたい800000くらい・・・。」と出力されたが、今回は、1435893と結果が出て、現実的な値に近づいた。
【練習問題】 あさがおの成長を分析
以下、4ステップを意識して実施。
・データの準備と可視化
・モデルの設定と訓練(多項式回帰を用いる)
・結果の可視化
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
# データの準備
df = pd.read_csv("/content/asagao.csv")
# 散布図でデータを可視化
plt.scatter(df['days'], df['length'], color='blue')
plt.title('days vs length')
plt.show()
# データの分割
X = df['days'].values.reshape(-1, 1)
Y = df['length'].values
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0)
# モデルの設定と訓練
poly = PolynomialFeatures(degree=4)
X_poly_train = poly.fit_transform(X_train)
X_poly_test = poly.transform(X_test)
model = LinearRegression()
model.fit(X_poly_train, Y_train)
# 結果の可視化
X_grid = np.arange(min(X), max(X), 0.1).reshape(-1, 1)
X_poly_grid = poly.transform(X_grid)
Y_grid_pred = model.predict(X_poly_grid)
plt.scatter(X, Y, color='blue', label='data')
plt.plot(X_grid, Y_grid_pred, color='red')
plt.title('asagao_pred')
plt.legend()
plt.show()
ついでの評価の精度も見ておく。
from sklearn.metrics import mean_squared_error, r2_score
# モデルの評価
Y_train_pred = model.predict(X_poly_train)
Y_test_pred = model.predict(X_poly_test)
train_mse = mean_squared_error(Y_train, Y_train_pred)
test_mse = mean_squared_error(Y_test, Y_test_pred)
train_r2 = r2_score(Y_train, Y_train_pred)
test_r2 = r2_score(Y_test, Y_test_pred)
print(f'Train MSE: {train_mse}, Test MSE: {test_mse}')
print(f'Train R^2: {train_r2}, Test R^2: {test_r2}')
精度を試す中で、degree=4の時からR^2が1にだんだん近づいていった。
続いては、 重回帰分析へGO!!!