sklearn: LogisticRegression - predict_proba(X) - 计算

Posted

技术标签:

【中文标题】sklearn: LogisticRegression - predict_proba(X) - 计算【英文标题】:sklearn: LogisticRegression - predict_proba(X) - calculation 【发布时间】:2016-05-20 19:24:40 【问题描述】:

我想知道是否有人可以快速查看以下代码 sn-p 并指出我在计算模型中每个类的样本概率和相关代码错误时的误解。我尝试手动计算 sklearn 函数 lm.predict_proba(X) 提供的结果,遗憾的是结果不同,所以我犯了一个错误。

我认为该错误将出现在以下代码演练的“d”部分。也许在数学上,但我不明白为什么。

a) 创建和训练逻辑回归模型(工作正常)

lm = LogisticRegression(random_state=413, multi_class='multinomial', solver='newton-cg')
lm.fit(X, train_labels)

b) 保存系数和偏差(工作正常)

W = lm.coef_
b = lm.intercept_

c) 使用 lm.predict_proba(X) (工作正常)

def reshape_single_element(x,num):
    singleElement = x[num]
    nx,ny = singleElement.shape
    return  singleElement.reshape((1,nx*ny))

select_image_number = 6 
X_select_image_data=reshape_single_element(train_dataset,select_image_number)
Y_probabilities =  lm.predict_proba(X_select_image_data)
Y_pandas_probabilities = pd.Series(Y_probabilities[0], index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
print"estimate probabilities for each class: \n" ,Y_pandas_probabilities , "\n"
print"all probabilities by lm.predict_proba(..) sum up to ", np.sum(Y_probabilities) , "\n"

输出是:

estimate probabilities for each class: 
a 0.595426
b 0.019244
c 0.001343
d 0.004033
e 0.017185
f 0.004193
g 0.160380
h 0.158245
i 0.003093
j 0.036860
dtype: float64 
all probabilities by lm.predict_proba(..) sum up to 1.0

d) 手动执行由 lm.predict_proba 完成的计算(没有错误/警告,但结果不一样)

manual_calculated_probabilities = []
for select_class_k in range(0,10):  #a=0. b=1, c=3 ...
    z_for_class_k = (np.sum(W[select_class_k] *X_select_image_data) + b[select_class_k] )
    p_for_class_k = 1/ (1 + math.exp(-z_for_class_k))
    manual_calculated_probabilities.append(p_for_class_k)

print "formula: ", manual_calculated_probabilities , "\n"

def softmax(x):
    """Compute softmax values for each sets of scores in x."""
    e = np.exp(x)
    dist = e / np.sum(np.exp(x),axis=0)
    return dist

abc = softmax(manual_calculated_probabilities)
print "softmax:" , abc

输出是:

formula: [0.9667598370531315, 0.48453459121301334, 0.06154496922245115, 0.16456194859398865, 0.45634781280053394, 0.16999340794727547, 0.8867996361191054, 0.8854473986336552, 0.13124464656251109, 0.642913996162282]

softmax: [ 0.15329642 0.09464644 0.0620015 0.0687293 0.0920159 0.069103610.14151607 0.14132483 0.06647715 0.11088877]

使用了Softmax,因为github logistic.py的评论

For a multi_class problem, if multi_class is set to be "multinomial" the softmax function is used to find the predicted probability of each class.

注意:

print "shape of X: " , X_select_image_data.shape
print "shape of W: " , W.shape
print "shape of b: " , b.shape

shape of X:  (1, 784)
shape of W:  (10, 784)
shape of b:  (10,)

我发现了一个非常相似的问题here,但遗憾的是我无法将其调整到我的代码中,因此预测结果相同。我尝试了许多不同的组合来计算变量“z_for_class_k”和“p_for_class_k”,但遗憾的是没有成功重现“predict_proba(X)”的预测值。

【问题讨论】:

@Ted Frank 找到解决方案了吗? 【参考方案1】:

我认为问题出在

p_for_class_k = 1/ (1 + math.exp(-z_for_class_k))

1 / (1 + exp(-logit)) 是一种仅适用于二元问题的简化。

真正的方程,在被简化之前是这样的:

p_for_classA = exp(logit_classA) / [1 + exp(logit_classA) + exp(logit_classB) ... + exp(logit_classC)]

换句话说,在计算特定类别的概率时,您必须将其他类别的所有权重和偏差也纳入您的公式中。

我没有数据来测试这一点,但希望这可以为您指明正确的方向。

【讨论】:

【参考方案2】:

改变

p_for_class_k = 1/ (1 + math.exp(-z_for_class_k))
manual_calculated_probabilities.append(p_for_class_k)

manual_calculated_probabilities.append(z_for_class_k)

在你的符号中,softmax 的输入是“z”s 而不是“p”s。 multinomial logistic

【讨论】:

【参考方案3】:

通过执行以下操作,我能够复制方法 lr.predict_proba

>>> sigmoid = lambda x: 1/(1+np.exp(-x))
>>> sigmoid(lr.intercept_+np.sum(lr.coef_*X.values, axis=1))

假设 X 是一个 numpy 数组,lr 是一个来自 sklearn 的对象。

【讨论】:

以上是关于sklearn: LogisticRegression - predict_proba(X) - 计算的主要内容,如果未能解决你的问题,请参考以下文章

sklearn中OneHotEncoder

机器学习- 吴恩达Andrew Ng - week3-2 Logistic Regression Model

无法从 sklearn.externals.joblib 导入 Sklearn

sklearn的PCA

sklearn数据库-老鱼学sklearn

使用sklearn画二分类模型ROC曲线,PR曲线