赞
踩
逻辑回归是一种基于回归思想来解决分类问题的一个算法,利用线性回归输出的值,进行一定的处理转化为分类的标签值
我们可以按照任务的种类,将任务分为回归任务和分类任务。分类问题的输出是离散值,例如识别猫狗,任务的输出只能是猫或者狗,是离散值。回归问题的输出是连续值,例如根据某些特征预测一个人的体重,体重是连续值。
考虑:线性模型的输出值为连续值,如何将它与分类问题联系起来?
找⼀个单调可微函数将分类任务的真实标记 y 与线性回归模型的预测值联系起来
z=
θ
\theta
θT x + b的输出是实值,我们将实值z转化为0/1值,使用对数几率函数。
其中z=
θ
\theta
θT x + b 是线性回归的输出。
x和
θ
\theta
θ是同纬度的向量,x有几个特征
θ
\theta
θ就有几个分量
sigmoid函数的输出值大于0.5就判断为正类,小于0.5就判断为负类
当y=1时 输出h越接近1 代价越小,越远离1代价越大,当y=0时,输出h越接近0代价越小,越远离0代价越大
由于还需判断y的值,则将此式子合并成为一个式子
对于某个参数 θ \theta θ,算出损失对这个参数的偏导数g,则更新 θ \theta θ= θ \theta θ-α*g,α是学习率,手动设置的超参数。设置过大导致模型无法收敛,设置过小则导致收敛过慢,所以需要设置合适的大小。
sigmoid函数的导数推导
代价loss对参数求导推导过程
为了计算方便,将在x第一个位置添加一个分量1,与
θ
\theta
θ相乘后分量1的位置代表偏置值,因此
θ
\theta
θ也许多出一个分量,之前的z=
θ
\theta
θTx+b,变成了z=
θ
\theta
θTx,少了一个偏置值b,但x和
θ
\theta
θ分别多加了一个分量,相乘可代表偏置值b。
from sklearn import datasets import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler def sigmoid(x): #添加判断防止e的正数次幂过大导致溢出 if x>0: return 1/(1+np.exp(-x)) else: return np.exp(x)/(1+np.exp(x)) #h(x)函数 def fun_h(thetas,x): z=np.dot(thetas,x) h=sigmoid(z) return h class model(): def __init__(self,num_iters=20,lr=0.1): """ :param num_iters: 迭代次数 :param lr: 学习率 """ self.num_iters=num_iters self.lr=lr def fit(self,X,Y): """ :param X: 训练集特征数据 :param Y: 标签 :return: """ #初始化参数θ self.thetas = np.zeros(X.shape[1]) m = len(X) for k in range(self.num_iters): for j in range(len(self.thetas)): d_thetaj = 0 loss = 0 for i in range(m): h = fun_h(self.thetas, x_train[i]) loss += -(Y[i] * np.log(fun_h(self.thetas, x_train[i])) + (1 - Y[i]) * np.log(1 - fun_h(self.thetas, x_train[i]))) d_thetaj += (h - Y[i]) * x_train[i][j] loss /= m d_thetaj /= m self.thetas[j] -= self.lr * d_thetaj print("iter:%d,loss:%f"%(k,loss)) #判断类别 def predict(self,x): h=fun_h(self.thetas,x) if h>=0.5: return 1 else: return 0 #计算测试集准确率 def score(self,x_test,y_test): num_correct = 0 for x, y in zip(x_test, y_test): y_hat = self.predict( x) if y_hat == y: num_correct += 1 return num_correct / len(x_test) if __name__ == '__main__': cancer = datasets.load_breast_cancer() data=cancer.data target=cancer.target #进行数据标准化 std = StandardScaler() data = std.fit_transform(data) #对数据添加一列1方便计算 ones=np.ones((len(data),1)) data=np.c_[ones,data] x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=0) model=model(30,0.1) model.fit(x_train,y_train) score=model.score(x_test,y_test) print("acc:",score)
运行结果:
iter:0,loss:0.545435
iter:1,loss:0.458332
iter:2,loss:0.401712
iter:3,loss:0.361705
iter:4,loss:0.331730
iter:5,loss:0.308293
iter:6,loss:0.289367
iter:7,loss:0.273695
iter:8,loss:0.260458
iter:9,loss:0.249093
iter:10,loss:0.239204
iter:11,loss:0.230502
iter:12,loss:0.222772
iter:13,loss:0.215849
iter:14,loss:0.209604
iter:15,loss:0.203937
iter:16,loss:0.198765
iter:17,loss:0.194023
iter:18,loss:0.189656
iter:19,loss:0.185618
iter:20,loss:0.181872
iter:21,loss:0.178386
iter:22,loss:0.175131
iter:23,loss:0.172085
iter:24,loss:0.169227
iter:25,loss:0.166539
iter:26,loss:0.164005
iter:27,loss:0.161612
iter:28,loss:0.159348
iter:29,loss:0.157202
acc: 0.956140350877193
Process finished with exit code 0
loss在逐步下降,最终测试集也达到了不错的正确率95%
提示:这里对文章进行总结:
以上就是今天要讲的内容,本文仅仅简单介绍了逻辑回归简单原理,以及numpy实现基于sklearn乳腺癌数据集
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。