【问题标题】:logistic regression doesn't find optimal decision boundary逻辑回归没有找到最佳决策边界
【发布时间】:2018-03-01 00:47:52
【问题描述】:

我在一个非常小且简单且可分离的数据集上运行逻辑回归。但我意识到模型无法找到最佳决策边界。我的错误在哪里?

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model

sm_df = pd.DataFrame()
sm_df['x'] = [0.5,4.0,1.0,2.5,2.0,3.5,1.0,3.0, 1.0, 2.0]
sm_df['y'] = [1.0,3.5,1.0,3.5,1.0, 4.5, 2.0,3.0, 0.0, 2.5]
sm_df['Bad_data'] = [True, False, True, False, True, False, True, False, True, False]

log = linear_model.LogisticRegression()

log.fit(sm_df[['x','y']], sm_df['Bad_data'])
test_score = log.score(sm_df[['x','y']], sm_df['Bad_data'])
print("test score: ", test_score)

# Create scatterplot of dataframe
sns.lmplot('x', # Horizontal axis
           'y', # Vertical axis
           data=sm_df, # Data source
           fit_reg=False, # Don't fix a regression line
           hue="Bad_data", # Set color
           scatter_kws={"marker": "D", # Set marker style
                        "s": 100}) # S marker size

plt.xlabel('x')
plt.ylabel('y')

# to plot desision bountdary
w0 = log.intercept_
w1, w2 = log.coef_[0]

X = np.array([0,4])
x2 = np.array([-w0/w2, -w0/w2 -w1*4/w2])
plt.plot(X, x2)
t_x = [1.5]
t_y = [1.8]
pr = log.predict([1.5,1.8])
plt.scatter(t_x, # Horizontal axis
           t_y, c='r') # S marker size
plt.annotate(pr, ([1.5,1.9]))

my plot:

【问题讨论】:

  • 您可以将 default solver 从 'liblinear' 更改为其他人,这将在此数据上提供完美的结果。 log = linear_model.LogisticRegression(solver='newton-cg')
  • 出于实现原因,默认求解器'liblinear' 会惩罚拦截,但不建议这样做。所有其他求解器都不会惩罚截距,应该给你正确的边界。
  • 有趣。谢谢@TomDLT。有那么一刻,我试图理解上述评论的含义以及答案。
  • 谢谢你,TomDLT。很高兴知道拦截可能会受到处罚。

标签: python machine-learning scikit-learn logistic-regression


【解决方案1】:

原因是因为错误不是模型受到惩罚的唯一原因 - 还有一个正则化项。如果你用类似的东西使正则化项更小

log = linear_model.LogisticRegression(C=10.)

那么在这个例子中所有的点都会被正确分类。这是因为模型将相对更关心正确分类点,而相对较少关心正则化。这里C的参数是正则化强度的倒数,默认为1。

这里有必要这样做的部分原因是您的数据没有标准化。如果您在应用逻辑回归之前对数据进行标准化(给 x 和 y 均值为零且方差为 1),那么您还可以完美拟合 C=1。你可以用类似的东西来做到这一点

sm_df['x'] = (sm_df['x'] - sm_df['x'].mean()) / sm_df['x'].std()
sm_df['y'] = (sm_df['y'] - sm_df['y'].mean()) / sm_df['y'].std()

【讨论】:

  • 谢谢你,杰里米!有用。看起来当我们有一个可分离的数据集时,我们应该不太关心正则化。
  • 有点!您必须增加 C 的部分原因是您的数据没有标准化,因此模型需要大系数来拟合数据(正则化不鼓励大系数)。我更新了我的答案以反映这一点。另一个原因是正则化的目的是防止过度拟合您的数据,这基本上意味着不要太努力地让所有训练数据都正确(但它可能会更好地泛化到看不见的数据上)。
猜你喜欢
  • 2015-03-31
  • 2020-05-05
  • 2020-08-31
  • 2017-07-30
  • 2014-11-27
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
相关资源
最近更新 更多