2017-05-29 38 views

回答

3

存在解決方法,但它不是本質上sklearn框架。

如果你有一個比例目標變量(取值範圍0-1)你遇到兩個基本困難scikit學習:

  • 分類器(如邏輯迴歸)處理類的標籤,因爲只有目標變量。作爲一種解決方法,您可以簡單地將您的概率限定爲0/1並將它們解釋爲類標籤,但是會丟失大量信息。
  • 迴歸模型(如線性迴歸)不會限制目標變量。您可以根據比例數據對它們進行訓練,但不能保證未見數據的輸出將限制在0/1範圍內。但是,在這種情況下,有一個強大的解決方法(見下文)。

有不同的方法來數學表達邏輯迴歸。其中之一是generalized linear model,它基本上將logistic迴歸定義爲logit轉換概率的正態線性迴歸。通常,這種方法需要複雜的數學優化,因爲概率是未知的,需要與迴歸係數一起進行估計。

然而就你而言,概率是已知的。這意味着您可以簡單地將它們轉換爲y = p/(1 - p)。現在它們覆蓋從-oooo的整個範圍,並且可以用作LinearRegression模型[*]的目標變量。當然,模型輸出需要再次變換以產生概率p = 1/(exp(-y) + 1)

import numpy as np 
from sklearn.linear_model import LinearRegression 


class LogitRegression(LinearRegression): 

    def fit(self, x, p): 
     p = np.asarray(p) 
     y = np.log(p/(1 - p)) 
     return super().fit(x, y) 

    def predict(self, x): 
     y = super().predict(x) 
     return 1/(np.exp(-y) + 1) 


if __name__ == '__main__': 
    # generate example data 
    np.random.seed(42) 
    n = 100 
    x = np.random.randn(n).reshape(-1, 1) 
    noise = 0.1 * np.random.randn(n).reshape(-1, 1) 
    p = np.tanh(x + noise)/2 + 0.5 

    model = LogitRegression() 
    model.fit(x, p) 

    print(model.predict([[-10], [0.0], [1]])) 
    # [[ 2.06115362e-09] 
    # [ 5.00000000e-01] 
    # [ 8.80797078e-01]] 
  • 也有許多其他選擇。一些非線性迴歸模型可以在0-1範圍內自然工作。例如Random Forest Regressors將永遠不會超過他們接受培訓的目標變量的範圍。簡單地把概率放在裏面,你會得到概率。具有適當的輸出激活函數的神經網絡(我猜想是tanh)也可以很好地處理概率,但是如果你想使用這些網絡,那麼存在比sklearn更專業的庫。

[*]你可以在事實上塞任何linear迴歸模型,可以使該方法更強大,但隨後不再是完全等同於邏輯迴歸。

+0

能否請您解釋一下應該對其中包含的0或1的概率訓練/測試數據做什麼?在這些情況下,y是-inf和div。 –

+0

@JakeDrew最簡單的解決方案是將* 0 *替換爲* e *和* 1 *替換爲* 1-e *,其中* e *是一個非常小的數字。 (你也可以用'p = p * e + 0.5 * e'來清理概率)。我猜'e = 1e-16'會運作良好。 – kazemakase

+0

感謝您的快速響應!我正在嘗試完全按照您之前的建議。我發現對於範圍p =(0,1),使用.009和.991表示0和1的值產生10倍cv MAE = 0.059或5.9%。在相同的數據上使用p = 9e-16可將MAE驅動至0.2266或22.6%。 e的精度似乎對平均絕對誤差有巨大的影響。當y = np.log(p /(1-p))和p = 0.991時,則y = 6.9。當p = 9e-16時,y = 36.7。也許我對我自己的數據集過度合適? –

相關問題