衡量線性回歸法的指標 MSE,RMS,MAE以及評價回歸算法 R Square
衡量線性回歸法的指標
對於分類問題來說,我們將原始數據分成了訓練數據集和測試數據集兩部分,我們使用訓練數據集得到模型以后使用測試數據集進行測試然后和測試數據集自帶的真實的標簽進行對比,那么這樣一來,我們就得到了我們的分類准確度,使用這種分類准確度來衡量機器學習模型的好壞
那么對於線性回歸算法的好壞應該用什么來衡量呢
以簡單線性回歸算法來說,我們就是為了使損失函數盡可能的小,那么我們在使用的時候,實際上也是分成兩部分的,我們的盡可能小是對於訓練數據集來說的,實際上就是訓練集和預測出的結果的差值的平方的和

當訓練過程結束以后,我們將x_test帶入,可以得到每個所相應的預測值
很顯然,衡量標准可以是

不過,有個問題,在我們匯報這個標准的時候,這個衡量標准是個m相關的,在沒有確定測試數據集的整體一致時,這個標准是沒法說明的,因此我們需要對其進行一個1/m的,相當於使這個標准和樣本數是無關的

我們一般稱其為均方誤差MSE
但是這里又有一個問題,就是量綱的問題,使y的單位變成了平方,有的時候會帶來麻煩,這個時候我們就可以對上面的式子進行一個平方根處理

我們一般稱其為均方根誤差RMSE
這兩個區別在於對於量綱是否敏感,如果使用同樣量綱的話,RMSE的誤差會更加的明顯
還有一個就是平均絕對誤差MAE,很直接,其直接得出每組數據的距離,然后加在一起,在對總數進行平均,就得到了相應的誤差

那么在notebook中實現一下衡量回歸標准的好壞
那么調用真實的數據,加載好相應的庫
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
使用波士頓的房價,將數據存放在Boston中
boston = datasets.load_boston()
可以使用print來看看其中的內容是什么
print(boston.DESCR)
因為我么只使用簡單的線性回歸,所以只取一個特征
boston.feature_names

可知rm是第五個屬性,那么我們可以只是用第五列的數值,即只用房間數量這個特征
x = boston.data[:,5]
使x和y對應起來
x.shape

y = boston.target
y.shape

然后進行繪制,看看大概長什么樣
plt.scatter(x,y)
數據如下所示

從圖中可以看出來,在50的地方分布了一些點,這些點是一個上限點,即數據中的最大值,比如大於50的全部屬於50,對於這些點,顯然有可能不是真實的點
確認一下最大值是否為50
np.max(y)

可知確實為50,那么我們將其范圍改成小於50
x = x[y < 50.0]
y = y[y < 50.0]
然后繪制看看有什么差異
plt.scatter(x,y)
圖像如下

使用簡單線性回歸算法
首先進行引用,並將其分成四個值,種子設置為666
from model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(x,y,seed=666)
其中我們通過shape可以知道其樣本數量
x_train.shape
x_test.shape

然后我們使用向量化運算的方式
from SimpleLinearRegression import SimpleLinearRegression2
確定以后進行實例化,在進行fit操作進行訓練
reg = SimpleLinearRegression2()
reg.fit(x_train,y_train)

可以看看得到的a和b
reg.a_
reg.b_

簡單的繪制一下結果
plt.scatter(x,y)
plt.plot(x_train,reg.predict(x_train),color='r')
圖像如下

然后我們可以開始進行預測,使用predict這個函數將x_test引入,結果放入
y_predict
y_predict = reg.predict(x_test)
指標部分:
MSE
對差距進行的平方的和再除以樣本總數對於test來說
mse_test = np.sum((y_predict - y_test) ** 2) / len(y_test)
mse_test

RMSE
對MSE進行一個平方根運算
from math import sqrt
rmse_test = sqrt(mse_test)
rmse_test

MAE
實際預測出來的結果和真實值的差值的絕對值並求和再取平均
mae_test = np.sum(np.absolute(y_predict - y_test)) / len(y_test)
mae_test

我們寫入一個metrics.py文件,將對應的操作對應的函數寫在其中,三個函數的實現過程和notebook中是一樣的
代碼如下
import numpy as np
from math import sqrt
def accuracy_score(y_true, y_predict):
"""計算y_true和y_predict間的准確率"""
assert y_true.shape[0] == y_predict.shape[0], \
"the size of y_true must be equal to the size of y_predict"
return sum(y_true == y_predict) / len(y_true)
def mean_squared_error(y_true, y_predict):
"""計算y_true和y_predict間的MSE"""
assert len(y_true) == len(y_predict), \
"the size of y_true must be equal to the size of y_predict"
return np.sum((y_true - y_predict) ** 2) / len(y_true)
def root_mean_squared_error(y_true, y_predict):
"""計算y_true和y_predict間的RMSE"""
return sqrt(mean_squared_error(y_true, y_predict))
def mean_absolute_error(y_true, y_predict):
"""計算y_true和y_predict間的MAE"""
assert len(y_true) == len(y_predict), \
"the size of y_true must be equal to the size of y_predict"
return np.sum(np.absolute(y_true - y_predict)) / len(y_true)
def r2_score(y_ture, y_predict):
"""計算y_true和y_predict間的R Square"""
return 1 - mean_squared_error(y_ture, y_predict) / np.var(y_ture)
我們封裝好屬於我們自己的標准之后,我們也可以調用自己的標准
from metrics import mean_squared_error
from metrics import root_mean_squared_error
from metrics import mean_absolute_error
MSE
mean_squared_error(y_test,y_predict)

RMSE
root_mean_squared_error(y_test,y_predict)

MAE
mean_absolute_error(y_test,y_predict)

sklearn中的MSE,MAE
在sklearn中沒有RMSE的方法的
因此只能使用其他兩個,包裝方式相同
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
對其使用
MSE
mean_squared_error(y_test,y_predict)

MAE
mean_absolute_error(y_test,y_predict)

RSME和MAE的比較
他們的量綱是一樣的,都對應着原始數據,但是大部分情況下,RMSE比MAE大,從公式可以發現,RMSE是有一個放大差距的一個趨勢,因此,從某種程度上,是MSE小更好一些
從我個人來看,若是數據基本相同,從公式可以發現RMSE是除以的根號下的m,而MAE是除以m,這個地方就已經導致差距不小了,不知道這種理解對還是不對
評價回歸算法 R Square
上面介紹了三種指標,但是這些還是有問題的,像是分類的准確度,1最好,0最壞,很直觀,但是上面的指標就沒法很直觀的判斷,種類不同,沒法直接對比,這算是一個局限性
解決方法,使用R Square
簡單來說,就是讓1減去預測結果減去真值的差距的平方的和再除以均值減去真值的平方的和

這個R²的意義是什么呢
對於分子來說,這樣的操作可以使用我們的模型預測產生的錯誤,對於分母來說,是使用y=y*(y的均值)預測產生的錯誤,這也可以當成一個模型,其與x是無關的,是一個很朴素的預測結果,稱其為Baseline Model
基於此,我們可以認為,我們使用自己的模型和基礎的模型來預測產生的錯誤,在用1減去兩者相除以后,相當於衡量了我們的模型擬合住的數據的地方,即衡量了我們的式子沒有產生錯誤的指標
這樣下來,我們可以確定
1.R²是小於等於1的
2.R²越大越好。當我們的預測模型不犯任何錯誤的時候,R²會得到最大值1
3.當我們的模型等於基准模型的時候,R²為0
4.和准確度不一樣,存在小於0的情況,如果R²小於0,這就說明我們學習到的模型還不如一個基准模型,這個時候,很可能是我們的模型不存在任何的線性關系,這個時候可能需要換別的非線性的算法了
我們可以發現式子是可以變化成

這就可以變成

這樣計算會更加的方便直觀
上式可以書寫成
1 - mean_squared_error(y_test,y_predict) / np.var(y_test)

在metrics.py中已經寫好了R Square,我們直接引用使用即可
from metrics import r2_score
直接就可以調用這個函數,就可以得出結果
r2_score(y_test,y_predict)

在sklearn中一樣有R Square,使用方法是一樣的
from sklearn.metrics import r2_score
r2_score(y_test,y_predict)

我們可以在其中直接添加上計算准確度的函數score
在SimpleLinearRegression中添加上
from metrics import r2_score
def r2_score(y_ture, y_predict):
"""計算y_true和y_predict間的R Square"""
return 1 - mean_squared_error(y_ture, y_predict) / np.var(y_ture)
直接使用即可
reg.score(x_test,y_test)


