逻辑回归原理以及代码实现 基于numpy


一、逻辑回归原理

逻辑回归是一种基于回归思想来解决分类问题的一个算法,利用线性回归输出的值,进行一定的处理转化为分类的标签值

分类问题和回归问题的区别

我们可以按照任务的种类,将任务分为回归任务和分类任务。分类问题的输出是离散值,例如识别猫狗,任务的输出只能是猫或者狗,是离散值。回归问题的输出是连续值,例如根据某些特征预测一个人的体重,体重是连续值。

考虑:线性模型的输出值为连续值,如何将它与分类问题联系起来?

找⼀个单调可微函数将分类任务的真实标记 y 与线性回归模型的预测值联系起来
z= θ \theta θT x + b的输出是实值,我们将实值z转化为0/1值,使用对数几率函数。

对数几率函数(sigmoid函数)

请添加图片描述

请添加图片描述
其中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乳腺癌数据集

猜你喜欢

转载自blog.csdn.net/weixin_44599230/article/details/121442118