用于分类的线性模型
对于用于回归的线性模型,输出是特征的线性函数,是直线、平面或超平面
对于用于分类的线性模型,决策边界是输入的线性函数。(二元)线性分类器利用直线、平面或超平面来分开两个类别的分类器
最常见的两种线性分类算法是Logistic回归(logistic regression,LR)和线性支持向量机(linear support vector machine, 线性SVM)
注:转自https://blog.csdn.net/ztf312/article/details/88606667
两者的相同点:
- LR和SVM都是分类算法
- 如果不考虑使用核函数,LR和SVM都是线性分类模型,也就是说它们的分类决策边界是线性的
- LR和SVM都是监督学习算法
- LR和SVM都是判别模型
两者的不同点:
-
loss function不同
LR:
SVM:
LR基于概率理论,通过极大似然估计方法估计出参数的值,然后计算分类概率,取概率较大的作为分类结果。SVM基于几何间隔最大化,把最大几何间隔面作为最优分类面。 -
SVM只考虑分类面附近的局部的点,即支持向量,LR则考虑所有的点,与分类面距离较远的点对结果也起作用,虽然作用较小
SVM中的分类面是由支持向量控制的,非支持向量对结果不会产生任何影响。线性SVM不直接依赖数据分布,分类平面不受一类点影响;LR中的分类面则是由全部样本共同决定,受所有数据点的影响,如果数据不同类别strongly unbalance,一般需要先对数据做balancing。 -
在解决非线性分类问题时,SVM采用核函数,而LR通常不采用核函数
分类模型的结果就是计算决策面,模型训练的过程就是决策面的计算过程。在计算决策面时,SVM算法中只有支持向量参与了核计算,即kernel machine的解的系数是稀疏的。在LR算法里,如果采用核函数,则每一个样本点都会参与核计算,这会带来很高的计算复杂度,所以,在具体应用中,LR很少采用核函数。 -
SVM不具有伸缩不变性,LR则具有伸缩不变性
SVM模型在各个维度进行不均匀伸缩后,最优解与原来不等价,对于这样的模型,除非本来各维数据的分布范围就比较接近,否则必须进行标准化,以免模型参数被分布范围较大或较小的数据影响。LR模型在各个维度进行不均匀伸缩后,最优解与原来等价,对于这样的模型,是否标准化理论上不会改变最优解。但是,由于实际求解往往使用迭代算法,如果目标函数的形状太“扁”,迭代算法可能收敛得很慢甚至不收敛。所以对于具有伸缩不变性的模型,最好也进行数据标准化。 -
SVM损失函数自带正则项,因此,SVM是结构风险最小化算法。而LR需要额外在损失函数上加正则项
所谓结构风险最小化,意思就是在训练误差和模型复杂度之间寻求平衡,防止过拟合,从而达到真实误差的最小化。未达到结构风险最小化的目的,最常用的方法就是添加正则项。
我们可以将两者模型应用到forge数据集上,并将线性模型找到的决策边界可视化
#线性分类模型
from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
import matplotlib.pyplot as plt
import mglearn
%matplotlib inline
X, y = mglearn.datasets.make_forge()
fig, axes = plt.subplots(1,2,figsize=(10,3))
for model, ax in zip([LinearSVC(),LogisticRegression()],axes):
clf = model.fit(X, y)
mglearn.plots.plot_2d_separator(clf, X, fill=False, eps=0.5, ax=ax, alpha=.7)
mglearn.discrete_scatter(X[:,0], X[:,1], y, ax=ax)
ax.set_title("{}".format(clf.__class__.__name__))
ax.set_xlabel("Feature 0")
ax.set_ylabel("Feature 1")
axes[0].legend()
对于每个分类器而言,位于决策边界上方的新数据点会被划为类别1,而在决策边界下方的点都会被划为类别0。
决定正则化强度的权衡参数叫作C,C值越大,对应的正则化越弱。换句话说,如果参数C值比较大,那么LogisticRegression
和LinearSVC
将尽可能将训练集拟合到最好,而如果C值较小,那么模型更强调系数向量接近于0。
参数C还有一个有趣之处,较小的C值可以让算法尽量适应”大多数“数据点,而较大的C值更强调每个数据点都分类正确的重要性。
#不同C值
mglearn.plots.plot_linear_svc_regularization()
- 在左侧的图中,C值很小,对应强正则化,强正则化的模型会选择一条相对水平的线,有两个点分类错误。
- 在中间的图中,C值稍大,模型更关注两个分类错误的样本,使决策边界的斜率变大。
- 在右侧的图中,C值非常大,使得决策边界的斜率也很大,现在模型对类别0中的所有点的分类都是正确的,类别1中仍有一个点分类错误。
我们在乳腺癌数据集上详细分析LogisticRegression
#cancer上的LogisticRegression
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target,
stratify=cancer.target, random_state=42)
logreg = LogisticRegression().fit(X_train, y_train)
print("Training set score: {:.3f}".format(logreg.score(X_train, y_train)))
print("Test set score: {:.3f}".format(logreg.score(X_test, y_test)))
logreg100 = LogisticRegression(C=100).fit(X_train, y_train)
print("Training set score: {:.3f}".format(logreg100.score(X_train, y_train)))
print("Test set score: {:.3f}".format(logreg100.score(X_test, y_test)))
logreg001 = LogisticRegression(C=0.01).fit(X_train, y_train)
print("Training set score: {:.3f}".format(logreg001.score(X_train, y_train)))
print("Test set score: {:.3f}".format(logreg001.score(X_test, y_test)))
输出结果:
默认C=1:
Training set score: 0.948
Test set score: 0.965
C=100:
Training set score: 0.951
Test set score: 0.965
C=0.01:
Training set score: 0.937
Test set score: 0.930
- C=1的默认值给出了相当好的性能,在训练集和测试集上都达到了接近95%的精度,但由于两者性能非常接近,所以模型很可能是欠拟合的,尝试增大C来拟合一个更灵活的模型。
- 使用C=100,可以得到更高的训练集精度,也得到稍高的测试集精度,即更复杂的模型应该性能更好
- 使用C=0.01,即使用正则化更强的模型,已经欠拟合的模型继续向左移动,训练集和测试集的精度都比采用默认参数时更小。