SVR(Linear)回帰によって、連続データを線形回帰分析する手法を、実装・解説します。
本記事ではSVMをベースとした回帰手法であるSVR(Support Vector Regression)を実装します。
SVMはカーネルトリックで非線形を扱いますが、本記事ではまず線形カーネルによる回帰手法を紹介します。
SVMを回帰解析に使用するってあまり直感的ではないですが、そのあたりも説明したいと思います。
SVR Linear回帰分析は以下のscikit-learnマップの黒矢印に対応します。
目的変数の量を求める→サンプル数10万以下→説明変数xの特徴量のすべてが重要→[SVR linear]
です。
SVR linearの実装
実装して、SGD回帰との結果を比較します。
これまでと同様に、住宅価格のデータを使用して実装します。
被説明変数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 | # 1:ライブラリのインポート-------------------------------- import numpy as np #numpyという行列などを扱うライブラリを利用 import pandas as pd #pandasというデータ分析ライブラリを利用 import matplotlib.pyplot as plt #プロット用のライブラリを利用 from sklearn import cross_validation, preprocessing, linear_model, svm #機械学習用のライブラリを利用 # 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_rm_train, X_rm_test, Y_train, Y_test = cross_validation.train_test_split(X_rm, Y, test_size=0.5, random_state=0) # 5:SGD Regressorを適用する------------------------------------------- clf_rm = linear_model.SGDRegressor(max_iter=1000) clf_rm.fit(X_rm_train, Y_train) # 解説6:SVR linear Regressorを適用する------------------------------------------- clf_svr = svm.SVR(kernel='linear', C=1e3, epsilon=2.0) clf_svr.fit(X_rm_train, Y_train) # 7:結果をプロットする------------------------------------------------ %matplotlib inline line_X=np.arange(-4, 4, 0.1) #3から10まで1刻み line_Y_sgd=clf_rm.predict(line_X[:, np.newaxis]) line_Y_svr=clf_svr.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_sgd, c='r') plt.plot(line_X, line_Y_svr, c='g') plt.show # 8:誤差------------------------------------------------- Y_pred_sgd=clf_rm.predict(X_rm_test) Y_pred_svr=clf_svr.predict(X_rm_test) print("\n「SGDの平均2乗誤差」と「SVRの平均二乗誤差」") RMS_sgd=np.mean((Y_pred_sgd - Y_test) ** 2) RMS_svr=np.mean((Y_pred_svr - Y_test) ** 2) print(RMS_sgd) print(RMS_svr) |
結果は次の通りになります。
緑色がSVRによる結果です。
今回はSVRの方が誤差は大きくなりました。
重要なのは、SDGとは結果が異なるということです。
実装コードを解説します。
# 解説6:SVR linear Regressorを適用する——————————————-
clf_svr = svm.SVR(kernel=’linear’, C=1e3, epsilon=2.0)
ここでSVR回帰を指定しています。
カーネルはlinearを指定しています。
Cはペナルティ項の係数です。
epsilonは回帰直線からどれだけ離れたらペナルティをかけるかを指定します。
それでは「結局、SVRって何をやっていたの?」を説明します。
SVRの心
正確な情報は以下をご覧ください。
SVRとはSVMを回帰分析に利用した手法です。
とはいえ、直感的には分かりにくいです。
識別平面を作るSVC(SVM Classification)を回帰解析に使用することについて説明します。
SVCの場合、マージン最大化といって、識別平面からそれぞれのクラスの最近傍の点への距離が最大となるように識別平面を設定しました。
SVRの場合この部分は、重みの最小化となり、重み係数wの二乗和(L2ノルム)が最小となるように設定します。
SVCの場合、ソフトマージンといってスラック変数を用意し、識別平面できちんと識別できなかった誤識別された点に対してペナルティを与えました。
SVRの場合も同様に回帰直線から一定の距離(epsilon)まではペナルティを与えませんが、それ以上離れた点に対してはペナルティを与えます。
ペナルティはヒンジ関数で与えられます。
またペナルティをどれほど考慮するかはCで設定します。
以上の点を踏まえ、SVRを通常の線形回帰と比較した特徴を述べます。
定量的には、線形回帰の場合は回帰直線から少しでも離れると、その二乗誤差を考慮します。
一方SVRの場合は回帰直線から距離epsilonまでは誤差を考慮せず、それ以上は絶対値で誤差を考慮します。
そのため定性的にはSVRの場合、非説明変数yにのっている小さな誤差に対して強い回帰直線を作ることができます。
またSVMなので、カーネルを利用することが容易であり、単純に線形回帰でうまくフィッティングできないデータに対しても、カーネルトリックでフィッティングすることが可能になります。
カーネルトリックの非線形フィッティングは次回説明します。
SVRについて詳細はこちらのスライドが分かりやすいです。
●サポートベクター回帰(Support Vector Regression, SVR)
以上、Pythonとscikit-learnで学ぶ機械学習入門|第18回:SVR linear回帰での回帰分析でした。
次回はSVR(Support Vector Regression)のカーネルによる非線形回帰について説明します。