上一篇文章博主讲解了用线性回归解决房价预测问题,现在不知不觉已经到五月份了,
大概还有两个月左右不少小伙伴就要期末考试了,那这次就用逻辑回归预测一下考试是否能通过吧!
我们想一想,当我们要解决一个分类问题,尤其是一个二分类问题时,如果我们用线性回归去解决就会面临这样一个问题:样本量变大后,准确率会下降。这时为了更好地解决这种分类问题,我们就需要采用逻辑回归的方法了。
我们先看一看逻辑回归方程
再来看一看该方程所对应的图形
可以发现当样本值越大y越接近1,样本值越小y越接近0,以0.5为分界点就可以将y分成以下两种情况。
这时负样本就是0,正样本就是1,0和1就是我们给样本定义的标签。在考试通过问题中,可以用1代表通过(pass),用0代表失败(failed),这样就可以通过标签0和1将失败和通过进行一个分类,就可以很好地解决二分类问题了。
当问题更复杂时,可以用g(x)代替x,然后就可以根据g(x)寻找最合适的决策边界从而解决二分类问题
比如下面这个图形:
此时虚线部分就是它的决策边界
任务:
基于examdata.csv数据,建立逻辑回归模型 预测Exam1 = 70, Exam2 = 60时,该同学在Exam3是 passed or failed; 建立二阶边界,提高模型准确度。
先来建立一阶边界看看准确率:
#加载数据
import pandas as pd
import numpy as np
data = pd.read_csv('examdata.csv')
data.head() #数据预览
#可视化数据
%matplotlib inline
from matplotlib import pyplot as plt #导入相关包
fig1 = plt.figure() #新建一个画布
plt.scatter(data.loc[:,'Exam1'],data.loc[:,'Exam2']) #导入数据
plt.title('Exam1-Exam2') #图形名称
plt.xlabel('Exam1') #横坐标
plt.ylabel('Exam2') #纵坐标
plt.show() #展示图形
#添加标签
mask = data.loc[:,'Pass'] == 1 #如果pass等于1就是true,否则就是false
print(mask)#预览 这里可以和最开始的数据预览图比较起来看,前五项Pass的值是0,0,0,1,1,所以这里前五项的结果就如下图所示了。
#将通过考试和未通过考试的用图形来区分开
fig2 = plt.figure()
passed = plt.scatter(data.loc[:,'Exam1'][mask],data.loc[:,'Exam2'][mask])
failed = plt.scatter(data.loc[:,'Exam1'][~mask],data.loc[:,'Exam2'][~mask]) #这里的~mask是取反,可以理解为0
plt.title('Exam1-Exam2')
plt.xlabel('Exam1')
plt.ylabel('Exam2')
plt.legend((passed,failed),('passed','failed'))
plt.show()
#将数据赋值给相关变量
x = data.drop(['Pass'],axis=1) #这里是去除pass那一列
y = data.loc[:,'Pass'] #将pass那一列的值赋给y
x1 = data.loc[:,'Exam1']#将Exam1那一列的值赋给x1
x2 = data.loc[:,'Exam2']#将Exam2那一列的值赋给x2
x1.head() #这里以x1为例看一下预览效果,正确;
print(x.shape,y.shape) #看一下数据维度
#建立模型以及训练模型
from sklearn.linear_model import LogisticRegression
LR = LogisticRegression()
LR.fit(x,y) #训练模型
#预测结果
y_predict = LR.predict(x)
print(y_predict)
#预测结果
#评估模型表现 看一下准确率
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y,y_predict)
print(accuracy)
准确率达到了0.89,虽然感觉挺高的,但是判断错误的还是很多的
LR.intercept_ #截距
# θo,θ1,θ2
theta0 = LR.intercept_
theta1,theta2 = LR.coef_[0][0],LR.coef_[0][1]
print(theta0,theta1,theta2)
x2_new = -(theta0+theta1*x1)/theta2
print(x2_new)
fig3 = plt.figure()
passed=plt.scatter(data.loc[:,'Exam1'][mask],data.loc[:,'Exam2'][mask])
failed=plt.scatter(data.loc[:,'Exam1'][~mask],data.loc[:,'Exam2'][~mask])
plt.plot(x1,x2_new) #画出决策边界
plt.title('Exam1-Exam2')
plt.xlabel('Exam1')
plt.ylabel('Exam2')
plt.legend((passed,failed),('passed','failed'))
plt.show()
#建立一个二阶的边界
#创建新数据
x1_2 = x1*x1
x2_2 = x2*x2
x1_x2 = x1*x2
x_new = {'x1':x1,'x2':x2,'x1_2':x1_2,'x2_2':x2_2,'x1_x2':x1_x2}#将所有数据放到一个字典里面
x_new = pd.DataFrame(x_new) #方便后面进行模型数据的加载
print(x_new)#预览
#建立并训练一个新模型
LR2 = LogisticRegression()
LR2.fit(x_new,y)
#模型评估
y2_predict = LR2.predict(x_new)
accuracy2 = accuracy_score(y,y2_predict)
print(accuracy2)
准确率达到了百分之百,可以看处通过二阶边界建立的模型比通过一阶边界建立的模型准确率高很多。
x1_new = x1.sort_values() #将x1_new从小到大排序
print(x1_new) #预览
这里是保证后面画图不出现交叉,使图形更好看、更直观
#θo,θ1,θ2,θ3,θ4,θ5
theta0 = LR2.intercept_
theta1,theta2,theta3,theta4,theta5 = LR2.coef_[0][0],LR2.coef_[0][1],LR2.coef_[0][2],LR2.coef_[0][3],LR2.coef_[0][4]
a = theta4
b = theta5*x1_new+theta2
c = theta0+theta1*x1_new+theta3*x1_new*x1_new
x2_new_boundary = (-b+np.sqrt(b*b-4*a*c))/(2*a)
print(x2_new_boundary)
θo,θ1,θ2,θ3,θ4,θ5的求解可以根据以下公式:
因为成绩都是正数,所以就不用图中x2那个表达式了。
fig5 = plt.figure()
passed=plt.scatter(data.loc[:,'Exam1'][mask],data.loc[:,'Exam2'][mask])
failed=plt.scatter(data.loc[:,'Exam1'][~mask],data.loc[:,'Exam2'][~mask])
plt.plot(x1_new,x2_new_boundary) #画出决策边界
plt.title('Exam1-Exam2')
plt.xlabel('Exam1')
plt.ylabel('Exam2')
plt.legend((passed,failed),('passed','failed'))
plt.show()
附上数据集,需要的小伙伴自取
链接: https://pan.baidu.com/s/1iv7yvWdqhSK9pWLj3dzhEA .
提取码:spyc
本次学习笔记就到这里啦! thanks~~