通过以往学生的两门考试成绩和录取结果建立逻辑回归模型来预测新学生能否被录取。
一、引入库和导入文件
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
df=pd.read_csv('C:/Users/Administrator/AppData/Local/Temp/Temp1_machine-learning-ex2.zip/machine-learning-ex2/ex2/ex2data1.txt',
names=['成绩一','成绩二','录取'])
二、将数据可视化
matplotlib.rcParams['font.sans-serif']=['SimHei']#用黑体显示中文
positive=df[df['录取'].isin([1])] # 正的表示被录取
negetive=df[df['录取'].isin([0])] #负的表示没有被录取
fig,ax=plt.subplots(figsize=(8,6))
ax.scatter(positive['成绩一'],positive['成绩二'],c='r',label='被录取')
ax.scatter(negetive['成绩一'],negetive['成绩二'],c='b',marker='x',label='未被录取')
# 将图例显示在上方
box = ax.get_position()
ax.set_position([box.x0,box.y0,box.width,box.height*0.8])
ax.legend(loc='center left',bbox_to_anchor=(0.2,1.12),ncol=3)
ax.set_xlabel('成绩一')
ax.set_ylabel('成绩二')
plt.show()
三、建立模型
1.定义sigmoid函数
# 定义sigmoid函数
def sigmoid(z):
return 1/(1+np.exp(-z))
#将sigmoid函数的图像画出来
matplotlib.rcParams['axes.unicode_minus']=False
#这一行代码的作用是:在matplotlib绘图中,可以显示负号
x1=np.arange(-10,10,0.1)
plt.plot(x1,sigmoid(x1))
plt.show()
2.初始化各变量
X=df.loc[:,['ones','成绩一','成绩二']]
y=df.loc[:,'录取']
X=np.array(X)
y=np.array(y)
theta=np.zeros(X.shape[1])
检查X,y,theta各自的维数
3.定义代价函数
def cost(theta,X,y):
first=y@np.log(sigmoid(X@theta))
second=(1-y)@np.log(1-sigmoid(X@theta))
return (first+second)/(-len(X))
cost(theta,X,y) # 0.6931471805599453
4.定义梯度函数(即偏导数)
def gradient(theta,X,y):
return (X.T@(sigmoid(X@theta)-y))/(len(X))
gradient(theta,X,y)
#array([ -0.1 , -12.00921659, -11.26284221])
4.使用高级优化算法进行梯度下降
import scipy.optimize as opt
result =opt.fmin_tnc(func=cost,x0=theta,fprime=gradient,args=(X,y))
result
#(array([-25.16131858, 0.20623159, 0.20147149]), 36, 0)
cost(result[0],X,y) #0.20349770158947472
或者(这两种方法是等价的)
result1=opt.minimize(fun=cost,x0=theta,args=(X,y),method='TNC',jac=gradient)
result1
注意:
如果要将cost函数和gradient函数带入到高级优化算法中,那么(1)cost函数和gradient函数的第一个参数应该是theta,否则会报错!
(2)y和theta都应该是一维的array形式,如(100,)和(3,),否则会报错!
5.最合适的参数theta已经求出,接下来要做的就是定义预测函数
def predict(theta,X):
probability=sigmoid(X@theta)
return [1 if x>=0.5 else 0 for x in probability ]
finally_theta=result[0]
predictions=predict(finally_theta,X)
# 将训练集中的特征变量带入到模型中,把得到的目标变量和实际的标签变量进行比较,从而得到模型的预测精度
correct=[1 if a==b else 0 for (a,b) in zip(predictions,y)]
accuracy=sum(correct)/len(correct)
accuracy # 0.89
或者用sklearn中的方法进行检验,计算预测精度
from sklearn.metrics import classification_report
print(classification_report(predictions,y))
6.决策边界
这个模型的决策边界是线性的
x1=np.arange(120,step=0.1) # 要表明关键字step,否则会报错
x2=(finally_theta[0]+finally_theta[1]*x1)/(-finally_theta[2])
fig,ax=plt.subplots(figsize=(8,6))
ax.scatter(positive['成绩一'],positive['成绩二'],c='b',label='被录取')
ax.scatter(negetive['成绩一'],negetive['成绩二'],c='r',label='未录取')
ax.plot(x1,x2,c='r')
ax.set_xlim(0,120)
ax.set_ylim(0,120)
ax.set_xlabel('x1')
ax.set_ylabel('x2')
ax.set_title('决策边界')
plt.show()