简单逻辑回归错误预测

数据挖掘 逻辑回归
2022-02-27 15:38:37

在以下示例中,拟合模型后,但预期为x=[0,0]10

X = np.array([
    [0, 0],
    [1, 0],
    [0, 1]
])

Y = np.array([0,1,1])

model = LogisticRegression()
model.fit(X,Y)

x = [0,0]
y = model.predict([x])[0]

)的训练行时才有效x=[0,0],y=[0]

但为什么?

3个回答

因为你有一个类不平衡和非常少的数据。您的模型本质上是在利用不成比例地偏向正类的先验概率,并且您没有为模型提供足够的数据来在学习过程中逃避这种先验概率。考虑模型的以下详细输出:

model.score(X,Y) # 0.6666
model.coef_      # array([[ 0.36566712,  0.36566712]])
model.intercept_ # array([ 0.18517658])

model.predict_proba(X)
# array([[ 0.45383769,  0.54616231],
#        [ 0.36566869,  0.63433131],
#        [ 0.36566869,  0.63433131]])

您的模型正确地识别出 [0,0] 比任何其他观察结果更可能为负数,但该模型无法摆脱其对正类的偏见。如果您多次复制数据集,模型最终将有足够的“证据”来避免这种偏差。在几何上,当我们为模型提供更多数据时,会发生两件事:

  1. 区分边界将转向负类。这将表现为一个越来越负的截距项。
  2. 逻辑曲线的斜率将变陡,其效果是输入的单位变化将对结果产生更大的影响。如果我们给模型足够的完全可分离的数据,曲线将接近一个阶跃函数,模型将输出 0 和 1 的概率。这体现在系数的大小上。只有三个观察值,曲线相当平坦,改变输入值对结果概率没有太大影响,因此产生的类分配基本上仅由截距决定。

将原始模型的结果与我们复制数据集 100 次时发生的结果进行对比:

model2 = LogisticRegression()
X2 = np.matlib.repmat(X,100,1)
Y2 = np.matlib.repmat(Y,100,1).ravel()
model2.fit(X2, Y2)

model2.score(X,Y) # 1.0
model2.coef_      # array([[ 4.95489068,  4.95489068]])
model2.intercept_ # array([-2.00091433])
model2.predict_proba(X)

# array([[ 0.88089304,  0.11910696],
#        [ 0.04954891,  0.95045109],
#        [ 0.04954891,  0.95045109]])

这是因为你有一个不平衡的数据集指向 0 类。我查看了你得到的逻辑回归系数。在下面的图表 1 中,我绘制了您使用逻辑回归得到的决策边界。在第二张图表上,我绘制了您的预期。

那么为什么会出现这种差异以及为什么您的逻辑回归会产生图表 1?原因是即使它是机器学习算法,也不是很聪明。逻辑回归算法希望最小化其成本函数(交叉熵)。交叉熵可以以非常简单的方式定义为您的点与决策边界之间的距离。

但是,在您的训练案例中,您只有一个 class_0 观察有两个 class-1 观察。因此机器学习算法会看到,为了尽可能地达到最低成本函数,最好的选择是提升两个 1 类观察值而不是只有一个 0 类观察值。图表 2 上的成本函数值大于图表 1,这就是它产生图表 1 结果的原因。多数获胜!

为避免此问题,您可以执行以下三个想法:

  • 对您的数据集进行欠采样/过采样,以便在您的训练集的每个类别中获得相似数量的观察结果。
  • 更改您的观察类权重。
  • 使用其他成本函数,如铰链损失,它是 SVM 中使用的成本函数,其目标是最大化类之间的边际。

在此处输入图像描述

在最简单的语言中,您的模型“看到”的 1 类示例比 0 类示例更多(因为数据非常少),因此将 1 类作为输出的概率更高。正如其他人所指出的,这是一个阶级不平衡问题。所以,即使你给出[0,0]预测,它也会返回第 1 类作为输出。

当前训练集中第 1 类和第 0 类的比例为 2:1。当您复制数据时,比率变为 1:1,因此模型现在可以正确预测您的示例。