先來看一組代碼:
import numpy as np
rng = np.random.RandomState(42)
X = rng.randn(100, 80)
y = rng.randn(100)
cross_val_score(LR(), X, y, cv=5, scoring='r2')
運作結果
array([-179.12952605, -5.692624 , -15.61747513, -78.68042858,
-59.5311006 ])
sklearn真的是設定了太多障礙,均方誤差是負的,R2也是負的,這個名字裡都帶平方了,居然是負的,無論如何,再來看看的計算公式:
R 2 = 1 − ∑ i = 0 m ( y i − y ^ i ) 2 ∑ i = 0 m ( y i − y ˉ i ) 2 = 1 − R S S ∑ i = 0 m ( y i − y ˉ i ) 2 R^2=1-\large{\frac{\sum_{i=0}^m(y_i-\hat{y}_i)^2}{\sum_{i=0}^m(y_i-\bar{y}_i)^2}}\small=1-\large{\frac{RSS}{\sum_{i=0}^m(y_i-\bar{y}_i)^2}} R2=1−∑i=0m(yi−yˉi)2∑i=0m(yi−y^i)2=1−∑i=0m(yi−yˉi)2RSS
第一次學習機器器學習或者統計學的,可能會感覺沒什麼問題了, 是1減一個數,後面的部分隻要大于1的話完全可以小于0。但是學過機器器學習,尤其是在統計學上有基礎的可能會坐不住了:這不對啊!
一直以來,衆多的機器學習教材中都有這樣的解讀:除了RSS之外,還有平方和ESS(Explained Sum of Squares,也叫做SSR回歸平方和)以及總離差平方和TSS(Total Sum of Squares,也叫做SST總離差平方和)。
平方和ESS定義了預測值和樣本均值之間的差異,而總離差平方和定義了真實值和樣本均值之間的差異(就是R2中的分母),兩個名額分别寫作:
T S S = ∑ i = 0 m ( y i − y ˉ i ) 2 TSS=\sum_{i=0}^m(y_i-\bar{y}_i)^2 TSS=i=0∑m(yi−yˉi)2
E S S = ∑ i = 0 m ( y ^ i − y ˉ i ) 2 ESS=\sum_{i=0}^m(\hat{y}_i-\bar{y}_i)^2 ESS=i=0∑m(y^i−yˉi)2
而公式:
T S S = R S S + E S S TSS=RSS+ESS TSS=RSS+ESS
看R2的公式,如果帶入TSS和ESS,就有:
R 2 = 1 − R S S T S S = T S S − R S S T S S = E S S T S S R^2=1-\frac{RSS}{TSS}=\frac{TSS-RSS}{TSS}=\frac{ESS}{TSS} R2=1−TSSRSS=TSSTSS−RSS=TSSESS
而ESS和TSS都帶平方,是以必然都是正數,R^2怎麼可能是負的呢?
因為,公式TSS = RSS + ESS不是永遠成立,如何證明:
T S S = ∑ i = 0 m ( y i − y ˉ i ) 2 = ∑ i = 0 m ( y i − y ^ i + y ^ i − y ˉ i ) 2 = ∑ i = 0 m ( y i − y ^ i ) 2 + ∑ i = 0 m ( y ^ i − y ˉ i ) 2 + 2 ∑ i = 0 m ( y i − y ^ i ) ( y ^ i − y ˉ i ) = R S S + E S S + 2 ∑ i = 0 m ( y i − y ^ i ) ( y ^ i − y ˉ i ) TSS=\sum_{i=0}^m(y_i-\bar{y}_i)^2 \\ =\sum_{i=0}^m(y_i-\hat{y}_i+\hat{y}_i-\bar{y}_i)^2 \\ =\sum_{i=0}^m(y_i-\hat{y}_i)^2+\sum_{i=0}^m(\hat{y}_i-\bar{y}_i)^2+2\sum_{i=0}^m(y_i-\hat{y}_i)(\hat{y}_i-\bar{y}_i)\\ =RSS+ESS+2\sum_{i=0}^m(y_i-\hat{y}_i)(\hat{y}_i-\bar{y}_i) TSS=i=0∑m(yi−yˉi)2=i=0∑m(yi−y^i+y^i−yˉi)2=i=0∑m(yi−y^i)2+i=0∑m(y^i−yˉi)2+2i=0∑m(yi−y^i)(y^i−yˉi)=RSS+ESS+2i=0∑m(yi−y^i)(y^i−yˉi)
兩邊同時除以TSS,則有:
1 = R S S T S S + E S S T S S + 2 ∑ i = 0 m ( y i − y ^ i ) ( y ^ i − y ˉ i ) T S S 1=\frac{RSS}{TSS}+\frac{ESS}{TSS}+\frac{2\sum_{i=0}^m(y_i-\hat{y}_i)(\hat{y}_i-\bar{y}_i)}{TSS} 1=TSSRSS+TSSESS+TSS2∑i=0m(yi−y^i)(y^i−yˉi)
1 − R S S T S S = E S S + 2 ∑ i = 0 m ( y i − y ^ i ) ( y ^ i − y ˉ i ) T S S 1-\frac{RSS}{TSS}=\frac{ESS+2\sum_{i=0}^m(y_i-\hat{y}_i)(\hat{y}_i-\bar{y}_i)}{TSS} 1−TSSRSS=TSSESS+2∑i=0m(yi−y^i)(y^i−yˉi)
R 2 = E S S + 2 ∑ i = 0 m ( y i − y ^ i ) ( y ^ i − y ˉ i ) T S S R^2=\frac{ESS+2\sum_{i=0}^m(y_i-\hat{y}_i)(\hat{y}_i-\bar{y}_i)}{TSS} R2=TSSESS+2∑i=0m(yi−y^i)(y^i−yˉi)
許多教材和部落格中讓 2 ∑ i = 0 m ( y i − y ^ i ) ( y ^ i − y ˉ i ) 2\sum_{i=0}^m(y_i-\hat{y}_i)(\hat{y}_i-\bar{y}_i) 2∑i=0m(yi−y^i)(y^i−yˉi)這個式子為0,公式TSS=RSS+ESS自然就成立了,但要讓這個式子成立是有條件的。現在有了這個式子的存在, R2就可以是一個負數了。隻要 ( y i − y ^ i ) (y_i-\hat{y}_i) (yi−y^i)衡量的是真實值到預測值的距離,而 ( y ^ i − y ˉ i ) (\hat{y}_i-\bar{y}_i) (y^i−yˉi)衡量的是預測值到均值的距離,隻要這兩部分的符号不同,式子 2 ∑ i = 0 m ( y i − y ^ i ) ( y ^ i − y ˉ i ) 2\sum_{i=0}^m(y_i-\hat{y}_i)(\hat{y}_i-\bar{y}_i) 2∑i=0m(yi−y^i)(y^i−yˉi)就有可能為負,而R^2也就有可能為負。
看下面這張圖,藍色的橫線是均值線 y ˉ \bar{y} yˉ,橙色的線是模型 y ^ \hat{y} y^,藍色的點是樣本點。對于 x i x_i xi,真實标簽減預測值的值 ( y i − y ^ i ) (y_i-\hat{y}_i) (yi−y^i)為正,但我們的預測值減均值的值 ( y ^ i − y ˉ i ) (\hat{y}_i-\bar{y}_i) (y^i−yˉi)卻是一個負數。
這說明,資料本身的均值,比資料的拟合模型本身更接近資料的真實值,模型就是廢的,完全沒有作用,類似于分類模型中的分類準确率為50%,不如瞎猜。
就是說,當R2的顯示為負,證明模型對資料的拟合非常糟糕,模型完全不能使用。所有,一個負的R2是合理的。當然,現實應用中,如果發現線性回歸模型出現負的R2,不代表就要接受:首先,檢查模組化過程和資料處理過程是否正确,也許原始資料處理不當,也許模組化過程存在bug。如果是內建模型的回歸,檢查弱評估器的數量是否不足,随機森林、提升樹這些模型在隻有兩三棵樹的時候很容易出現負的R2。如果檢查了所有的代碼,也确定了預處理沒有問題,但R2還是負的,說明線性回歸模型不适合此資料,需要嘗試其他算法。