线性模型用于分类,分类的原理还要从公式说起。
y=w[0]?x[0] w[1]?x[1] ... w[p]?x[p] by=w[0]?x[0]w[1]?x[1]...w[p]?x[p]b
y = w[0]x[0] w1x1 ... w[p]*x[p] b线性模型的公司的结果y
是一个连续的输出结果,如果将y
的值与0
作一个界限上的区分,那y
的值将被分成两个区域。公式的表达如下:
y=w[0]?x[0] w[1]?x[1] ... w[p]?x[p] b>0y=w[0]?x[0]w[1]?x[1]...w[p]?x[p]b>0
y = w[0]x[0] w1x1 ... w[p]*x[p] b>0也就是说,如果该公式(函数)预测的结果值小于0,就归类为-1,如果结果值大于0,就归类为1.
需要重点理解的地方在于:
对于用于回归的线性模型来说,输出y
是特征的线性函数,是直线、平面或超平面(对于更高维的数据集)。
对于用于分类的线性模型,决策边界是输入的线性函数。
不同线性模型算法之间的区别在于:
系数和截距的特定组合对训练集数据拟合好坏的度量方法;
是否使用正则化,以及使用哪种正则化方法。
最觉的两种线性分类算法是Logistic回归和线性支持向量机。前者在linear_model.LogisticRegression
中实现,后者在svm.LinearSVC
(SVC代表支持向量分类器)中实现 。
接下来对这两个模型做一个初步认识吧!
# 在学习之前,先导入这些常用的模块import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport mglearn
下面,将这两个模型用在二分类数据forge
数据集上,并显示模型得出的决策边界。
先展示下二分类的展示图:
# 导入二分类数据X, y = mglearn.datasets.make_forge()mglearn.discrete_scatter(X[:, 0], X[:, 1], y)plt.show()
# 导入Logisticfrom sklearn.linear_model import LogisticRegression# 导入LinearSVCfrom sklearn.svm import LinearSVC# 导入二分类数据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=.5, ax=ax, alpha=.7)# 绘制二分类的训练数据mglearn.discrete_scatter(X[:, 0], X[:, 1], y, ax=ax)# 设置标题为模型名称ax.set_title('{}'.format(clf.__class__.__name__))# 设置x坐标轴标签名称ax.set_xlabel('Feature 0')# 设置y坐标轴标签名称ax.set_ylabel('Feature 1')# 在第一个绘图区上显示图例axes[0].legend() plt.show()
说明:
forge数据集有两个特征,分别对应X轴与Y轴。
LinearSVC与LogisticRegression得到的决策边界,都是直线,将数据分为了上下两个区域。
两个模型默认使用了L2正则化。
继续探讨:
对于LinearSVC与LogisticRegression而言,决定正则化强度的权衡参数叫做C
。C
值越大,对就的正则化越弱。
也就是说,越大的C
将拥有越上的约束力,即系数的大小更自由,模型对于数据的贴合度将变得更复杂。
如果C
越小,则对系数的约束越大,甚至趋向于0,使模型更能贴合大多数数据,模型也更简单。
下面直接展示一下LinearSVC模型的C
分别取0.01
、1
、100
时模型的决策边界效果:
mglearn.plots.plot_linear_svc_regularization()
对上图的总结:
最左侧的图,C值很小,所以对应强正则化。要求模型更贴合于大多数数据,因此对于图中两个错误的点进行了忽略。
中间的图,C值稍大,由于对模型的约束变小,模型对于数据的反应则变得更加第三一些,决策线向着两个错误的点进行偏移,希望更好的贴合训练数据。
右侧图C值很大,因为对模型的约束很小,导致模型的决策边界要求对所有数据都贴合,造成了过拟合现象。
再来看看使用乳腺癌数据集对LogisticRegression模型做出分析:
# 导入乳腺癌数据from sklearn.datasets import load_breast_cancer cancer = load_breast_cancer()# 将数据分为训练集测试集from sklearn.model_selection import train_test_split 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('训练集评估分数:', logreg.score(X_train, y_train))print('测试集评估分数:', logreg.score(X_test, y_test))
训练集评估分数: 0.9553990610328639测试集评估分数: 0.958041958041958
这里模型置信的C
值是1.如果训练集的评分与测试集的评分差不多,那可能存在欠拟合的现象。
现在给模型增大C
值,再看看评估结果:
logreg100 = LogisticRegression(C=100).fit(X_train, y_train)print('训练集评估分数:', logreg100.score(X_train, y_train))print('测试集评估分数:', logreg100.score(X_test, y_test))
训练集评估分数: 0.971830985915493测试集评估分数: 0.965034965034965
通过增大模型的C
值,发现模型的精度变高了。
现在再减小C
值看看模型的评估分数:
logreg001 = LogisticRegression(C=0.01).fit(X_train, y_train)print('训练集评估分数:', logreg001.score(X_train, y_train))print('测试集评估分数:', logreg001.score(X_test, y_test))
训练集评估分数: 0.9342723004694836测试集评估分数: 0.9300699300699301
可以看出,模型的精度变小了,并且存在欠拟合的可能。
按照老办法,我们当不同C
值情况下,模型得出的系数图例化,看看结果:
plt.plot(logreg.coef_.T, 'o', label='C=1') plt.plot(logreg100.coef_.T, '^', label='C=100') plt.plot(logreg001.coef_.T, 'v', label='C=0.01') plt.xticks(range(cancer.data.shape[1]), cancer.feature_names, rotation=90) plt.hlines(0, 0, cancer.data.shape[1]) plt.ylim(-5, 5) plt.xlabel('Codefficient index') plt.ylabel('Coefficient magnitude') plt.legend() plt.show()
从这个图例可以看出,C
值越小,模型的系数就越趋向于0.
另外,该模型默认使用L2正则,也可以将其改成L1正则,以减少模型使用的特征:
# 评估for C, marker in zip([0.001, 1, 100], ['o', '^', 'v']): lr_l1 = LogisticRegression(C=C, penalty='l1').fit(X_train, y_train)print('训练集,C={0},评估分数={1}'.format(C, lr_l1.score(X_train, y_train)))print('测试集,C={0},评估分数={1}'.format(C, lr_l1.score(X_test, y_test)))# 绘图plt.plot(lr_l1.coef_.T, marker, label='C={}'.format(C)) plt.xticks(range(cancer.data.shape[1]), cancer.feature_names, rotation=90) plt.hlines(0, 0, cancer.data.shape[1]) plt.ylim(-5, 5) plt.xlabel('Codefficient index') plt.ylabel('Coefficient magnitude') plt.legend(loc=3) plt.show()
训练集,C=0.001,评估分数=0.9131455399061033 测试集,C=0.001,评估分数=0.9230769230769231 训练集,C=1,评估分数=0.960093896713615 测试集,C=1,评估分数=0.958041958041958 训练集,C=100,评估分数=0.9859154929577465 测试集,C=100,评估分数=0.9790209790209791
Ok,上图对于不同C
值所对应的L
正则下的系数分布有了直观的了解,也就明白了对应的约束力。
这里主要需要明白设置L1或L2需要通过参数penalty
来设置。
多分类其实也是一处二分类的模式,它是一对其余的方法。
这里展示一个三类的gf数据:
from sklearn.datasets import make_blobs X, y = make_blobs(random_state=42) mglearn.discrete_scatter(X[:, 0], X[:, 1], y) plt.xlabel('Feature 0') plt.ylabel('Feature 1') plt.legend(['Class 0', 'Class 1', 'Class 2']) plt.show()
然后使用该数据对LinearSVC
分类器进行训练:
linear_svm = LinearSVC().fit(X, y)print('模型斜率集:', linear_svm.coef_.shape)print('模型截距集:', linear_svm.intercept_.shape)
模型斜率集: (3, 2) 模型截距集: (3,)
通过形状可以明白:斜率集有3行,每行代表类别之一的一个系数向量;有2列,每列包含某个特征对应的系数值。而截距是个一维数据,包含每个类别的截距值。
现在将分类器给出的直线进行可视化:
mglearn.discrete_scatter(X[:, 0], X[:, 1], y) line = np.linspace(-15, 15)for coef, intercept, color in zip(linear_svm.coef_, linear_svm.intercept_, ['b', 'r', 'g']): plt.plot(line, -(line * coef[0] intercept) / coef[1], c=color) plt.ylim(-10, 15) plt.xlim(-10, 8) plt.xlabel('Feature 0') plt.ylabel('Feature 1') plt.legend(['Class 0', 'Class 1', 'Class 2'], loc=(1.01, 0.3)) plt.show()
在这里,线条的颜色与各点的颜色是一致的。从图中可以很直观的看到这三个点是如何被分成三类的。
但是,这三条线交叉的地方,有一个空白的三角区,那这个区域属于哪个类别呢?
答案是分类方程结果最大的那个类别,即最接近的那条结对应的类别!
下面将展示整个二维空间是如何被分类的:
mglearn.plots.plot_2d_classification(linear_svm, X, alpha=.7) mglearn.discrete_scatter(X[:, 0], X[:, 1], y) line = np.linspace(-15, 15)for coef, intercept, color in zip(linear_svm.coef_, linear_svm.intercept_, ['b', 'r', 'g']): plt.plot(line, -(line * coef[0] intercept) / coef[1], c=color) plt.xlabel('Feature 0') plt.ylabel('Feature 1') plt.legend(['Class 0', 'Class 1', 'Class 2'], loc=(1.01, 0.3)) plt.show()
通过上图很明白的就看出中间的三角区是如何被分类的了!
线性模型用于分类,分类的原理还要从公式说起。
$y = w[0]*x[0]+w[1]*x[1]+...+w[p]*x[p]+b$
线性模型的公司的结果y
是一个连续的输出结果,如果将y
的值与0
作一个界限上的区分,那y
的值将被分成两个区域。公式的表达如下:
$y = w[0]*x[0]+w[1]*x[1]+...+w[p]*x[p]+b>0$
也就是说,如果该公式(函数)预测的结果值小于0,就归类为-1,如果结果值大于0,就归类为1.
需要重点理解的地方在于:
对于用于回归的线性模型来说,输出y
是特征的线性函数,是直线、平面或超平面(对于更高维的数据集)。
对于用于分类的线性模型,决策边界是输入的线性函数。
不同线性模型算法之间的区别在于:
系数和截距的特定组合对训练集数据拟合好坏的度量方法;
是否使用正则化,以及使用哪种正则化方法。
最觉的两种线性分类算法是Logistic回归和线性支持向量机。前者在linear_model.LogisticRegression
中实现,后者在svm.LinearSVC
(SVC代表支持再是分类器)中实现 。
接下来对这两个模型做一个初步认识吧!
# 在学习之前,先导入这些常用的模块import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport mglearn
下面,将这两个模型用在二分类数据forge
数据集上,并显示模型得出的决策边界。
先展示下二分类的展示图:
# 导入二分类数据X, y = mglearn.datasets.make_forge()mglearn.discrete_scatter(X[:, 0], X[:, 1], y)plt.show()
C:\Users\Administrator\Anaconda3\lib\site-packages\sklearn\utils\deprecation.py:77: DeprecationWarning: Function make_blobs is deprecated; Please import make_blobs directly from scikit-learn warnings.warn(msg, category=DeprecationWarning)
# 导入Logisticfrom sklearn.linear_model import LogisticRegression# 导入LinearSVCfrom sklearn.svm import LinearSVC# 导入二分类数据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=.5, ax=ax, alpha=.7)# 绘制二分类的训练数据mglearn.discrete_scatter(X[:, 0], X[:, 1], y, ax=ax)# 设置标题为模型名称ax.set_title('{}'.format(clf.__class__.__name__))# 设置x坐标轴标签名称ax.set_xlabel('Feature 0')# 设置y坐标轴标签名称ax.set_ylabel('Feature 1')# 在第一个绘图区上显示图例axes[0].legend()plt.show()
C:\Users\Administrator\Anaconda3\lib\site-packages\sklearn\utils\deprecation.py:77: DeprecationWarning: Function make_blobs is deprecated; Please import make_blobs directly from scikit-learn warnings.warn(msg, category=DeprecationWarning)
说明:
forge数据集有两个特征,分别对应X轴与Y轴。
LinearSVC与LogisticRegression得到的决策边界,都是直线,将数据分为了上下两个区域。
两个模型默认使用了L2正则化。
继续探讨:
对于LinearSVC与LogisticRegression而言,决定正则化强度的权衡参数叫做C
。C
值越大,对就的正则化越弱。
也就是说,越大的C
将拥有越上的约束力,即系数的大小更自由,模型对于数据的贴合度将变得更复杂。
如果C
越小,则对系数的约束越大,甚至趋向于0,使模型更能贴合大多数数据,模型也更简单。
下面直接展示一下LinearSVC模型的C
分别取0.01
、1
、100
时模型的决策边界效果:
mglearn.plots.plot_linear_svc_regularization()
对上图的总结:
最左侧的图,C值很小,所以对应强正则化。要求模型更贴合于大多数数据,因此对于图中两个错误的点进行了忽略。
中间的图,C值稍大,由于对模型的约束变小,模型对于数据的反应则变得更加第三一些,决策线向着两个错误的点进行偏移,希望更好的贴合训练数据。
右侧图C值很大,因为对模型的约束很小,导致模型的决策边界要求对所有数据都贴合,造成了过拟合现象。
再来看看使用乳腺癌数据集对LogisticRegression模型做出分析:
# 导入乳腺癌数据from sklearn.datasets import load_breast_cancercancer = load_breast_cancer()# 将数据分为训练集测试集from sklearn.model_selection import train_test_splitX_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('训练集评估分数:', logreg.score(X_train, y_train))print('测试集评估分数:', logreg.score(X_test, y_test))
训练集评估分数: 0.9553990610328639 测试集评估分数: 0.958041958041958
这里模型置信的C
值是1.如果训练集的评分与测试集的评分差不多,那可能存在欠拟合的现象。
现在给模型增大C
值,再看看评估结果:
logreg100 = LogisticRegression(C=100).fit(X_train, y_train)print('训练集评估分数:', logreg100.score(X_train, y_train))print('测试集评估分数:', logreg100.score(X_test, y_test))
训练集评估分数: 0.971830985915493 测试集评估分数: 0.965034965034965
通过增大模型的C
值,发现模型的精度变高了。
现在再减小C
值看看模型的评估分数:
logreg001 = LogisticRegression(C=0.01).fit(X_train, y_train)print('训练集评估分数:', logreg001.score(X_train, y_train))print('测试集评估分数:', logreg001.score(X_test, y_test))
训练集评估分数: 0.9342723004694836 测试集评估分数: 0.9300699300699301
可以看出,模型的精度变小了,并且存在欠拟合的可能。
按照老办法,我们当不同C
值情况下,模型得出的系数图例化,看看结果:
plt.plot(logreg.coef_.T, 'o', label='C=1')plt.plot(logreg100.coef_.T, '^', label='C=100')plt.plot(logreg001.coef_.T, 'v', label='C=0.01')plt.xticks(range(cancer.data.shape[1]), cancer.feature_names, rotation=90)plt.hlines(0, 0, cancer.data.shape[1])plt.ylim(-5, 5)plt.xlabel('Codefficient index')plt.ylabel('Coefficient magnitude')plt.legend()plt.show()
从这个图例可以看出,C
值越小,模型的系数就越趋向于0.
另外,该模型默认使用L2正则,也可以将其改成L1正则,以减少模型使用的特征:
# 评估for C, marker in zip([0.001, 1, 100], ['o', '^', 'v']):lr_l1 = LogisticRegression(C=C, penalty='l1').fit(X_train, y_train)print('训练集,C={0},评估分数={1}'.format(C, lr_l1.score(X_train, y_train)))print('测试集,C={0},评估分数={1}'.format(C, lr_l1.score(X_test, y_test)))# 绘图plt.plot(lr_l1.coef_.T, marker, label='C={}'.format(C))plt.xticks(range(cancer.data.shape[1]), cancer.feature_names, rotation=90)plt.hlines(0, 0, cancer.data.shape[1])plt.ylim(-5, 5)plt.xlabel('Codefficient index')plt.ylabel('Coefficient magnitude')plt.legend(loc=3)plt.show()
训练集,C=0.001,评估分数=0.9131455399061033 测试集,C=0.001,评估分数=0.9230769230769231 训练集,C=1,评估分数=0.960093896713615 测试集,C=1,评估分数=0.958041958041958 训练集,C=100,评估分数=0.9859154929577465 测试集,C=100,评估分数=0.9790209790209791
Ok,上图对于不同C
值所对应的L
正则下的系数分布有了直观的了解,也就明白了对应的约束力。
这里主要需要明白设置L1或L2需要通过参数penalty
来设置。
多分类其实也是一处二分类的模式,它是一对其余的方法。
这里展示一个三类的gf数据:
from sklearn.datasets import make_blobsX, y = make_blobs(random_state=42)mglearn.discrete_scatter(X[:, 0], X[:, 1], y)plt.xlabel('Feature 0')plt.ylabel('Feature 1')plt.legend(['Class 0', 'Class 1', 'Class 2'])plt.show()
然后使用该数据对LinearSVC
分类器进行训练:
linear_svm = LinearSVC().fit(X, y)print('模型斜率集:', linear_svm.coef_.shape)print('模型截距集:', linear_svm.intercept_.shape)
模型斜率集: (3, 2) 模型截距集: (3,)
通过形状可以明白:斜率集有3行,每行代表类别之一的一个系数向量;有2列,每列包含某个特征对应的系数值。而截距是个一维数据,包含每个类别的截距值。
现在将分类器给出的直线进行可视化:
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)line = np.linspace(-15, 15)for coef, intercept, color in zip(linear_svm.coef_, linear_svm.intercept_, ['b', 'r', 'g']):plt.plot(line, -(line * coef[0] + intercept) / coef[1], c=color)plt.ylim(-10, 15)plt.xlim(-10, 8)plt.xlabel('Feature 0')plt.ylabel('Feature 1')plt.legend(['Class 0', 'Class 1', 'Class 2'], loc=(1.01, 0.3))plt.show()
在这里,线条的颜色与各点的颜色是一致的。从图中可以很直观的看到这三个点是如何被分成三类的。
但是,这三条线交叉的地方,有一个空白的三角区,那这个区域属于哪个类别呢?
答案是分类方程结果最大的那个类别,即最接近的那条结对应的类别!
下面将展示整个二维空间是如何被分类的:
mglearn.plots.plot_2d_classification(linear_svm, X, alpha=.7)mglearn.discrete_scatter(X[:, 0], X[:, 1], y)line = np.linspace(-15, 15)for coef, intercept, color in zip(linear_svm.coef_, linear_svm.intercept_, ['b', 'r', 'g']):plt.plot(line, -(line * coef[0] + intercept) / coef[1], c=color)plt.xlabel('Feature 0')plt.ylabel('Feature 1')plt.legend(['Class 0', 'Class 1', 'Class 2'], loc=(1.01, 0.3))plt.show()
通过上图很明白的就看出中间的三角区是如何被分类的了!
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程