sklearn---線性回歸


1. 普通線性回歸 Linear Regression

(1)目標:

class sklearn.linear_model.LinearRegression (fit_intercept=True, normalize=False, copy_X=True, n_jobs=None)  

 (2)參數:

(3)sklearn的三個坑

【1】均方誤差為負

  我們在決策樹和隨機森林中都提到過,雖然均方誤差永遠為正,但是sklearn中的參數scoring下,均方誤差作為評 判標准時,卻是計算”負均方誤差“(neg_mean_squared_error)。這是因為sklearn在計算模型評估指標的時候, 會考慮指標本身的性質,均方誤差本身是一種誤差,所以被sklearn划分為模型的一種損失(loss)。在sklearn當中, 所有的損失都使用負數表示,因此均方誤差也被顯示為負數了。真正的均方誤差MSE的數值,其實就是 neg_mean_squared_error去掉負號的數字。
  除了MSE,我們還有與MSE類似的MAE(Mean absolute error,絕對均值誤差)

  其表達的概念與均方誤差完全一致,不過在真實標簽和預測值之間的差異外我們使用的是L1范式(絕對值)。現實 使用中,MSE和MAE選一個來使用就好了。在sklearn當中,我們使用命令from sklearn.metrics import mean_absolute_error來調用MAE,同時,我們也可以使用交叉驗證中的scoring = "neg_mean_absolute_error",以此在交叉驗證時調用MAE。

【2】相同的評估指標不同的結果

  來看這張圖,其中紅色線是我們的真實標簽,而藍色線是我們的擬合模型。這是一種比較極端,但的確可能發生的 情況。這張圖像上,前半部分的擬合非常成功,看上去我們的真實標簽和我們的預測結果幾乎重合,但后半部分的擬合卻非常糟糕,模型向着與真實標簽完全相反的方向去了。對於這樣的一個擬合模型,如果我們使用MSE來對它 進行判斷,它的MSE會很小,因為大部分樣本其實都被完美擬合了,少數樣本的真實值和預測值的巨大差異在被均分到每個樣本上之后,MSE就會很小。但這樣的擬合結果必然不是一個好結果,因為一旦我的新樣本是處於擬合曲線的后半段的,我的預測結果必然會有巨大的偏差,而這不是我們希望看到的。所以,我們希望找到新的指標,除了判斷預測的數值是否正確之外,還能夠判斷我們的模型是否擬合了足夠多的,數值之外的信息。

  在我們學習降維算法PCA的時候,我們提到我們使用方差來衡量數據上的信息量。如果方差越大,代表數據上的信 息量越多,而這個信息量不僅包括了數值的大小,還包括了我們希望模型捕捉的那些規律。為了衡量模型對數據上 的信息量的捕捉,我們定義了 和可解釋性方差分數(explained_variance_score,EVS)來幫助我們

  其中y是我們的真實標簽, y^是我們的預測結果, y-是我們的均值,Var表示方差。方差的本質是任意一個y值和樣本 均值的差異,差異越大,這些值所帶的信息越多。在R2和EVS中,分子是真實值和預測值之差的差值,也就是我們的模型沒有捕獲到的信息總量,分母是真實標簽所帶的信息量,所以兩者都衡量1 - 我們的模型沒有捕獲到的信息量占真實標簽中所帶的信息量的比例,所以,兩者都是越接近1越好.

   R 2可以使用三種方式來調用,一種是直接從metrics中導入r2_score,輸入預測值和真實值后打分。第二種是直接從線性回歸LinearRegression的接口score來進行調用。第三種是在交叉驗證中,輸入"r2"來調用。EVS有兩種調用方法,可以從metrics中導入,也可以在交叉驗證中輸入”explained_variance“來調用。

  在我們的分類模型的評價指標當中,我們進行的是一種 if a == b的對比,這種判斷和if b == a其實完全是一種概念,所以我們在進行模型評估的時候,從未踩到我們現在在的這個坑里。然而看R2的計算公式,R2明顯和分類模型的指標中的accuracy或者precision不一樣,R2涉及到的計算中對預測值和真實值有極大的區別,必須是預測值在分子,真實值在分母,所以我們在調用metrcis模塊中的模型評估指標的時候,必須要檢查清楚,指標的參數中,究竟是要求我們先輸入真實值還是先輸入預測值。

  我們觀察到,雖然我們在加利福尼亞房子價值數據集上的MSE相當小,但我們的R2卻不高這證明我們的模型比較好地擬合了數據的數值,卻沒有能正確擬合數據的分布。讓我們與繪圖來看看,究竟是不是這樣一回事。我們可以繪制一張圖上的兩條曲線,一條曲線是我們的真實標簽Ytest,另一條曲線是我們的預測結果yhat,兩條曲線的交疊越多,我們的模型擬合就越好。

【3】負的R2

 

 

一直以來,眾多的機器學習教材中都有這樣的解讀:
除了RSS之外,我們還有解釋平方和ESS(Explained Sum of Squares,也叫做SSR回歸平方和)以及總離差平方和 TSS(Total Sum of Squares,也叫做SST總離差平方和)。解釋平方和ESS定義了我們的預測值和樣本均值之間的 差異,而總離差平方和定義了真實值和樣本均值之間的差異,兩個指標分別寫作:

而我們有公式: TSS = RSS + ESS

看我們的R2的公式,如果帶入我們的TSS和ESS,那就有

而ESS和TSS都帶平方,所以必然都是正數,那 怎么可能是負的呢?
好了,顛覆認知的時刻到來了——公式TSS = RSS + ESS不是永遠成立的!就算所有的教材和許多博客里都理所當然這樣寫了大家也請抱着懷疑精神研究一下,你很快就會發現很多新世界。我們來看一看我們是如何證明(1)這個公 式的

  看下面這張圖,藍色的橫線是我們的均值線y-,橙色的線是我們的模型y^,藍色的點是我們的樣本點。現在對於xi來說,我們的真實標簽減預測值的值(yi-yi^)為正,但我們的預測值(yi^-y-)卻是一個負數,這說明,數據本身的均值,比我們對數據的擬合模型本身更接近數據的真實值,那我們的模型就是廢的,完全沒有作用,類似於分類模 型中的分類准確率為50%,不如瞎猜.

   也就是說,當我們的R2顯示為負的時候,這證明我們的模型對我們的數據的擬合非常糟糕,模型完全不能使用。 所有,一個負的R2是合理的。當然了,現實應用中,如果你發現你的線性回歸模型出現了負的 ,不代表你就要接受他了,首先檢查你的建模過程和數據處理過程是否正確,也許你已經傷害了數據本身,也許你的建模過程是存在bug的。如果你檢查了所有的代碼,也確定了你的預處理沒有問題,但你的R2也還是負的,那這就證明,線性回歸模型不適合你的數據,試試看其他的算法吧.

 

(4)舉例

def linear_regression(x_train,y_train,x_test):
    model = LR()
    reg = model.fit(x_train,y_train)
    pred = reg.predict(x_test)
#     print(reg.coef_)
    print(pred)

 

2. 嶺回歸Ridge

(1)

(2)舉例:

先找到最好的alpha,然后將alpha帶入線性模型中訓練

def find_min_alpha(x_train, y_train):
    alphas = np.logspace(-2, 3, 200)
    # print(alphas)
    test_scores = []
    alpha_score = []
    for alpha in alphas:
        clf = Ridge(alpha)
        test_score = -cross_validation.cross_val_score(clf, x_train, y_train, cv=10, scoring='neg_mean_squared_error')
        test_scores.append(np.mean(test_score))
        alpha_score.append([alpha, np.mean(test_score)])
    print("final test score:")
#     print(test_scores)
#     print(alpha_score)

    sorted_alpha = sorted(alpha_score, key=lambda x: x[1], reverse=False)
#     print(sorted_alpha)
    alpha = sorted_alpha[0][0]
    print("best alpha:" + str(alpha))
    return alpha

 

def linear_regression_with_Ridge(x_train,y_train,x_test,alpha):
    clf = Ridge(alpha=alpha)
    scores = -cross_validation.cross_val_score(clf,x_train,y_train,
             cv=10,scoring='neg_mean_squared_error')
    print('scores',scores)
    print('mean score',scores.mean())
    clf.fit(x_train,y_train)
#     print(clf.coef_)
#     print(clf.intercept_)
    
    ans = clf.predict(x_test)
#     print('ans',ans.shape)

  

以Ridge線性回歸為基回歸器的隨機森林

def create_model(x_train,y_train,alpha):
    print('begin to train')
    model = Ridge(alpha=alpha)
    clf1 = ensemble.BaggingRegressor(model,n_jobs=1,n_estimators=900)
    scores = -cross_validation.cross_val_score(model,x_train,y_train,cv=10,scoring='neg_mean_squared_error')
    print('========================')
    print('Scores:')
    print(scores.mean())
    clf1.fit(x_train,y_train)
    print('Finish')
    return clf1

  

 

3. LASSO

 

4. 彈性網

 

5. 最小角度回歸

 

6.正交匹配追蹤

 

7.貝葉斯回歸

 

8.其他回歸

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM