SGD回帰によって、連続データを線形回帰分析する手法を、実装・解説します。
本記事ではSGD Regressorを実装します。
回帰分析は連続値である被説明変数yに対して、説明変数xでyを近似する式を導出する分析です。
主に線形回帰を扱い、
y = w・x +b
という関係を満たす係数wとb(切片)を求めます。
SGD回帰はStochastic Gradient Descentを使用する回帰分析です。
近似式を導出するために係数を求めていきますが、全部のデータを一度に使用せずに一部のデータを交互に使用します。
以下のscikit-learnマップの黒矢印に対応します。
目的変数の量を求める→サンプル数10万以上→[SGD Regressor]
です。
なおscikit-learnのversionを0.19にするために、
スタートアップからAnaconda Promptを開き、
1 2 3 | conda update conda conda install scikit-learn=0.19 |
を実行しておきます。
SGD Regressorの実装
本記事では、住宅価格のデータを使用して実装します。
Boston house-prices (ボストン市の住宅価格)と呼ばれます。
説明変数xは13次元で
- CRIM 犯罪発生率
- ZN 住居区画の密集度
- INDUS 非小売業の土地割合
- CHAS チャールズ川 (1: 川の周辺, 0: それ以外)
- NOX NOx 濃度
- RM 住居の平均部屋数
- AGE 1940 年より前に建てられた物件の割合
- DIS 5 つのボストン市の雇用施設からの重み付き距離
- RAD 大きな道路へのアクセスしやすさ
- TAX $10,000 ドルあたりの所得税率
- PTRATIO 教師あたりの生徒数
- B 黒人の比率
- LSTAT 低所得者の割合
となっています。
被説明変数yは住宅価格の中央値です。
本記事では全部の住宅の部屋数RMのみを用いた回帰と、全部の次元を使用した回帰を行います。
実装コードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # 1:ライブラリのインポート-------------------------------- import numpy as np #numpyという行列などを扱うライブラリを利用 import pandas as pd #pandasというデータ分析ライブラリを利用 import matplotlib.pyplot as plt #プロット用のライブラリを利用 from sklearn import cross_validation, preprocessing, linear_model #機械学習用のライブラリを利用 import sklearn sklearn.__version__ #解説 2:Housingのデータセットを読み込む-------------------------------- df=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/housing/housing.data', header=None, sep='\s+') df.columns=['CRIM','ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV'] X_rm=df[['RM']].values X=df.iloc[:, 0:13] #X=df[['AGE']].values Y=df['MEDV'].values #解説 3:データの整形------------------------------------------------------- sc=preprocessing.StandardScaler() sc.fit(X) X=sc.transform(X) sc.fit(X_rm) X_rm=sc.transform(X_rm) #解説 4:学習データとテストデータに分割する------------------------------- X_train, X_test, Y_train, Y_test = cross_validation.train_test_split(X, Y, test_size=0.2, random_state=0) X_rm_train, X_rm_test, Y_train, Y_test = cross_validation.train_test_split(X_rm, Y, test_size=0.2, random_state=0) #解説 5:SGD Regressorを適用する------------------------------------------- clf = linear_model.SGDRegressor(max_iter=1000) clf.fit(X_train, Y_train) clf_rm = linear_model.SGDRegressor(max_iter=1000) clf_rm.fit(X_rm_train, Y_train) print("全部使用したときの回帰式の係数") print(clf.intercept_) print(clf.coef_) #解説 6:結果をプロットする------------------------------------------------ %matplotlib inline line_X=np.arange(-4, 4, 0.1) #3から10まで1刻み line_Y=clf_rm.predict(line_X[:, np.newaxis]) plt.figure(figsize=(10,10)) plt.subplot(2, 1, 1) plt.scatter(X_rm_train, Y_train, c='b', marker='s') plt.plot(line_X, line_Y, c='r') plt.show #解説 7:誤差をプロットする------------------------------------------------- Y_rm_pred=clf_rm.predict(X_rm_test) plt.subplot(2, 1, 2) plt.scatter(Y_test, Y_rm_pred-Y_test, c='b', marker='s', label="RM_only") Y_pred=clf.predict(X_test) plt.scatter(Y_test, Y_pred-Y_test, c='r', marker='s',label="ALL") plt.legend() plt.hlines(y=0, xmin=0, xmax=50, colors='black') plt.show print("\n「RMだけの平均2乗誤差」と「全部を使用したときの平均二乗誤差」") RMS=np.mean((Y_pred - Y_test) ** 2) RMS_rm=np.mean((Y_rm_pred - Y_test) ** 2) print(RMS_rm) print(RMS) |
結果は次の通りになります。
上記結果は、まず全部の次元を使用した回帰式の係数を示します。
次に、回帰式でテストデータの住宅価格を推定した際に、RMだけの場合の平均二乗誤差と全部の次元を使用した場合の平均二乗誤差を示しています。
全部使用する方が誤差は少ないです。
グラフは、1つ目はx軸が部屋数(正規化)を示し、y軸が住宅価格となっています。
直線はRMだけの場合の回帰結果を示します。
2つ目のグラフはテストデータにおいて、x軸が住宅価格を示し、y軸が回帰式で推定した値と正解値との誤差を示します。
実装コードを解説します。
#解説 2:Housingのデータセットを読み込む——-
ここでHousingのデータを読み込んでいます。
#解説 3:データの整形——-
説明変数xの各次元を正規化しておきます。
#解説 4:学習データとテストデータに分割する—-
8割を学習データとして回帰式を作成し、残り2割で誤差を評価します。
#解説 5:SGD Regressorを適用する——————————————-
clf = linear_model.SGDRegressor(max_iter=1000)
回帰式を実行しますが、iterationの回数を1000にしておきます。
デフォルトでは5で少ないです(そのうち1000がdefaultになるそうです)
#解説 6:結果をプロットする—-
RMだけで回帰した場合の結果をプロットします。
きちんと回帰分析できているかを目視します。
#解説 7:誤差をプロットする————————————————-
テストデータに対して、回帰式での予測値との誤差を求め、プロットします。
全部のデータを使用するほうが結果が良いです。
それでは「結局、SGD Regressionって何をやっていたの?」を説明します。
SGD Regressionの心
正確な情報は以下をご覧ください。
●scikit-learnのSGD Regressorの解説ページ
基本的にはSGD Classificationとやっていることは同じになります。
事前に説明変数を正規化し、iteration回数を増やしておく点に注意が必要です。
以上、Pythonとscikit-learnで学ぶ機械学習入門|第14回:SGD回帰での回帰分析でした。
次回はLasso回帰について説明します。