SVMをベースとしたSVRの直線回帰を扱います
元URLは
http://neuro-educator.com/ml18/
二項分類でよく知られるSVM(Support Vector Machine)は分類だけでなく
回帰でも利用されます。今回はSGD(確率的勾配降下法)との比較を行います。
その結果は、今回に関してはSVRの方が誤差が大きくないます。
プロットは黄色い線がSVR、マゼンタがSGDになっています。
SGDでは回帰直線から少しでも離れると、その二乗誤差を考慮する。それに対して
SVRの場合は回帰直線から距離epsilon(ε)までは誤差を考慮せず、それ以上は絶対値で誤差を考慮し、
そのペナルティはCの値の大きさで指定する。
このため、SVRの場合、非説明変数yにのっている小さな誤差に対して強い回帰直線を作ることができる。
またSVMなので、カーネルを利用することが容易であり、
単純に線形回帰でうまくフィッティングできないデータに対しても、
カーネルトリックでフィッティングすることが可能になる。
# 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:学習データとテストデータに分割する(訓練用データを8割、テスト用データを2割に分割する)
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を適用する(SVMベースの回帰法)
# Cはペナルティ項の係数、epsilon(ε)はペナルティをかける回帰直線からの最小距離)
clf_svr = svm.SVR(kernel='linear', C=1e3, epsilon=2.3)
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='c', marker='s')
plt.plot(line_X, line_Y_sgd, c='m')
plt.plot(line_X, line_Y_svr, c='y')
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("\n SGDの平均2乗誤差",RMS_sgd)
print("\n SVRの平均二乗誤差",RMS_svr)
