単純な線形モデルを実行しています。私が持っています
fire = load_data()
regr = linear_model.LinearRegression()
scores = cross_validation.cross_val_score(regr, fire.data, fire.target, cv=10, scoring='r2')
print scores
これは
[ 0.00000000e+00 0.00000000e+00 -8.27299054e+02 -5.80431382e+00
-1.04444147e-01 -1.19367785e+00 -1.24843536e+00 -3.39950443e-01
1.95018287e-02 -9.73940970e-02]
これはどのようにして可能ですか?組み込みの糖尿病データを使用して同じことを行うと、完全に正常に機能しますが、私のデータでは、これらの不合理な結果が返されます。私は何か間違ったことをした?
r^2
が負であってはならない理由はありません(名前に^2
があるにもかかわらず)。これは doc にも記載されています。 r^2
は、モデルの近似(線形回帰のコンテキストでは、たとえば次数1(アフィン)のモデル)と次数0(定数を近似する)のモデルの比較として、両方を最小化することで確認できます。二乗損失。二乗誤差を最小化する定数が平均です。除外されたデータを使用して相互検証を行っているため、テストセットの平均がトレーニングセットの平均と大きく異なる場合があります。これだけでは、テストデータの平均を予測するだけの場合と比較して、予測ではるかに高い二乗誤差が発生する可能性があり、負のr^2
スコアになります。
最悪の場合、データがターゲットをまったく説明しない場合、これらのスコアは非常に強く否定的になる可能性があります。試す
import numpy as np
rng = np.random.RandomState(42)
X = rng.randn(100, 80)
y = rng.randn(100) # y has nothing to do with X whatsoever
from sklearn.linear_model import LinearRegression
from sklearn.cross_validation import cross_val_score
scores = cross_val_score(LinearRegression(), X, y, cv=5, scoring='r2')
これは、負のr^2
値になるはずです。
In [23]: scores
Out[23]:
array([-240.17927358, -5.51819556, -14.06815196, -67.87003867,
-64.14367035])
ここで重要な問題は、線形モデルがデータ内で何も検出しないという事実に起因するのか、それともデータの前処理で修正される可能性のある何かに起因するのかということです。列を平均0と分散1にスケーリングしてみましたか?これは、sklearn.preprocessing.StandardScaler
を使用して行うことができます。実際、StandardScaler
とLinearRegression
をsklearn.pipeline.Pipeline
を使用してパイプラインに連結することにより、新しい推定量を作成する必要があります。次に、リッジ回帰を試してみるとよいでしょう。
_R^2
_が負である可能性があるからといって、それがそうである必要はありません。
可能性1:コードのバグ
よく確認する必要がある一般的なバグは、パラメーターを正しく渡していることです。
_r2_score(y_true, y_pred) # Correct!
r2_score(y_pred, y_true) # Incorrect!!!!
_
可能性2:小さなデータセット
負のR ^ 2を取得している場合は、過剰適合をチェックすることもできます。 cross_validation.cross_val_score()
は入力をランダムにシャッフルしないので、サンプルが誤って(たとえば日付で)並べ替えられた場合、他のフォールドを予測しないモデルを各フォールドに構築する可能性があることに注意してください。
特徴の数を減らし、サンプルの数を増やし、折りたたみの数を減らしてみてください(_cross_validation
_を使用している場合)。ここには公式のルールはありませんが、_m x n
_データセット(m
はサンプルの数、n
は特徴の数)は次のような形になります。
_m > n^2
_
フォールド数としてf
を使用して交差検証を使用する場合は、
_m/f > n^2
_
R²= 1-RSS /TSS。RSSは残差平方和∑(y-f(x))²で、TSSは平方和square(y-mean(y))²です。 R²≥-1の場合、RSS/TSS≤2である必要がありますが、これが当てはまらないモデルとデータセットを構築するのは簡単です。
>>> x = np.arange(50, dtype=float)
>>> y = x
>>> def f(x): return -100
...
>>> rss = np.sum((y - f(x)) ** 2)
>>> tss = np.sum((y - y.mean()) ** 2)
>>> 1 - rss / tss
-74.430972388955581
負の回帰r ^ 2スコアを取得している場合は、モデルをフィッティング/スコアリングする前に、データセットから一意の識別子(「id」や「rownum」など)を必ず削除してください。簡単なチェックですが、頭痛の時間を節約できます。