在以下示例中,拟合模型后,但预期为。
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 = 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]
)的训练行时才有效
但为什么?
因为你有一个类不平衡和非常少的数据。您的模型本质上是在利用不成比例地偏向正类的先验概率,并且您没有为模型提供足够的数据来在学习过程中逃避这种先验概率。考虑模型的以下详细输出:
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] 比任何其他观察结果更可能为负数,但该模型无法摆脱其对正类的偏见。如果您多次复制数据集,模型最终将有足够的“证据”来避免这种偏差。在几何上,当我们为模型提供更多数据时,会发生两件事:
将原始模型的结果与我们复制数据集 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 结果的原因。多数获胜!
为避免此问题,您可以执行以下三个想法:
在最简单的语言中,您的模型“看到”的 1 类示例比 0 类示例更多(因为数据非常少),因此将 1 类作为输出的概率更高。正如其他人所指出的,这是一个阶级不平衡问题。所以,即使你给出[0,0]预测,它也会返回第 1 类作为输出。
当前训练集中第 1 类和第 0 类的比例为 2:1。当您复制数据时,比率变为 1:1,因此模型现在可以正确预测您的示例。