逻辑回归
逻辑回归是一种分类算法,在这部分的练习中,你将建立一个逻辑回归模型来预测一个学生是否能进入大学。假设你是一所大学的行政管理人员,你想根据两门考试的结果,来决定每个申请人是否被录取。你有以前申请人的历史数据,可以将其用作逻辑回归训练集。对于每一个训练样本,你有申请人两次测评的分数以及录取的结果。为了完成这个预测任务,我们准备构建一个可以基于两次测试评分来评估录取可能性的分类模型。
首先准备预训练的数据‘ex2data1.txt’和‘ex2data2.txt’两个文件,库文件包括:
import scipy.optimize as opt
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
首先将文件利用pandas函数从txt文件中提取出来,对数据进行可视化处理:
data = pd.read_csv('ex2data1.txt',header=None,names=['exam1','exam2','admitted'])
print(data.head())
exam1 exam2 admitted
0 34.623660 78.024693 0
1 30.286711 43.894998 0
2 35.847409 72.902198 0
3 60.182599 86.308552 1
4 79.032736 75.344376 1
定义一个函数,用来将数据可视化:
def plot_data():
positive = data2[data['admitted'].isin([1])]
negative = data2[data['admitted'].isin([0])]
plt.scatter(positive['exam1'], positive['exam2'], s=50, c='b', label='admitted')
plt.scatter(negative['exam1'], negative['exam2'], s=50, c='r', marker='x', label='Not admitted')
plt.legend()
plt.title('raw_data')
plt.xlabel('exam1')
plt.ylabel('exam2')
return plt
plt = plot_data(data)
plt.show()
把数据data根据admitted列是否为‘1’,分为positive
和negative
,然后利用 matplotlib.pyplot
库画出其散点图:
定义一个takeArray函数,将数据以矩阵的形式提取出来。在训练集的左侧插入一列全为“1”的列,以便计算即x0=1,theta默认为0.
def takeArray(data):
if 'Ones' not in data.columns:
data.insert(0, 'Ones', 1)
clos = data.shape[1]
X = data.iloc[:,0:clos-1]
X = np.array(X)
y = data.iloc[:,-1]
y = np.array(y)
theta = np.zeros(X.shape[1])
return X,y,theta
检查一下:
X,y,theta = takeArray(data)
print(X.shape,y.shape,theta.shape)
(118, 3) (3,) (118,)
sigmoid函数:
def sigmoid(z):
return 1/(1+np.exp(-z))
接下来定义经过log凸优化之后的代价函数:
def computeCost(theta,X,y):
first = (-y)*np.log(sigmoid(X@theta))
second = (1-y)*np.log(1-sigmoid(X@theta))
return np.mean(first-second)
X@theta相当于X.dot(theta)是计算X与theta的内积,看下没被优化过theta的cost函数是多少:
print(computeCost(theta,X,y))
0.6931471805599453
定义梯度下降函数:
def gradientDescent(theta,X,y):
return (X.T@(sigmoid(X@theta)-y))/len(X)
求解final_theta:
final_theta = gradientDescent(theta,X,y)
print(final_theta)
#[ -0.1 -12.00921659 -11.26284221]
或者采用高级优化的方法:
final_theta = opt.minimize(fun=computeCost, x0=theta, args=(X, y), method='tnc',jac=gradientDescent).x
print(final_theta)
#[-25.1613186 0.20623159 0.20147149]
学习好了参数θ后,我们来用这个模型预测某个学生是否能被录取。
接下来,我们需要编写一个函数,用我们所学的参数theta来为数据集X输出预测。然后,我们可以使用这个函数来给我们的分类器的训练精度打分。
def predict(theta,X):
probability = sigmoid(X@theta)
return [1 if x >= 0.5 else 0 for x in probability] #return a list
def predictions(final_theta, X,y):
predictions = predict(final_theta, X)
correct = [1 if a == b else 0 for (a, b) in zip(predictions, y)]
accuray = sum(correct) / len(X)
return accuray
根据逻辑回归的假设模型,定义一个当实际值大于等于0.5时被认为是1,否则是0的一个分类器。predictions函数将最终训练好的theta放进分类器,输出一串0和1与y作比较,然后求其均值。反映了我们训练好的theta的拟合的准确率。
#未优化前的theta
print(predictions(theta,X,y))#0.6
#梯度下降法求解的最优theta在0.4
#高级优化后的theta
print(predictions(final_theta1,X,y))#0.89
画出决策边界,
x1 = np.arange(20,110,step=0.1)
x2 = -(final_theta1[0] + x1 * final_theta1[1]) / final_theta1[2]
plt= plot_data(data)
plt.plot(x1,x2)
plt.show()