python logistic回归(初学者)

我正在尝试自学使用Python进行logistic回归。我试图将这里的教程应用到维基百科条目中这里的小数据集上。

似乎有些地方不太对劲。维基百科和Excel Solver(使用这个视频中的方法验证)给出的截距为-4.0777,系数为1.5046,但从GitHub示例中构建的代码输出分别为-0.924200和0.756024。

我尝试使用的代码如下。有没有明显的错误?

import numpy as npimport pandas as pdfrom patsy import dmatricesfrom sklearn.linear_model import LogisticRegressionX = [0.5,0.75,1.0,1.25,1.5,1.75,1.75,2.0,2.25,2.5,2.75,3.0,3.25,3.5,4.0,4.25,4.5,4.75,5.0,5.5]y = [0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]zipped = list(zip(X,y))df = pd.DataFrame(zipped,columns = ['study_hrs','p_or_f'])y, X = dmatrices('p_or_f ~ study_hrs',                  df, return_type="dataframe")y = np.ravel(y)model = LogisticRegression()model = model.fit(X,y)print(pd.DataFrame(np.transpose(model.coef_),X.columns))>>>                  0Intercept -0.924200study_hrs  0.756024

回答:

解决方案

只需更改模型创建行如下:

model = LogisticRegression(C=100000, fit_intercept=False)

问题的分析

默认情况下,sklearn解决的是正则化的LogisticRegression,其拟合强度为C=1(C值小-正则化强,C值大-正则化弱)。

这个类使用liblinear库、newton-cg和lbfgs求解器实现了正则化的logistic回归。它可以处理密集和稀疏输入。为了获得最佳性能,请使用C顺序数组或包含64位浮点数的CSR矩阵;任何其他输入格式都将被转换(并复制)。

因此,要获得他们的模型,你应该拟合

model = LogisticRegression(C=1000000)

这将得到

Intercept -2.038853 # 这实际上是截距的一半study_hrs  1.504643 # 这是正确的

此外,问题还出在你使用patsy处理数据的方式上,请看简化的、正确的示例

import numpy as npfrom sklearn.linear_model import LogisticRegressionX = [0.5,0.75,1.0,1.25,1.5,1.75,1.75,2.0,2.25,2.5,2.75,3.0,3.25,3.5,4.0,4.25,4.5,4.75,5.0,5.5]y = [0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]X = np.array([[x] for x in X])y = np.ravel(y)model = LogisticRegression(C=1000000.)model = model.fit(X,y)print('coef', model.coef_)print('intercept', model.intercept_)

得到

coef [[ 1.50464059]]intercept [-4.07769916]

问题到底是什么?当你使用dmatrices时,它默认会在你的输入数据中嵌入一列全为1的值(偏置项)

X = [0.5,0.75,1.0,1.25,1.5,1.75,1.75,2.0,2.25,2.5,2.75,3.0,3.25,3.5,4.0,4.25,4.5,4.75,5.0,5.5]y = [0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]zipped = list(zip(X,y))df = pd.DataFrame(zipped,columns = ['study_hrs','p_or_f'])y, X = dmatrices('p_or_f ~ study_hrs',                  df, return_type="dataframe")print(X)

这导致

    Intercept  study_hrs0           1       0.501           1       0.752           1       1.003           1       1.254           1       1.505           1       1.756           1       1.757           1       2.008           1       2.259           1       2.5010          1       2.7511          1       3.0012          1       3.2513          1       3.5014          1       4.0015          1       4.2516          1       4.5017          1       4.7518          1       5.0019          1       5.50

这就是为什么结果中的偏置项只是真实值的一半——scikit-learn也添加了一列全为1的值…所以你现在有两个偏置项,因此最优解是给每个偏置项分配原本应该给单个偏置项的一半权重。

那么你可以做什么呢?

  • 不要以这种方式使用patsy
  • 禁止patsy添加偏置项
  • 告诉sklearn不要添加偏置项

.

import numpy as npimport pandas as pdfrom patsy import dmatricesfrom sklearn.linear_model import LogisticRegressionX = [0.5,0.75,1.0,1.25,1.5,1.75,1.75,2.0,2.25,2.5,2.75,3.0,3.25,3.5,4.0,4.25,4.5,4.75,5.0,5.5]y = [0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]zipped = list(zip(X,y))df = pd.DataFrame(zipped,columns = ['study_hrs','p_or_f'])y, X = dmatrices('p_or_f ~ study_hrs',                  df, return_type="dataframe")y = np.ravel(y)model = LogisticRegression(C=100000, fit_intercept=False)model = model.fit(X,y)print(pd.DataFrame(np.transpose(model.coef_),X.columns))

得到

Intercept -4.077571study_hrs  1.504597

如所期望的

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注