有預測比例的標準方法,如邏輯迴歸(無閾值)和貝塔迴歸。目前已經討論一下:當目標變量是一個比例時如何使用sklearn
http://scikit-learn-general.narkive.com/lLVQGzyl/beta-regression
如果sklearn
框架內,存在一個變通我不能告訴。
有預測比例的標準方法,如邏輯迴歸(無閾值)和貝塔迴歸。目前已經討論一下:當目標變量是一個比例時如何使用sklearn
http://scikit-learn-general.narkive.com/lLVQGzyl/beta-regression
如果sklearn
框架內,存在一個變通我不能告訴。
存在解決方法,但它不是本質上內sklearn
框架。
如果你有一個比例目標變量(取值範圍0-1)你遇到兩個基本困難scikit學習:
有不同的方法來數學表達邏輯迴歸。其中之一是generalized linear model,它基本上將logistic迴歸定義爲logit轉換概率的正態線性迴歸。通常,這種方法需要複雜的數學優化,因爲概率是未知的,需要與迴歸係數一起進行估計。
然而就你而言,概率是已知的。這意味着您可以簡單地將它們轉換爲y = p/(1 - p)
。現在它們覆蓋從-oo
到oo
的整個範圍,並且可以用作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]]
tanh
)也可以很好地處理概率,但是如果你想使用這些網絡,那麼存在比sklearn更專業的庫。[*]你可以在事實上塞任何linear迴歸模型,可以使該方法更強大,但隨後不再是完全等同於邏輯迴歸。
能否請您解釋一下應該對其中包含的0或1的概率訓練/測試數據做什麼?在這些情況下,y是-inf和div。 –
@JakeDrew最簡單的解決方案是將* 0 *替換爲* e *和* 1 *替換爲* 1-e *,其中* e *是一個非常小的數字。 (你也可以用'p = p * e + 0.5 * e'來清理概率)。我猜'e = 1e-16'會運作良好。 – kazemakase
感謝您的快速響應!我正在嘗試完全按照您之前的建議。我發現對於範圍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。也許我對我自己的數據集過度合適? –