11

質問

r2_scorescikit-learn の関数と、ウィキペディアで説明されている決定係数の式に大きな違いがあるのはなぜですか? どれが正しいですか?


環境

私は線形モデルと二次モデルを予測するために Python 3.5 を使用しています。r2_scoreただし、テスト中、メトリックscikit-learnとウィキペディアで提供される計算の間には顕著な違いがあります。


コード

上記のリンク先のウィキペディア ページの例を計算するコードを参照としてここに提供します。

sklearn.metrics インポート r2_score から
numpy をインポート

y = [1, 2, 3, 4, 5]
f = [1.9、3.7、5.8、8.0、9.6]

# numpy 配列に変換し、単精度エラーを回避するために倍精度を確保します
観測 = numpy.array(y, dtype=numpy.float64)
予測 = numpy.array(f, dtype=numpy.float64)

scipy_value = r2_score(観察、予測)

>>> scipy_value:

明らかなように、Wikipedia の参照値が であるのに対し、scipy計算値はです。-3.86999999999999920.998

ありがとうございました!

更新:これは、scikit-learn で R^2 がどのように計算されるかについてのこの質問とは異なります。私が理解しようとしているのは、両方の結果の不一致であるためです。その質問は、scikit で使用されている数式はウィキペディアのものと同じであり、異なる値になるべきではないと述べています。

更新 #2:ウィキペディアの記事の例を読み間違えたことが判明しました。以下の回答とコメントは、私が提供する例は、例の (x, y) 値の線形の最小二乗法であることを示しています。それについては、ウィキペディアの記事の答えが正しいです。そのために提供される R^2 値は 0.998 です。両方のベクトル間の R^2 については、scikit の答えも正しいです。助けてくれてどうもありがとう!

4

5 に答える 5

10

あなたはウィキペディアを誤解していると思います。ウィキペディアの例には次のように記載されていませ

y=[1,2,3,4,5]
f=[1.9, 3.7, 5.8, 8.0, 9.6]
R^2 = 0.998

代わりにR^2、線形最小二乗法がデータに適合することを示しています。

x=[1,2,3,4,5]
y=[1.9, 3.7, 5.8, 8.0, 9.6]

に等しい0.998

np.linalg.lstsq最初に最小二乗適合を見つけるために使用し、両方の方法を使用して両方R^2の 0.998 を見つける次のスクリプトを検討してください。

import numpy as np
from sklearn.metrics import r2_score

x=np.arange(1,6,1)
y=np.array([1.9, 3.7, 5.8, 8.0, 9.6])

A=np.vstack([x, np.ones(len(x))]).T

# Use numpy's least squares function
m, c = np.linalg.lstsq(A, y)[0]

print m,c
# 1.97 -0.11

# Define the values of our least squares fit
f=m*x+c

print f
# [ 1.86  3.83  5.8   7.77  9.74]

# Calculate R^2 explicitly
yminusf2=(y-f)**2
sserr=sum(yminusf2)
mean=float(sum(y))/float(len(y))
yminusmean2=(y-mean)**2
sstot=sum(yminusmean2)
R2=1.-(sserr/sstot)

print R2
# 0.99766066838

# Use scikit
print r2_score(y,f)
# 0.99766066838

r2_score(y,f) == R2
# True
于 2015-10-30T11:20:47.473 に答える
8

参照された質問は正しいです。残差平方和と総平方和の計算を行うと、sklearn と同じ値が得られます。

In [85]: import numpy as np

In [86]: y = [1,2,3,4,5]

In [87]: f = [1.9, 3.7, 5.8, 8.0, 9.6]

In [88]: SSres = sum(map(lambda x: (x[0]-x[1])**2, zip(y, f)))

In [89]: SStot = sum([(x-np.mean(y))**2 for x in y])

In [90]: SSres, SStot
Out[90]: (48.699999999999996, 10.0)

In [91]: 1-(SSres/SStot)
Out[91]: -3.8699999999999992

負の値の背後にある考え方は、毎回平均を予測していれば (r2 = 0 に相当)、実際の値により近くなっていたということです。

于 2015-10-30T03:23:08.357 に答える
0

どちらも正しいです。問題は、scikit Learn が R2 の式をデータに直接使用することです。

y = [1, 2, 3, 4, 5]

f = [1.9、3.7、5.8、8.0、9.6]

Scikitは、yが真の値であり、fがyの予測であることを考慮して、SSRとSSTを計算します。

ウィキペディアでは y を特徴配列 (x) として使用し、f は予測する必要がある人 (y) です。したがって、f_pred = 1.97y + 0.11 になった回帰があります。これで、f の真の値と f の f_pred が得られました。R2 はそれらの間で計算されます。

y = [1, 2, 3, 4, 5]

f = [1.9、3.7、5.8、8.0、9.6]

f_pred = [1.86、3.83、5.8、7.77、9.74]

f および f_pred データを使用して式 (1- SSR/SST) を使用する場合:

SSR = SUM[(f-fp_pred)^2] = SUM[0.0016, 0.0169, 0.0529, 0.0196, 0.091] = 0.091

SST = SUM[(f-AVE(f))^2] = SUM[15.21, 4.41, 4.84, 14.44, 38.9] = 38.9

R2 = (1-0.091/38.9) = 0.998

scikit Learn の負の R2 は、モデルが観測されたトレーニング データの平均よりも悪いことを意味します。負の R2 は、特にテスト データで発生します。これは、テスト データが適合モデリングに参加していないためです。scikit Learn で負の R2 値がある場合、True 値と Pred 値の間の線形回帰の R2 を使用して、R2 がゼロに近くなります。

于 2020-12-29T15:08:43.983 に答える