题目:假设你是一所大学的管理员,给出一份数据集,里面有每个学生第一次考试成绩、第二次考试成绩以及是否录取的数据,请建立一个逻辑回归模型用来预测学生的录取情况。
下面是我根据视频订正后的代码:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.optimize as opt
from sklearn.metrics import classification_report
# 定义函数sigmoid,方便后续假设函数以sigmoid(z)表示
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 定义代价函数
def computeCost (theta, X, y):
predictions = sigmoid(X @ theta) # 使用 @ 进行矩阵乘法
first = np.multiply(-y, np.log(predictions))
second = np.multiply((1 - y), np.log(1 - predictions))
return np.sum(first - second) / len(X) # 返回标量
# 梯度下降公式,这里只计算一个步长
def gradient(theta, X, y):
return (1/len(X))*(X.T@(sigmoid(X@theta)-y))
# 预测函数
def predict(X, theta):
probability = sigmoid(X@theta)
return [1 if x >= 0.5 else 0 for x in probability]
data = pd.read_csv('ex2data1.txt', names = ['first-score', 'second-score', 'admitted'])
sns.set(context='notebook', style='whitegrid')
sns.lmplot(x='first-score', y='second-score', hue='admitted', #定义数据子集的变量,绘制在图中
data=data,
height=6,
fit_reg=False,
scatter_kws={"s": 50}
)
plt.show()
data.insert(0, 'ONE', 1)
X = np.array(data.iloc[:, :-1].values) # 特征矩阵 (100, 3)
y = np.array(data.iloc[:, -1].values) # 将 y 转换为 (100,)
theta = np.zeros(3)
print(computeCost(theta, X, y))
print(gradient(theta, X, y))
print("X shape:", X.shape) # 应该是 (m, n)
print("y shape:", y.shape) # 应该是 (m, 1)
print("Initial theta shape:", theta.shape) # 应为 (3, 1)
print("Theta (flattened):", theta.flatten()) # 保证在res中theta是一维数组
res = opt.minimize(fun=computeCost, x0=theta.flatten(), args=(X, y), method='Newton-CG', jac=gradient)
print(res)
last_theta=res.x
y_pred=predict(X, last_theta)
print(classification_report(y, y_pred))
coef = -(res.x/ ((res.x)[2])) #将result[0]中的每一个数除以result[0]中的第三个元素,然后取相反值
print(coef)
x = np.arange(130, step=0.1) #默认起点为0,终点为130,步长为0.1的数组
y = coef[0] + coef[1]*x
sns.set(context='notebook',style='whitegrid',palette='bright')
sns.lmplot(x='first-score', y='second-score', hue='admitted', #定义数据子集的变量,绘制在图中
data=data,
height=6,
fit_reg=False,
scatter_kws={"s": 50}
)
plt.plot(x, y, 'grey') #plot为画图函数,plot(x变量,y变量,‘线条颜色和;类型’),设置线条颜色为灰色
plt.xlim(0, 130) #设置x轴的范围
plt.ylim(0, 130) #设置y轴的范围
plt.title('Decision Boundary') #设置标题
plt.show()
输出的数据散点图和算出决策边界后的图像如下:
原始数据录取情况散点图
带有决策边界,拟合好的图
输出如下:
0.6931471805599453
[ -0.1 -12.00921659 -11.26284221]
X shape: (100, 3)
y shape: (100,)
Initial theta shape: (3,)
Theta (flattened): [0. 0. 0.]
fun: 0.20576462118328537
jac: array([ 0.00121975, -0.00705683, -0.0064625 ])
message: 'Optimization terminated successfully.'
nfev: 71
nhev: 0
nit: 25
njev: 160
status: 0
success: True
x: array([-21.50746203, 0.17701971, 0.17190147])
precision recall f1-score support
0 0.87 0.85 0.86 40
1 0.90 0.92 0.91 60
accuracy 0.89 100
macro avg 0.89 0.88 0.88 100
weighted avg 0.89 0.89 0.89 100
[125.1150549 -1.02977425 -1. ]
进程已结束,退出代码0
在作业讲解视频中,如果使用的是跟视频一样的代码,读取特征方法get_X(df)的最后一句,return data.iloc[:, :-1].as_matrix(),用新版本的pandas包会报错('DataFrame' object has no attribute 'as_matrix'),因为新版本的pandas已经去除了as_matrix()方法,只需要把as_matrix()改为values即可。(小编用不一样的方法取值的输出也跟视频输出的值不一样,可能是库的问题)
第二次吴恩达机器学习作业逻辑回归作业总结:在此次作业中学习到了可以使用在视频中说的共轭梯度法来优化梯度下降中的参数,从而只需要计算一个步长而不需要进行完整的梯度下降。但本次作业中小编遇到了许多显示矩阵维度的问题,这说明在算法的计算过程中,矩阵运算的维度需要严格按照其运算规律,希望在以后的作业中能够在定义参数还有特征量等矩阵时能注意到这点,可以通过输出其维度的形式来排除错误以及确保报错是语法问题而不是定义问题。