sklearn LogisticRegression - 图显示的系数太小
sklearn LogisticRegression - plot displays too small coefficient
我正在尝试将逻辑回归模型拟合到 sklearn 的鸢尾花数据集。我得到一条看起来太平坦的概率曲线,也就是系数太小。我希望萼片长度 > 7 的概率超过 90% :
这条概率曲线真的是错误的吗?如果是这样,是什么原因导致我的代码出现这种情况?
from sklearn import datasets
import matplotlib.pyplot as plt
import numpy as np
import math
from sklearn.linear_model import LogisticRegression
data = datasets.load_iris()
#get relevent data
lengths = data.data[:100, :1]
is_setosa = data.target[:100]
#fit model
lgs = LogisticRegression()
lgs.fit(lengths, is_setosa)
m = lgs.coef_[0,0]
b = lgs.intercept_[0]
#generate values for curve overlay
lgs_curve = lambda x: 1/(1 + math.e**(-(m*x+b)))
x_values = np.linspace(2, 10, 100)
y_values = lgs_curve(x_values)
#plot it
plt.plot(x_values, y_values)
plt.scatter(lengths, is_setosa, c='r', s=2)
plt.xlabel("Sepal Length")
plt.ylabel("Probability is Setosa")
虽然你没有描述你想要绘制什么,但我假设你想要绘制分隔线。您似乎对 Logistic/sigmoid 函数感到困惑。逻辑回归的决策函数是一条线。
你的概率图看起来很平坦,因为从某种意义上说,你 "zoomed in" 太多了。
如果您查看 sigmoid 函数的中间,它几乎是线性的,因为二阶导数几乎为 0(例如参见 [=13=])
请注意,我们所说的值是 -(m*x+b)
的结果
当我们减少图表的限制时,比如使用
x_values = np.linspace(4, 7, 100)
,我们得到了一条线:
但另一方面,如果我们对极限疯狂,比如使用 x_values = np.linspace(-10, 20, 100)
,我们会得到更清晰的 sigmoid:
如果你参考http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression,你会发现一个正则化参数C
可以在训练逻辑回归模型时作为参数传递。
C : float, default: 1.0 Inverse of regularization strength; must be a
positive float. Like in support vector machines, smaller values
specify stronger regularization.
现在,如果您尝试此 正则化 参数的不同值,您会发现 C
的较大值会导致拟合具有从输出(响应)二进制变量的 0 到 1 值的更尖锐过渡的曲线,并且更大的值适合具有高方差的模型(尝试更紧密地模拟训练数据过渡,我认为这就是您所期望的,那么你可以尝试将 C
值设置为 10
并绘制)但同时可能会有 overfit[=43= 的风险],而默认值C=1
和小于该值的值会导致高偏差,并且可能欠拟合这就是机器学习中著名的偏差方差权衡。
您始终可以使用 交叉验证 等技术来选择适合您的 C
值。下面的代码/图显示了拟合不同复杂度模型的概率曲线(即正则化参数C
的不同值,从1
到10
):
x_values = np.linspace(2, 10, 100)
x_test = np.reshape(x_values, (100,1))
C = list(range(1, 11))
labels = map(str, C)
for i in range(len(C)):
lgs = LogisticRegression(C = C[i]) # pass a value for the regularization parameter C
lgs.fit(lengths, is_setosa)
y_values = lgs.predict_proba(x_test)[:,1] # use this function to compute probability directly
plt.plot(x_values, y_values, label=labels[i])
plt.scatter(lengths, is_setosa, c='r', s=2)
plt.xlabel("Sepal Length")
plt.ylabel("Probability is Setosa")
plt.legend()
plt.show()
使用不同 C
值拟合模型的预测概率
我正在尝试将逻辑回归模型拟合到 sklearn 的鸢尾花数据集。我得到一条看起来太平坦的概率曲线,也就是系数太小。我希望萼片长度 > 7 的概率超过 90% :
这条概率曲线真的是错误的吗?如果是这样,是什么原因导致我的代码出现这种情况?
from sklearn import datasets
import matplotlib.pyplot as plt
import numpy as np
import math
from sklearn.linear_model import LogisticRegression
data = datasets.load_iris()
#get relevent data
lengths = data.data[:100, :1]
is_setosa = data.target[:100]
#fit model
lgs = LogisticRegression()
lgs.fit(lengths, is_setosa)
m = lgs.coef_[0,0]
b = lgs.intercept_[0]
#generate values for curve overlay
lgs_curve = lambda x: 1/(1 + math.e**(-(m*x+b)))
x_values = np.linspace(2, 10, 100)
y_values = lgs_curve(x_values)
#plot it
plt.plot(x_values, y_values)
plt.scatter(lengths, is_setosa, c='r', s=2)
plt.xlabel("Sepal Length")
plt.ylabel("Probability is Setosa")
虽然你没有描述你想要绘制什么,但我假设你想要绘制分隔线。您似乎对 Logistic/sigmoid 函数感到困惑。逻辑回归的决策函数是一条线。
你的概率图看起来很平坦,因为从某种意义上说,你 "zoomed in" 太多了。
如果您查看 sigmoid 函数的中间,它几乎是线性的,因为二阶导数几乎为 0(例如参见 [=13=])
请注意,我们所说的值是 -(m*x+b)
当我们减少图表的限制时,比如使用
x_values = np.linspace(4, 7, 100)
,我们得到了一条线:
但另一方面,如果我们对极限疯狂,比如使用 x_values = np.linspace(-10, 20, 100)
,我们会得到更清晰的 sigmoid:
如果你参考http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression,你会发现一个正则化参数C
可以在训练逻辑回归模型时作为参数传递。
C : float, default: 1.0 Inverse of regularization strength; must be a positive float. Like in support vector machines, smaller values specify stronger regularization.
现在,如果您尝试此 正则化 参数的不同值,您会发现 C
的较大值会导致拟合具有从输出(响应)二进制变量的 0 到 1 值的更尖锐过渡的曲线,并且更大的值适合具有高方差的模型(尝试更紧密地模拟训练数据过渡,我认为这就是您所期望的,那么你可以尝试将 C
值设置为 10
并绘制)但同时可能会有 overfit[=43= 的风险],而默认值C=1
和小于该值的值会导致高偏差,并且可能欠拟合这就是机器学习中著名的偏差方差权衡。
您始终可以使用 交叉验证 等技术来选择适合您的 C
值。下面的代码/图显示了拟合不同复杂度模型的概率曲线(即正则化参数C
的不同值,从1
到10
):
x_values = np.linspace(2, 10, 100)
x_test = np.reshape(x_values, (100,1))
C = list(range(1, 11))
labels = map(str, C)
for i in range(len(C)):
lgs = LogisticRegression(C = C[i]) # pass a value for the regularization parameter C
lgs.fit(lengths, is_setosa)
y_values = lgs.predict_proba(x_test)[:,1] # use this function to compute probability directly
plt.plot(x_values, y_values, label=labels[i])
plt.scatter(lengths, is_setosa, c='r', s=2)
plt.xlabel("Sepal Length")
plt.ylabel("Probability is Setosa")
plt.legend()
plt.show()