数据集为学生录取情况
第一部分-自定义函数实现逻辑回归
首先构建自己的梯度下降,sigmoid函数
#载入模块省略#
#构建sigmoid函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def predict(theta, X):
prob = sigmoid(X * theta.T) #根据sigmoid函数预测admit的概率
return [1 if a >= 0.5 else 0 for a in prob] #根据admit的概率设定阈值,大于0.5计为1,否则为0
#梯度下降算法函数,X/y是输入变量,theta是参数,alpha是学习率,m是实例,numIter梯度下降迭代次数
def gradientDescent(X, y, theta, alpha, m, numIter):
XTrans = X.transpose() #矩阵转置
#在1-numIterations之间for循环
for i in range(0,numIter):
theta = np.matrix(theta) #将theta转化为矩阵
pred = np.array(predict(theta, X)) #将预测值转化为数组
loss = pred - y #预测值减去实际值
gradient = np.dot(XTrans, loss) / m #计算梯度
theta = theta - alpha * gradient #参数theta的计算,即更新法则
return theta
首先加载数据,进行可视化
df=pd.read_csv('..\data/5_logisitic_admit.csv')
df.insert(1,"ones",1)#线性回归,X=(1,x1,x2,...)
df.head(10)
postive=df[df['admit']==1]
negative=df[df['admit']==0]
fig,ax=plt.subplots(figsize=(8,5))
ax.scatter(postive['gre'],postive['gpa'],s=30,c='b',marker='o',label='admit')
ax.scatter(negative['gre'],negative['gpa'],s=30,c='r',marker='x',label='not admit')
ax.legend()
ax.set_xlabel('gre')
ax.set_ylabel('gpa')
image.png
结果可以看出高gre(入学成绩),高gpa(绩点)会有更好的admit率
梯度下降求解
X = df.iloc[:,1:4] #取df的后3列为X变量
y = df['admit'] #设置y变量
X = np.array(X.values)
y = np.array(y.values)
m, n = np.shape(X) #设置训练样本值m,变量个数n
theta = np.ones(n) #初始化
X.shape, theta.shape, y.shape #检查
numIter = 1000 #迭代次数
alpha = 0.00001 #学习率
theta = gradientDescent(X, y, theta, alpha, m, numIter)
#采用构造的gradientDescent求解theta
print(theta)
image.png
得到的结果表达 Z=0.9977...-0.07331X1+0.9918...X2
预测准确率
pred = predict(theta, X) #采用sigmiod函数来预测y
correct = [1 if ((a == 1 and b == 1) or (a == 0 and b == 0)) else 0 for (a, b) in zip(pred, y)]
#将预测为1.实际也为1;预测为0.实际也为0的均记为1
accuracy = (sum(map(int, correct)) % len(correct))
#采用加总correct值来计算预测对的个数
print("accuracy=""{:.2f}".format(100*accuracy/m))
最后的结果只有43%,可以说是准确率是非常低了
第二部分-采用sklearn做逻辑回归
只需要使用logsitcRegression即可
#直接调用sklearn logisticregression方法
from sklearn.linear_model.logistic import LogisticRegression
lf=LogisticRegression()
lf.fit(X,y)
lf.coef_
pred_sk=lf.predict(X)
corrtect=[1 if ((a ==1 and b==1)or (a==0 and b==0)) else 0 for (a,b) in zip(pred_sk,y)]
accuracy=(sum(map(int,corrtect))%len(corrtect))
print("accuracy=""{:.2f}".format(100*accuracy/m))
print(pred_sk)
image.png
最后得到的准确率为75.5%远高于第一部分自己设置的函数。
虽然自己编写的代码复杂,但这种方法很粗糙,求解中也没有加入正则化参数,惩罚项来进一步优化算法。
对于LogistRegression模块也可以自己设定正则化参数,solver优化方法等,这将是对逻辑回归的下一步学习重点。