Logistic回归详解

mac2025-07-10  7

logistic回归详解

1 原理讲解

算法结构如下图所示:

1.1 前向传播过程

1.2 反向传播过程

2 向量化实现方法

3 代码实现

为了便于理解,首先采用循环的形式实现。正向传播计算损失函数,梯度下降法反向传播更新参数。代码实现如下:

# -*- coding: utf-8 -*- """ Created on Thu Oct 24 21:27:14 2019 @author: Iseno_V """ import math import random #模型参数 y=w1*x1+w2*x2+b w1=random.random() w2=random.random() b=random.random() #生成训练集样本,本例子中训练集分为y轴以上和y轴以下两种不同类型的点 X=[]#训练集样本 Y=[]#训练集标签 for i in range(1000): X.append([random.random()*10.0,-random.random()*10.0]) Y.append(0) for i in range(1000): X.append([random.random()*10.0,random.random()*10.0]) Y.append(1) I = 1000#迭代步数 alpha=0.1#学习率 m=len(X)#训练样本集大小 #迭代训练过程 for i in range(I): #正向传播 J = 0 dw1=0 dw2=0 db=0 for j in range(m): z=w1*X[j][0]+w2*X[j][1]+b#计算logistic模型输出 a=1.0/(1+math.exp(-z))#激活函数采用sigmoid函数 J=J-(Y[j]*math.log(a)+((1-Y[j])*math.log(1-a)))#迭代求解损失函数 dz=a-Y[j]#迭代求解dJ/dz dw1=dw1+X[j][0]*dz#迭代求解dJ/dw1 dw2=dw2+X[j][1]*dz#迭代求解dJ/dw2 db=db+dz#迭代求解dJ/db J=J/m #计算当前的损失函数并打印出来 print('cross function = {0}'.format(J)) #反向传播(梯度下降法) dw1=dw1/m dw2=dw2/m db=db/m w1=w1-alpha*dw1#更新参数w1 w2=w2-alpha*dw2#更新参数w2 b=b-alpha*db#更新参数b #生成测试集 X_test=[] Y_test=[] for i in range(100): X_test.append([random.random()*10.0,-random.random()*10.0]) Y_test.append(0) for i in range(100): X_test.append([random.random()*10.0,random.random()*10.0]) Y_test.append(1) #计算准确率 ans = 0 for i in range(200): label = 0 if w1*X_test[i][0]+w2*X_test[i][1]+b>0.5: label=1 if label is Y_test[i]: ans=ans+1 print('accuracy={0}'.format(ans/200))

由于循环实现效率较低,可以考虑采用向量化方法来实现。python编程中,在可以采用向量化方法的时候尽量不要使用for循环,两种编码方式的效率相差高达几十倍。代码如下所示:

# -*- coding: utf-8 -*- """ Created on Fri Oct 25 13:54:19 2019 @author: Iseno_V """ import numpy as np m = 1000#x训练集大小 n = 6#logistic回归模型参数的维数 alpha=0.001#学习率 #生成样本集 X=np.hstack((np.random.rand(n,m/2),-np.random.rand(n,m/2))) Y=np.hstack((np.zeros((1,m/2)),np.ones((1,m/2)))) #生成测试集 X_test=np.hstack((-np.random.rand(n,m/2),np.random.rand(n,m/2))) Y_test=np.hstack((np.ones((1,m/2)),np.zeros((1,m/2)))) I = 20000#迭代步数 w = np.random.rand(n,1)#初始化参数w b = np.random.rand(1,1)#初始化参数b for i in range(I): #正向传播过程 z = np.dot(w.T,X)+b a = 1.0/(1+np.exp(-z)) #计算损失函数 J = - (np.dot(Y,np.log(a).T)+(np.dot((1-Y),np.log(1-a).T)))/m print('cost function={0}'.format(J)) #反向传播过程 dz = a-Y#计算梯度dJ/dz dw = np.dot(X,dz.T)/m#计算梯度dJ/dw db = np.sum(dz)/m#计算梯度dJ/db w=w-alpha*dw#更新w b=b-alpha*db#更新b #采用逻辑运算的方式获取准确率 pre = np.dot(w.T,X_test)+b>0.5 rate = 1-np.sum(np.abs(Y_test - pre.astype(np.int16)))/m print('accuracy={0}'.format(rate))
最新回复(0)