四、线性分类与回归
1 线性函数
大家知道,在二维空间内,线性函数可以表达为:
y=kx+b
或者
ax+by=0
在第一个表达式中k叫做斜率,b叫做截距(即x=0的时候,直线与y轴的交叉点)
把线性函数扩展到n维空间,其表达式为:
y=k1x1+k2x2+…kn-1xn-1+b
或者
a1x1+ a2x2+…an-1xn-1+ anxn=0
同样在第一个表达式中k1…kn-1叫做斜率,b叫做截距(即x1= x2=…=xn-1=0的时候,直线与y轴的交叉点)
2 线性分类
这里,我们用一个例子来说明线性分类的使用。假设一个函数:
y=a1x1+ a2x2+ a3x3+ a4x4
通过y的值评价西瓜的好坏,其值落在[0-1]之间(数学里这样的函数很多,比如sigmoid函数,通过某种变化就可以让值落在[0-1]之间)。x1表示敲瓜的清脆声;x2表示瓜的颜色;x3表示瓜楴的长度;x4表示瓜比重。当0<y<=0.5为好瓜,当0.5<y<=1< span="">为坏瓜。分类算法的目标就是通过训练找到a1 ,a2 ,a3 和a4 使得判断更为准确。</y<=1<>
3 线性回归
在二维图上分布着一些点,我们通过算法找出一条直线,使得所有点到这条直线的均差最小,也就是说这条线拟合了这些点。
案例:著名学者查尔斯·达尔文的表弟的高尔顿,发现子女的身高存在这样的关系:
Y = 0.516X+33.73(其中Y :子带身高(英寸),X:父代身高(英寸))。
下面我们主要来介绍线性分类。
4 逻辑回归
虽然叫逻辑回归,但是它本质上是一个分类问题。它通过sklearn.linear_model.LogisticRegression来实现。
sklearn.linear_model.LogisticRegression(penalty='l2', dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver='liblinear', max_iter=100, multi_class='ovr', verbose=0, warm_start=False, n_jobs=1)
4.1主要参数
参数 | 解释 |
---|---|
penalty | 字符串,'L1' or'L2', 默认:'L2'。用于指定惩罚中使用的规范。"牛顿CG"、"SAG"和"LBFGS"解算器只支持L2惩罚。版本0.19:La1惩罚与SAGA求解器(允许"多项"+L1) |
C | 浮点数, 默认: 1.0。正则化强度的逆;必须是正浮点。像支持向量机一样,较小的值指定更强的正则化。 |
4.2主要属性
属性 | 解释 |
---|---|
classes_ | ndarray of shape (n_classes, ).分类器已知的类标签列表。 |
coef_ | ndarray of shape (1, n_features) or (n_classes, n_features).决策函数中特征的系数。 |
intercept_ | ndarray of shape (1,) or (n_classes,). 截距(又称偏差)添加到决策函数中。 |
n_iter_ | ndarray of shape (n_classes,) or (1, ).所有类的实际迭代次数。如果是二进制或多项式,它只返回1个元素。对于liblinear solver,只给出所有类的最大迭代次数。 |
4.3主要方法
decision_function(X) | 预测样本的置信度得分。 |
---|---|
densify() | 将系数矩阵转换为密集数组格式。 |
fit(X, y[, sample_weight]) | 根据给定的训练数据对模型进行拟合。 |
get_params([deep]) | 获取此估计器的参数。 |
predict(X) | 预测X中样本的类标签。 |
predict_log_proba(X) | 预测概率估计的对数。 |
predict_proba(X) | 概率估计。 |
score(X, y[, sample_weight]) | 返回给定测试数据和标签的平均精度。 |
set_params(**params) | 设置此估计器的参数。 |
sparsify() | 将系数矩阵转换为稀疏格式。 |
4.4 代码
4.4.1逻辑回归分析make_blobs数据集
#LogisticRegression分析make_blobs数据
def LogisticRegression_for_make_blobs():
myutil = util()
X,y = make_blobs(n_samples=500,centers=5, random_state=8)
clf = LogisticRegression(max_iter=100000)
clf.fit(X,y)
print('模型正确率:{:.2%}'.format(clf.score(X,y)))
其中
util类在Util.py文件中定义。
获得结果
模型正确率:94.80%
在util类定义了一个画散点图方法:draw_scatter和学习曲线的函数:plot_learning_curve
#画一个算法的散点图
def draw_scatter(self,X, y,clf,title):
plt.scatter(X[:,0],X[:,1],c=y,cmap=plt.cm.spring,edgecolor='k')
x_min,x_max = X[:,0].min()-1,X[:,0].max()+1
y_min,y_max = X[:,1].min()-1,X[:,1].max()+1
xx,yy = np.meshgrid(np.arange(x_min,x_max,.02),np.arange(y_min,y_max,.02))#生成网格点坐标矩阵
Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])#预测数据集X的结果
Z = Z.reshape(xx.shape)
plt.pcolormesh(xx, yy, Z,shading='auto',cmap=plt.cm.Spectral)#绘制分类图
plt.scatter(X[:,0],X[:,1],c=y,cmap=plt.cm.spring,edgecolor='k')
plt.xlim(xx.min(),xx.max())#设置或查询 x 轴限制
plt.ylim(yy.min(),yy.max())#设置或查询 y 轴限制
self.show_pic(title)
#定义一个绘制学习曲线的函数
def plot_learning_curve(self,est, X, y,title):#learning_curve:学习曲线
tarining_set_size,train_scores,test_scores = learning_curve(
est,X,y,train_sizes=np.linspace(.1,1,20),cv=KFold(20,shuffle=True,random_state=1))
estimator_name = est.__class__.__name__
line = plt.plot(tarining_set_size,train_scores.mean(axis=1),'o-',label=u'训练得分'+estimator_name,c='r')
plt.plot(tarining_set_size,test_scores.mean(axis=1),'o-',label=u'测试得分'+estimator_name,c='g')
plt.grid()
plt.xlabel(u'训练设置值')
plt.ylabel(u"得分")
plt.ylim(0,1.1)
plt.legend(loc='lower right')
我们把make_blobs数据集通过逻辑回归处理后的散点图画出来。
title = "逻辑回归_make_blobs"
myutil.draw_scatter(X,y,clf, title)
myutil.plot_learning_curve(LogisticRegression(max_iter=100000),X,y,title)
myutil.show_pic(title)
散点分布图
由此可见由于make_blobs方法中定义了5个类,500个点(n_samples=500,centers=5),其分布在同中一目了然。
学习曲线图
学习得分,随着样本的变化波动不是很大,基本上在可以接收的范围内。
下面我们分别用LogisticRegression分析一下乳腺癌数据、鸢尾花数据和红酒数据
4.4.2逻辑回归分析乳腺癌数据集
#LogisticRegression分析乳腺癌数据
def LogisticRegression_for_load_breast_cancer():
myutil = util()
X,y = datasets.load_breast_cancer().data,datasets.load_breast_cancer().target
X1 = datasets.load_breast_cancer().data[:,:2]
print("X的shape={},正样本数:{},负样本数:{}".format(X.shape, y[y == 1].shape[0], y[y == 0].shape[0]))
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 训练模型
clf = LogisticRegression(max_iter=100000)
clf.fit(X_train, y_train)
# 查看模型得分
train_score = clf.score(X_train, y_train)
test_score = clf.score(X_test, y_test)
print("乳腺癌训练集得分:{trs:.2%},乳腺癌测试集得分:{tss:.2%}".format(trs=train_score, tss=test_score))
title = "逻辑回归_乳腺癌数据"
myutil.plot_learning_curve(LogisticRegression(max_iter=100000),X,y,title)
myutil.show_pic(title)
clf = LogisticRegression(max_iter=100000).fit(X1,y)
myutil.draw_scatter_for_clf(X1,y,clf,title)
说明
在乳腺癌数据集中,总共有569个样本,每个样本有30属性,其中正样本数(良性):357,负样本数(恶性):212。最后获得的输出如下:
乳腺癌训练集得分:94.95%,乳腺癌测试集得分:97.37%
散点图
分类为两个结果的,我们成为二分类
学习曲线
学习曲线也是在可以接受范围之内。
4.4.3逻辑回归分析鸢尾花数据集
#LogisticRegression分析鸢尾花数据
def LogisticRegression_for_load_iris():
myutil = util()
X,y = datasets.load_iris().data,datasets.load_iris().target
X1 = datasets.load_iris().data[:,:2]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
clf = LogisticRegression(max_iter=100000)
clf.fit(X_train, y_train)
train_score = clf.score(X_train, y_train)
test_score = clf.score(X_test, y_test)
print("鸢尾花训练集得分:{trs:.2%},鸢尾花测试集得分:{tss:.2%}".format(trs=train_score, tss=test_score))
title = "逻辑回归_鸢尾花数据"
myutil.plot_learning_curve(LogisticRegression(max_iter=100000),X,y,title)
myutil.show_pic(title)
clf = LogisticRegression(max_iter=100000).fit(X1,y)
myutil.draw_scatter_for_clf(X1,y,clf,title)
最后输出
鸢尾花训练集得分:96.67%,鸢尾花测试集得分:100.00%。
散点图
学习曲线
数据少的时候,测试集的得分比较低,随着测试集数据的增加而增加。
4.4.4逻辑回归分析红酒数据集
#LogisticRegression分析红酒数据
def LogisticRegression_for_load_wine():
myutil = util()
X,y = datasets.load_wine().data,datasets.load_wine().target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
X1 = datasets.load_wine().data[:,:2]
clf = LogisticRegression(max_iter=100000)
clf.fit(X_train, y_train)
train_score = clf.score(X_train, y_train)
test_score = clf.score(X_test, y_test)
print("红酒训练集得分:{trs:.2%},红酒测试集得分:{tss:.2%}".format(trs=train_score, tss=test_score))
title = "逻辑回归_红酒数据"
myutil.plot_learning_curve(LogisticRegression(max_iter=100000),X,y,title)
myutil.show_pic(title)
clf = LogisticRegression(max_iter=100000).fit(X1,y)
myutil.draw_scatter_for_clf(X1,y,clf,title)
最后输出
红酒训练集得分:100.00%,红酒测试集得分:94.44%
散点图
学习曲线
同鸢尾花一样,在数据少的时候,测试集的得分比较低,随着测试集数据的增加而增加。
由于我们这里用的是线性分类,所以在散点图中可以看出,分类的边界是一条直线。