2016-02-15 169 views
2

我正在尝试SciKit学习。我想我会尝试一个加权logistic回归,但是当使用sample_weight参数初始化它时,我从sklearn的LogisticRegression对象中获得无意义的预测。sklearn LogisticRegression predict_proba()在使用sample_weight参数时给出了不正确的预测

这是一个玩具的例子,它演示了这个问题。我建立了一个非常简单的数据集,包含一个功能和一个二进制目标输出。

feat target weight 
A  0  1 
A  0  1 
A  1  1 
A  1  1 
B  0  1 
B  0  1 
B  0  1 
B  1  W 

因此,任何明智的回归应该预测,当feat=A,有成功的概率0.5。 概率时feat=B取决于重量W

  • 如果W=1,那么它看起来像有一个0.25的成功机会
  • 如果W=3,这平衡了三个0 S,它看起来就像有0.5的成功几率
  • 如果W=9,现在有效九个1 s和三个0 s,所以有0.75的成功几率。

[R加权回归给出正确的预测:

test <- function(final_weight) { 
    feat <- c('A','A','A','A','B','B','B','B') 
    target <- c(0, 0, 1, 1, 0, 0, 0, 1) 
    weight <- c(1, 1, 1, 1, 1, 1, 1, final_weight) 

    df = data.frame(feat, target, weight) 

    m = glm(target ~ feat, data=df, family='binomial', weights=weight) 
    predict(m, type='response') 
} 

test(1) 
# 1 2 3 4 5 6 7 8 
#0.50 0.50 0.50 0.50 0.25 0.25 0.25 0.25 
test(3) 
# 1 2 3 4 5 6 7 8 
#0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 
test(9) 
# 1 2 3 4 5 6 7 8 
#0.50 0.50 0.50 0.50 0.75 0.75 0.75 0.75 

大。 但是在SciKit Learn中,使用LogisticRegression对象时,我在使用W=9时不断出现无意义的预测。这里是我的Python代码:

import pandas as pd 
from sklearn.linear_model import LogisticRegression 
from patsy import dmatrices 

def test(final_weight): 
    d = { 
     'feat' : ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B'], 
     'target' : [0, 0, 1, 1, 0, 0, 0, 1], 
     'weight' : [1, 1, 1, 1, 1, 1, 1, final_weight], 
    } 
    df = pd.DataFrame(d) 
    print df, '\n' 

    y, X = dmatrices('target ~ feat', df, return_type="dataframe") 
    features = X.columns 

    C = 1e10 # high value to prevent regularization 
    solver = 'sag' # so we can use sample_weight 
    lr = LogisticRegression(C=C, solver=solver) 
    lr.fit(X, df.target, sample_weight=df.weight) 

    print 'Predictions:', '\n', lr.predict_proba(X), '\n', '====' 


test(1) 
test(3) 
test(9) 

这让下面的输出(我已删除了一些,使之少一些详细):

feat target weight 
... 
4 B  0  1 
5 B  0  1 
6 B  0  1 
7 B  1  1 

Predictions: 
[[ 0.50000091 0.49999909] 
... 
[ 0.74997935 0.25002065]] 
==== 
    feat target weight 
... 
4 B  0  1 
5 B  0  1 
6 B  0  1 
7 B  1  3 

/usr/local/lib/python2.7/dist-packages/sklearn/linear_model/sag.py:267: ConvergenceWarning: The max_iter was reached which means the coef_ did not converge 
Predictions: 
[[ 0.49939191 0.50060809] 
... 
[ 0.49967407 0.50032593]] 
==== 
    feat target weight 
... 
4 B  0  1 
5 B  0  1 
6 B  0  1 
7 B  1  9 

Predictions: 
[[ 0.00002912 0.99997088] # Nonsense predictions for A! 
... 
[ 0.00000034 0.99999966]] # And for B too... 
==== 

你可以看到,当我设置的最终重量为9(这看起来不像是一个不合理的高权重),预测就被破坏了!不仅是feat=B的预测可笑,而且的预测当时feat=A现在也荒谬

我的问题是

  • 为什么这些预测将会使错了,当最后的重量是9?

有没有我做过的错误或误解?

更一般地,我会非常有兴趣,如果有任何人成功地利用加权回归在SciKit学习,并取得了类似的预测由[Rglm(..., family='binomial')函数给出的。

很多人提前感谢任何帮助。

回答

1

看来,问题出在求解:

solver = 'sag' 

使用随机求解器是与你训练的例子独立同分布的假设大型数据集普遍。对于较高的样本权重,它效果不佳。

改变求解器来lbfgs后的结果符合您所看到的在R.

solver = 'lbfgs' 
+0

大卫,非常感谢!这似乎是完美的。出于某种原因,我已经将它纳入我的脑海,只有'sag'解算器可以用于sample_weight,但事实并非如此。 –

相关问题