Python機械学習ライブラリScikit-learn その26:糖尿病患者のデータセットを使って、SVRモデルのオプションを試してみる3

スポンサーリンク

機械学習ライブラリScikit-learn

前回、機械学習ライブラリScikit-learnの糖尿病患者のデータセットを使い、SVRモデルでkernelをrbf中心に色々と試してみました。

Python機械学習ライブラリScikit-learn その25:糖尿病患者のデータセットを使って、SVRモデルのオプションを試してみる2
機械学習ライブラリScikit-learn前回、機械学習ライブラリScikit-learnの糖尿病患者のデータセットを使い、SVRモデルのうちどのkernelでも共通に影響のある(だろう)オプションを試してみました。...

今回は”sigmoid”に関連するオプションを見ていきたいと思います。

ということでまずはデータの読み込みから。

<セル1>

from sklearn.datasets import load_diabetes
import pandas as pd

diabetes = load_diabetes()

df = pd.DataFrame(diabetes.data, columns=diabetes.feature_names)

df["target"] = diabetes.target

df

実行結果

次に機械学習に用いる特徴量とターゲットをそれぞれ変数xとyに格納します。

(後で気付いたのですが、前の記事では「s6」も関連性がありそうということでしたが、忘れてしまいました。他の記事でも上記の組み合わせで行っているものもありますが、忘れたんだなぁと思って読んでください。)

<セル2>

x = df.loc[:, ["bmi", "s5", "bp", "s4", "s3"]]
y = df.loc[:, "target"]

実行結果

次にSVRモデル読み込み、機械学習と予想を100回試した後、その予想精度のスコアの平均値を表示します。

この際、SVRのkernelをsigmoidに指定します。

また過学習になっていないか確認するため、テスト用データでのスコアだけでなく、学習用データでのスコアも計算します。

<セル3>

from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn.metrics import r2_score
import numpy as np

trial = 100

pred_svr_score = []; pred_svr_train_score = []

for i in range(trial):
    x_train_ori, x_test_ori, y_train_ori, y_test_ori = train_test_split(x, y, test_size=0.2, train_size=0.8)
    
    model_svr = SVR(kernel="sigmoid")
    model_svr.fit(x_train_ori, y_train_ori)
    pred_svr_ori = model_svr.predict(x_test_ori)
    pred_svr_score.append(r2_score(y_test_ori, pred_svr_ori))
    
    pred_svr_ori_train = model_svr.predict(x_train_ori)
    pred_svr_train_score.append(r2_score(y_train_ori, pred_svr_ori_train))
    
pred_svr_ave = np.average(np.array(pred_svr_score))
pred_svr_train_ave = np.average(np.array(pred_svr_train_score))
    
print(pred_svr_ave, pred_svr_train_ave)

実行結果
0.40189367844128376 0.4120729668270072

そしてグラフの表示です。

<セル4>

from matplotlib import pyplot as plt

fig=plt.figure(figsize=(8,6))
plt.clf()

plt.scatter(y_test_ori, pred_svr_ori)

実行結果

ということでkernel=”sigmoid”に関連するオプションを見ていきましょう。

解説ページからすると、「gamma」と「coef0」が”sigmoid”に関連するようです。

sklearn.svm.SVR — scikit-learn 0.24.1 documentation

「gamma」は前回、kernel=”rbf”の時に試しているので、今回は「coef0」を試してみることにします。

スポンサーリンク

coef0

coef0: カーネル関数とは独立した項(?)。”poly”と”sigmoid”においてのみ意味を持つ。
float値(小数)、デフォルト値は0.0

これまたよく分からない値です。

とりあえず”poly”と”sigmoid”の時だけ使用できる値であるということだけは分かりました。

デフォルト値は0.0らしいので、まずは負の値が使えるかどうかの確認をしてみます。

ということでまずはcoef0=-1を試してみましょう。

<セル5 coef0=-1>

trial = 100

pred_svr_score = []; pred_svr_train_score = []

for i in range(trial):
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)
    
    model_svr = SVR(kernel="sigmoid", coef0=-1)
    model_svr.fit(x_train, y_train)
    pred_svr = model_svr.predict(x_test)
    pred_svr_score.append(r2_score(y_test, pred_svr))
    
    pred_svr_train = model_svr.predict(x_train)
    pred_svr_train_score.append(r2_score(y_train, pred_svr_train))
    
pred_svr_ave = np.average(np.array(pred_svr_score))
pred_svr_train_ave = np.average(np.array(pred_svr_train_score))
    
print(pred_svr_ave, pred_svr_train_ave)

実行結果
0.3771579626675715 0.3874905934987896

負の値も使うことができました。

スコア的には指定なしの「0.40189」よりもほんの少し悪くなったかなという感じですね。

グラフはどうでしょうか。

<セル6 coef0=-1>

fig=plt.figure(figsize=(8,6))
plt.clf()

plt.scatter(y_test_ori, pred_svr_ori)
plt.scatter(y_test, pred_svr)

実行結果

グラフ的にはあまり変わったように見受けられません。

では正の値はどうでしょうか。

coef0=1を試してみましょう。

<セル5 coef0=1>

trial = 100

pred_svr_score = []; pred_svr_train_score = []

for i in range(trial):
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)
    
    model_svr = SVR(kernel="sigmoid", coef0=1)
    model_svr.fit(x_train, y_train)
    pred_svr = model_svr.predict(x_test)
    pred_svr_score.append(r2_score(y_test, pred_svr))
    
    pred_svr_train = model_svr.predict(x_train)
    pred_svr_train_score.append(r2_score(y_train, pred_svr_train))
    
pred_svr_ave = np.average(np.array(pred_svr_score))
pred_svr_train_ave = np.average(np.array(pred_svr_train_score))
    
print(pred_svr_ave, pred_svr_train_ave)

実行結果
0.33454221936314604 0.35578786905343385

指定なしの「0.40189」で、coef0=-1の時のスコアが「0.37716」なのでまた悪くなってしまいました。

<セル6 coef0=1>

fig=plt.figure(figsize=(8,6))
plt.clf()

plt.scatter(y_test_ori, pred_svr_ori)
plt.scatter(y_test, pred_svr)

実行結果

グラフはあまり変わったように見えませんが、これでもスコアに大きく影響しているのですね。

coef0の値をもっと大きくしたらどうなるでしょうか?

ということで次はcoef0=10を試してみます。

<セル5 coef0=10>

trial = 100

pred_svr_score = []; pred_svr_train_score = []

for i in range(trial):
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)
    
    model_svr = SVR(kernel="poly", coef0=10)
    model_svr.fit(x_train, y_train)
    pred_svr = model_svr.predict(x_test)
    pred_svr_score.append(r2_score(y_test, pred_svr))
    
    pred_svr_train = model_svr.predict(x_train)
    pred_svr_train_score.append(r2_score(y_train, pred_svr_train))
    
pred_svr_ave = np.average(np.array(pred_svr_score))
pred_svr_train_ave = np.average(np.array(pred_svr_train_score))
    
print(pred_svr_ave, pred_svr_train_ave)

実行結果
0.4445049760366271 0.5135215264118775

スコアは今回最高値が出てきました。

予想値はどう変わったのか、グラフで確認してみましょう。

<セル6 coef=10>

fig=plt.figure(figsize=(8,6))
plt.clf()

plt.scatter(y_test_ori, pred_svr_ori)
plt.scatter(y_test, pred_svr)

実行結果

予想値が大きくばらけてきました。

このばらけ具合が広がったことにより、全体的に予想値が正解値に近くなったものだと推測されます。

ということはcoef0は大きければ大きい方がいいのでしょうか?

coef0=100を試してみることにします。

<セル5 coef=100>

trial = 100

pred_svr_score = []; pred_svr_train_score = []

for i in range(trial):
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)
    
    model_svr = SVR(kernel="poly", coef0=100)
    model_svr.fit(x_train, y_train)
    pred_svr = model_svr.predict(x_test)
    pred_svr_score.append(r2_score(y_test, pred_svr))
    
    pred_svr_train = model_svr.predict(x_train)
    pred_svr_train_score.append(r2_score(y_train, pred_svr_train))
    
pred_svr_ave = np.average(np.array(pred_svr_score))
pred_svr_train_ave = np.average(np.array(pred_svr_train_score))
    
print(pred_svr_ave, pred_svr_train_ave)

実行結果
0.39994249453680814 0.5091461706701099

スコアは少し悪くなり「0.39994」。

<セル6 coef=100>

fig=plt.figure(figsize=(8,6))
plt.clf()

plt.scatter(y_test_ori, pred_svr_ori)
plt.scatter(y_test, pred_svr)

実行結果

先ほどのcoef0=10と比べてみるとそれほどばらつき具合が変わったようには見えません。

ただこの結果には現れてこない部分である計算時間に差はありました。

coef0=100とすると明らかにcoef=10よりも計算時間が伸びていることから、coef0の値を大きくするに従って計算コストが増大してくようです。

となると計算時間と予想精度のバランスを見極めてcoef0の値を決めていくということが必要そうです。

さてcoef0=10でそこそこ予想精度のスコアが上がったのですが、負の値にしても同じような結果になるのでしょうか。

ということで次にcoef0=-10を試してみましょう。

<セル5 coef0=-10>

trial = 100

pred_svr_score = []; pred_svr_train_score = []

for i in range(trial):
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, train_size=0.8)
    
    model_svr = SVR(kernel="poly", coef0=-10)
    model_svr.fit(x_train, y_train)
    pred_svr = model_svr.predict(x_test)
    pred_svr_score.append(r2_score(y_test, pred_svr))
    
    pred_svr_train = model_svr.predict(x_train)
    pred_svr_train_score.append(r2_score(y_train, pred_svr_train))
    
pred_svr_ave = np.average(np.array(pred_svr_score))
pred_svr_train_ave = np.average(np.array(pred_svr_train_score))
    
print(pred_svr_ave, pred_svr_train_ave)

実行結果
-1519.7871103286814 -1455.4665236178143
<セル6 coef=-10>

fig=plt.figure(figsize=(8,6))
plt.clf()

plt.scatter(y_test_ori, pred_svr_ori)
plt.scatter(y_test, pred_svr)

実行結果

coef0=-10とするとスコアからもグラフからも予想精度が劇的に低下したことが分かります。

裏には色々な計算があるのでしょうが、なかなかそこまで踏み込めないので、ある程度こう言った傾向だけになってしまうのですが、それでも少しパラメータを変えるだけで劇的に変化があると楽しいものです。

それでは次回は最後に残った”poly”に関連するパラメータをいじっていきたいと思います。

ということで今回はこんな感じで。

コメント

タイトルとURLをコピーしました