質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2634閲覧

回帰分析においての損失関数の出し方(ridge)と交差検証の解釈について

unser

総合スコア58

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/04/21 07:53

編集2021/04/21 09:09

Pythonにて,Ridge回帰などを行い,その損失関数(MSE)の値を算出したいのですが,
その見方の方法がわからないためご教授していただけると幸いです.

また,Ridge回帰や線形単回帰,他項回帰で得られた,モデルの係数を
どのように参照したら良いかを教えていただけると幸いです.

また,付随する質問とはなりますが,
その損失関数をk-交差検証でモデルを評価した際に,
どのような判断をすれば良いかの質問を下部でしているため,お答えしていただけると幸いです.

何卒よろしくお願いいたします.

以下はコードと説明です.

python

1# import library 2%matplotlib inline 3import matplotlib.pyplot as plt 4import numpy as np 5import pandas as pd 6from sklearn.model_selection import train_test_split 7from sklearn.preprocessing import StandardScaler 8from sklearn.linear_model import LinearRegression 9from sklearn.linear_model import Ridge 10from sklearn.preprocessing import PolynomialFeatures 11 12from sklearn.model_selection import cross_val_score 13from sklearn.metrics import mean_squared_error 14import statistics 15 16# generate a true function 17def func(x): 18 return 100*x+10*x**3+0.001*x**15 19 20# generate sample datas {(y,x)}_30 21np.random.seed(0) 22x = np.random.rand(30) * 2 23noise = (np.random.rand(30) -0.5)* 100 24true_y = func(x) 25y = true_y + noise 26 27# visualize true function and sample data 28plt.scatter(x,y) 29xx=np.arange(0,2,0.01) 30yy = func(xx) 31plt.plot(xx, yy)

イメージ説明

python

1x=x.reshape(-1,1) 2# generate models 3 4# degree=1 5k_1=500 6model1=LinearRegression() 7model2=Ridge(alpha=k_1) 8 9# degree = 20 10k_20=500 11model3=LinearRegression() 12model4=Ridge(alpha=k_20) 13base_x_20=PolynomialFeatures(degree=20,include_bias=False) 14x_20=base_x_20.fit_transform(x) 15 16model1.fit(x,y) 17model2.fit(x,y) 18model3.fit(x_20,y) 19model4.fit(x_20,y) 20 21# visualize model 22# visualize model 23def model_conf(model,x): 24 y=[model.intercept_ for _ in range(len(x))] 25 for j in range(len(x)): 26 for i in range(len(model.coef_)): 27 y[j]+=model.coef_[i]*((x[j][0])**(i+1)) 28 return y 29 30plt.figure(figsize=(10, 7)) 31 32X_plt=np.arange(0,2,0.01).reshape(200,1) 33 34y_pred = model1.predict(X_plt) 35y_pred2 = model2.predict(X_plt) 36 37line_20=base_x_20.transform(X_plt) 38y_pred3=model3.predict(line_20) 39y_pred4=model4.predict(line_20) 40 41plt.scatter(x, y, color='blue', label='data') 42plt.plot(X_plt, func(X_plt), color='purple', linestyle='-', label='True Function', lw=5) 43plt.plot(X_plt, y_pred, color='red', linestyle=':', label='LinearRegression', lw=3) 44plt.plot(X_plt, y_pred2, color='black', linestyle='--', label='Line Ridge(α={})'.format(k_1), lw=3) 45#plt.plot(X_plt, model_conf(model3,X_plt), color='purple', linestyle="dashdot", label='Polynomial regression(20)', lw=5) 46plt.plot(X_plt, y_pred3, color='green', linestyle="dashdot", label='Polynomial regression(20)', lw=3) 47plt.plot(X_plt, y_pred4, color='pink', linestyle='-', label='Poly Ridge(α={})'.format(k_1), lw=3) 48plt.legend() 49 50plt.ylim([-50,300]) 51plt.show()

イメージ説明

python

1#損失関数を算出する.(修正 4/21, 17:29) 2ans_lst=[] 3for i in range(5): 4 ans=0 5 if i==0: 6 #score=cross_val_score(model1,x,y,cv=10) 7 ans=statistics.mean(list(map(lambda t: t**2, (y-model1.predict(x)).tolist()))) 8 elif i==1: 9 model2.coef_ 10 ans=statistics.mean(list(map(lambda t: t**2, (y-model2.predict(x)).tolist()))) 11 ans+=sum(list(map(lambda t: t**2, model2.coef_))) 12 elif i==2: 13 ans=statistics.mean(list(map(lambda t: t**2, (y-model3.predict(x_20)).tolist()))) 14 elif i==3: 15 ans=statistics.mean(list(map(lambda t: t**2, (y-model4.predict(x_20)).tolist()))) 16 ans+=sum(list(map(lambda t: t**2, model4.coef_))) 17 else: 18 #試しに真の分布のもののエラー関数を見てみる. 19 ans=statistics.mean(list(map(lambda t: t**2, (y-func(x).reshape(1,-1)[0]).tolist()))) 20 ans_lst.append(ans) 21 break 22 ans_lst.append(ans) 23 24""" 25[878.1943851888309, 26 6835.932288142904, 27 165.22430413762072, 28 1480.3156315725134, 29 660.6537337438299] 30"""

ans_lst=[878.1943851888309,
6829.205481962394,
165.22430413762072,
1472.468473432889,
660.6537337438299]
<- ridge項を入れる前.

こちら,最後をみると明らかに過学習しているmodel3が
最も損失関数が低いため良いモデルとなってしまいました.

そのため,k-交差検証を用いて,それぞれのモデルを評価して,
その値が小さいモデルを判断します.

python

1# generate models 2models=[] 3 4k_1=500 5# degree=1 6models.append(LinearRegression()) 7models.append(Ridge(alpha=k_1)) 8 9k_20=500 10# degree = 20 11models.append(LinearRegression()) 12models.append(Ridge(alpha=k_20)) 13base_x_20=PolynomialFeatures(degree=20,include_bias=False) 14x_20=base_x_20.fit_transform(x) 15 16# generate models 17models=[] 18 19# degree=1 20k_1=500 21models.append(LinearRegression()) 22models.append(Ridge(alpha=k_1)) 23 24# degree = 20 25k_20=500 26models.append(LinearRegression()) 27models.append(Ridge(alpha=k_20)) 28base_x_20=PolynomialFeatures(degree=20,include_bias=False) 29x_20=base_x_20.fit_transform(x) 30 31# evaluate model 32scores=[] 33for i in range(4): 34 if i < 2 : 35 scores.append(-np.mean(cross_val_score(models[i],x,y,scoring='neg_mean_squared_error',cv=10))) 36 else: 37 scores.append(-np.mean(cross_val_score(models[i],x_20,y,scoring='neg_mean_squared_error',cv=10))) 38# 本当はridgeの部分はそれを含めたscoreを算出したいです. 39 40""" 41scores=[1050.7385117716492, 7591.142086205172, 5966152468.751239, 2145.3345481477745] 42"""

この場合,models[0]を用いると良いとなりますが,結局最初のモデルを用いて
全てを訓練データとして得られたものを係数として答えを出せば良いでしょうか?
それとも,k-cross_validationで得られるそれぞれの係数を平均した方が良いのでしょうか?
こちらもご回答していただけると幸いです.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

MSEの算出にはsklearn.metrics.mean_squared_errorを使います。真値と予測値を引数に与えればMSEを返してくれます。

係数は(存在すれば)coef_アトリビュートでアクセスできます。リファレンスのAttributes
の欄を確認してみてください。たとえばRidgeであれば、

coef_ndarray of shape (n_features,) or (n_targets, n_features)
Weight vector(s).

intercept_float or ndarray of shape (n_targets,)
Independent term in decision function. Set to 0.0 if fit_intercept = False.

sklearn.linear_model.Ridge — scikit-learn 0.24.1 documentation

といった項目が用意されています。

交差検証については、最良とされたモデルを全データで学習させるのが無難なやり方です。


なお、これを損失関数とは言いません。単に結果を評価しているだけなので、「MSEを評価指標に用いて評価した」等と書きます。

もしかしたら、ほんとうに最適化の過程で計算される損失関数(最小化される目的関数)の値を取得したいのかもしれませんが、scikit-learnでは残念ながら取得できません。

投稿2021/04/21 08:21

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

unser

2021/04/21 09:06

ご回答いただきありがとうございます. このような関数を用意すると確かに,coefで参照できていることが確認できました. def model_conf(model,x): y=[model.intercept_ for _ in range(len(x))] for j in range(len(x)): for i in range(len(model.coef_)): y[j]+=model.coef_[i]*((x[j][0])**(i+1)) return y 確かに,損失関数というよりスコア関数の位置付けですね.ありがとうございます. また,Ridge回帰において,k-crossvalidationの評価に関してscoringをneg_mean_squared_errorから何かに変更する必要があると思うのですが,そちらの方法はご存知でしょうか.
hayataka2049

2021/04/21 11:41

>また,Ridge回帰において,k-crossvalidationの評価に関してscoringをneg_mean_squared_errorから何かに変更する必要があると思うのですが,そちらの方法はご存知でしょうか. 特にその必要はないと思います。というか、他のモデルと違う指標を使ってしまうと、比較で困ります。
unser

2021/04/21 13:47

なるほど. つまり 目的関数は罰則項を含めた形で用いるけれど, 評価する際の関数に関しては k-交差検証の場合は罰則項を含めずにやるということよろしいですか? また今回Ridgeによる罰則をないモデルも用意しましたが, 今後はメインでRidge回帰同士で比較する場合を主に考慮したいためRidgeの罰則項を含めた評価実装も教えていただけると幸いです...
hayataka2049

2021/04/21 14:36 編集

目的関数と評価指標は独立に選べます。 (というか、「異なる目的関数を用いるモデル同士とか、そもそも目的関数という考え方を積極的に持たないようなモデルにおいて、優劣を比較したい」とかのために、評価指標を使う訳ですが) Ridgeの罰則項を含めた評価をやる場合、 1.今回やっているのと同様に、罰則項のハイパーパラメータが異なる複数のRidgeモデルを作成する 2.GridSearchCVを使ってチューニングする 3.RidgeCVを使ってチューニングする 2が素直です。また、3はスマートかもしれません。 https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.RidgeCV.html
unser

2021/04/21 14:40

ありがとうございます. 確かに,独立に選べるべきですね! 確かに実用的にはGridSearchなどが良いですよね. ベイズ最適化などでも実装したいと考えているので,その時わからなければまたこのサイトにて質問いたします! ご丁寧にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問