美文网首页
机器学习|logistic回归代码实现解读

机器学习|logistic回归代码实现解读

作者: 蓝白绛 | 来源:发表于2019-02-21 23:29 被阅读0次

    前言

    如果你能找到这里,真是我的幸运~这里是蓝白绛的学习笔记,本集合主要针对《统计学习方法》这本书,主要是基本机器学习算法代码实现的解读。
    本集合中的代码整理来自github:黄海广《统计学习方法》代码实现
    代码原作者github:wzyonggege《统计学习方法》笔记-基于Python算法实现
    本篇整理Logistic回归实现,github地址为:wzyonggege-Logistic Regression

    1、模型

    1. logistic回归也叫对数几率回归,很多地方也叫逻辑回归。虽然名字叫回归,但是它是一个分类模型。
      这里我们将要预测的b作为w_0并入w,则logistic回归模型如下:P(Y=1|x)=\frac{\exp(w\cdot x)}{1+\exp(w\cdot x)} P(Y=0|x)=\frac{1}{1+\exp(w\cdot x)}
    2. logistic回归和线性回归的异同(logistic回归名字中有“回归”的原因):
    • 几率(odds)的概念:一个事件发生的概率与该事件不发生的概率的比值。
      如果一个事件发生的概率为p,则该事件的几率的对数为{\rm logit}(p)=\log\frac{p}{1-p}=\log\frac{P(Y=1|x)}{1-P(Y=1|x)}=w\cdot x
      从上式可以看出该事件的对数几率为x的线性函数,也就是说logistic回归可以看作事件发生的对数几率的线性回归,于是logistic回归这个名字就延续下来了。

    2、参数估计

    1. 用极大似然估计法,设P(Y=1|x)=\frac{\exp(w\cdot x)}{1+\exp(w\cdot x)}=\pi(x); P(Y=0|x)=\frac{1}{1+\exp(w\cdot x)}=1-\pi(x).似然函数为:\prod_{i=1}^N[\pi(x_i)]^{y_i}[1-\pi(x_i)]^{1-y_i}
      取对数,得对数似然函数为:\begin{align} L(w) &=\sum_{i=1}^N[y_i\log\pi(x_i)+(1-y_i)\log(1-\pi(x_i))] \\ &=\sum_{i=1}^N[y_i(w\cdot x_i)-\log(1+\exp(w\cdot x_i))] \end{align}w求偏导得:\begin{align} \nabla_wL(w) &=\sum_{i=1}^N(y_ix_i-\frac{x_i\cdot\exp(w\cdot x_i)}{1+\exp(w\cdot x_i)}) \\ &=\sum_{i=1}^Nx_i(y_i-\hat{y}_i) \end{align}其中\hat{y}_i为预测值,y_i-\hat{y}_i为预测误差。
      接下来就可以用随机梯度下降法或拟牛顿法进行学习,如果用随机梯度下降法,可以得到w的更新公式为:w\leftarrow w+\eta x_i(y_i-\hat{y}_i)

    3、代码实现

    本篇中logistic回归的代码实现原始代码github为:wzyonggege-Logistic Regression该代码块用的是随机梯度下降算法进行学习。同时大佬的github上有对应的测试代码,可供测试。

    class LogisticReressionClassifier:
        def __init__(self, max_iter=200, learning_rate=0.01):
            self.max_iter = max_iter# max_iter为最大迭代数
            self.learning_rate = learning_rate# 学习率
    
        def sigmoid(self, x):# f(x) = 1 / (1 + exp(-wx))
            return 1 / (1 + exp(-x))  # 这里已经将e的指数变成了负数
    
        def data_matrix(self, X):
            data_mat = []
            for d in X:
                # 给数据前面增加一列,表示x0=1,因为这里将b并入了w
                data_mat.append([1.0, *d])
            return data_mat
    
        def fit(self, X, y):
            # label = np.mat(y)
            data_mat = self.data_matrix(X)  # 调用上面的data_matrix(),给数据前面增加一列,表示x0=1
            self.weights = np.zeros((len(data_mat[0]), 1), dtype=np.float32)  # 初始化权重,全为1
    
            for iter_ in range(self.max_iter):
                for i in range(len(X)):
                    # 计算当前sigmoid(1/1+exp(-wx))的值,自定义的sigmoid函数包含了取负,result为预测值
                    result = self.sigmoid(np.dot(data_mat[i], self.weights))
    
                    # w的更新公式为w <- w + eta * x_i * (y_i - y_i_predict)
                    error = y[i] - result  # 计算当前模型计算的预测值与真实值的误差
                    self.weights += self.learning_rate * error * np.transpose([data_mat[i]])
                    # 对于每条数据(batch=1),更新w
                    # data_mat[i]是第i条数据,是行向量,weights是列向量,所以后面data_mat[i]要转置
            print('LogisticRegression Model(learning_rate={},max_iter={})'.format(self.learning_rate, self.max_iter))
    
        def score(self, X_test, y_test):
            right = 0
            X_test = self.data_matrix(X_test)  # 给数据加一列x0
            for x, y in zip(X_test, y_test):
                result = np.dot(x, self.weights)
                if (result > 0 and y == 1) or (result < 0 and y == 0):
                    right += 1  # 如果result=wx<0则模型预测值为0,result=wx>0则模型预测值为1,可以不用带入完整的模型去计算预测值。
            return right / len(X_test)
    

    logistic回归的推导就是列出极大似然函数,取对数,对w取偏导,即可得到w的更新公式。实现的时候,关键代码就是w的更新。

    结尾

    如果您发现我的文章有任何错误,或对我的文章有什么好的建议,请联系我!如果您喜欢我的文章,请点喜欢~*我是蓝白绛,感谢你的阅读!

    相关文章

      网友评论

          本文标题:机器学习|logistic回归代码实现解读

          本文链接:https://www.haomeiwen.com/subject/hklkyqtx.html