不同于线性回归是预测出来具体的值,逻辑回归本质上是分类问题,逻辑回归将值映射到(0,1)集合。
逻辑回归是根据现有数据对分类边界线建立回归公式,以此进行分类。逻辑回归在线性回归的基础上,通过引入sigmoid函数,将线性回归的输出值映射到(0,1)上,接下来使用阈值将结果转换成0或1就能够完成两类问题的预测。
问题描述:某银行搜集乐园用户贷款,收入和信用卡是否逾期的信息,使用这些数据建立一个能预测信用卡逾期情况的逻辑回归模型,使用梯度下降法确定模型参数,并绘图显示损失函数的变化过程。
数据部分示意图如下
初始数据可视化如下
经过逻辑回归后分界线可视化如下
损失函数可视化如下 可以看到随着迭代次数的增加损失函数一直在减小 直到收敛
源代码如下
import numpy as np import pandas as pd import matplotlib; matplotlib.use('TkAgg') df=pd.read_csv(r"credit-overdue.csv") print(df.head()) from matplotlib import pyplot as plt matplotlib.rcParams['font.family'] = 'SimHei' matplotlib.rcParams['font.size'] = 10 matplotlib.rcParams['axes.unicode_minus']=False plt.figure(figsize=(10,6)) map_size={0:20,1:100} size=list(map(lambda x:map_size[x],df['overdue'])) plt.scatter(df['debt'],df['income'],s=size,c=df['overdue'],marker='v') plt.show() #step 3 def sigmoid(z):#逻辑函数 把值放缩到0 1之间 sigmoid=1/(1+np.exp(-z)) return sigmoid def loss(h,y):#损失函数 loss=(-y*np.log(h)-(1-y)*np.log(1-h)).mean() return loss def gradient(X,h,y):#梯度下降 gradient=np.dot(X.T,(h-y)/y.shape[0]) return gradient #逻辑回归函数 def Logistic_Regression(x,y,lr,num_iter): intercept=np.ones((x.shape[0],1)) x=np.concatenate((intercept,x),axis=1) w=np.zeros(x.shape[1]) l_list=[] for i in range(num_iter):#梯度迭代下降 z=np.dot(x,w)#线性函数 h=sigmoid(z) g=gradient(x,h,y) w-=lr*g z=np.dot(x,w) h=sigmoid(z) l=loss(h,y) l_list.append(l) return l,w x=df[['debt','income']].values y=df['overdue'].values lr=0.01 num_iter=30000 l_y=Logistic_Regression(x,y,lr,num_iter) L=Logistic_Regression(x,y,lr,num_iter) print("第一个为损失函数值 第二个为梯度下降") print(l_y) plt.figure(figsize=(10,6)) map_size={0:20,1:100} size=list(map(lambda x:map_size[x],df['overdue'])) plt.scatter(df['debt'],df['income'],s=size,c=df['overdue'],marker='v') x1_min,x1_max=df['debt'].min(),df['debt'].max() x2_min,x2_max=df['income'].min(),df['income'].max() xx1,xx2=np.meshgrid(np.linspace(x1_min,x1_max),np.linspace(x2_min,x2_max)) grid=np.c_[xx1.ravel(),xx2.ravel()] probs=(np.dot(grid,np.array([L[1][1:3]]).T)+L[1][0]).reshape(xx1.shape) plt.contour(xx1,xx2,probs,levels=[0],linewidths=1,colors='red') plt.show() ''' plt.plot([i for i in range(len(l_y))],l_y) plt.xlabel("迭代次数") plt.ylabel("损失函数") plt.show() '''