数据分析模型学习(二)——逻辑回归

数据分析模型学习(二)——逻辑回归

在之前的的线性回归中,我们尝试用一个公式来描述数据的分布情况,这个公式可以概括如下:

y=wwXX+b y = w w X X + b

根据我的理解,大部分的分类算法的模型根本上都是一个线性回归的模型,包括本次的逻辑回归,以及接下来的SVM等。

逻辑回归是什么?

首先,逻辑回归不是一个回归模型,而是一个分类模型。这个分类模型的基本形态用来判断被预测数据属于0分类还是1分类。换言之,我们的数据标签只用两个,0和1。
在这用情况下,使用单纯的线性回归就会面临一个问题。根据特征预算得到的标签如何转换成0/1标签。
在数学上,使用一个sigmod函数对线性回归输出的标签进行再次运算,将线性回归的结果映射到一个(0,1)的区间内,然后,我们认为运算结果>0.5的数据标签为1,<0.5的数据标签为0(当然,0.5并不是绝对的,可以根据具体的需要进行调整。) 使用的sigmod函数如下:

S(x)=1/(1+ex) S ( x ) = 1 / ( 1 + e − x )

至于为什么使用这个函数,会涉及一些数学方面的内容,在这里不做推导。

如何对参数进行估计?

现在,我们逻辑回归的基本构成就已经说完了。然而在线性回归中,有一个很重要的问题没有解决,如何才能得到 y=wwXX+b y = w w X X + b 中的参数呢? 在统计学和计算机中采取的不太相同的方式。
首先是统计学,一般采用最小二乘法对参数进行估计,公式为 ww=(XXTXX)1XXy w w = ( X X T X X ) − 1 X X y 。公式的具体推导过程略去,请参考维基百科。

计算机中参数估计方法

在计算机中,一般采用梯度下降法(也有更优化的随机梯度下降法,会在后续的内容中尝试进行解释。)
随机梯度下降法中,首先定义了一个损失函数——一个用来衡量预测结果和样本之间区别程度的函数,这个函数的定义一般上要求有两点(这两个要求是我的理解,如果有误,请留言指正,谢谢)。

  • 正确反应损失的变化趋势
  • 可导

在这里,我简单的定义了损失函数为 1/2(yy^)2 1 / 2 ( y − y ^ ) 2 当我们有了损失函数之后,不妨思考一个问题,如果参数能够使得损失最小,就可以认为参数最优了,那么如何使得损失最小?我们怎么判断出参数最小了呢?
我们首先对损失函数进行求导,根据导函数,可以确定函数的梯度(可以理解为在欧式空间内函数值变化最快的方向),在函数梯度方向上,小小的进行一次前进(由学习速率决定,即learning_rate),得到新的参数w后,重新计算函数损失,不断迭代,最终可以得到损失为0的参数。这时,可以认为函数的损失最小了。注意,由于函数不一定只有一个极值点,所以,参数不一定为最优解。

在这里贴上一个简单的逻辑回归实现的代码:

# -*- coding:utf-8 -*-
import numpy as np
class LogisticRegression:

    def __init__(self, n_iterations=3000, learning_rate=0.00004, regularization=None, gradient=True, alpha=0.5):
        '''
        :param n_iterations: 迭代次数
        :param learning_rate: 学习速率
        :param regularization: 是否使用正则
        :param gradient: 是否使用梯度下降
        '''
        self.n_iterations = n_iterations
        self.learning_rate = learning_rate
        self.gradient = gradient
        self.train_errors = []
        if regularization == None:
            self.regularization = lambda x: 0
            self.regularization.grad = lambda x: 0
        else:
            self.regularization = regularization
        self.alpha = alpha

    # sigmod函数
    def sigmoid(self, X):
        return 1 / (1 + np.exp(X.dot(self.w)))

    # 初始化w值
    def __initialize_weights(self, n_features):
        limit = 1 / np.sqrt(n_features)
        w = np.random.uniform(-limit, limit, (n_features, 1))
        b = 0
        self.w = np.insert(w, 0, b, axis=0)
        # print(self.w.shape)

    # 使用梯度下降法或最小二乘法进行参数估计
     def fit(self, X, y):
            '''
            :param X: 训练数据的自变量(特征)
            :param y: 训练数据的因变量(标签)
            :return: self
            '''
            m_samples, n_features = X.shape
            self.__initialize_weights(n_features)
            X = np.insert(X, 0, 1, axis=1)
            y = np.reshape(y, (m_samples, 1))
            self.train_errors = []
            if self.gradient == True:
                for i in range(self.n_iterations):
                    y_pred = X.dot(self.w)
                    loss = np.mean(0.5 * (y_pred - y) ** 2) + self.regularization(self.w)
                    self.train_errors.append(loss)
                    a_grad = X.T.dot(y_pred - y) + self.regularization.grad(self.w)
                    self.w = self.w - self.learning_rate * a_grad
            else:
                X = np.matrix(X)
                y = np.matrix(y)
                _coef = X.T.dot(X)
                _coef = _coef.I
                _coef = _coef.dot(X.T)
                self.w = _coef.dot(y)

    def predict(self, X):
        X = np.insert(X, 0, 1, axis=1)
        y_pred = X.dot(self.w)
        y_pred[y_pred >= self.alpha] = 1
        y_pred[y_pred < self.alpha] = 0
        return y_pred

    @property
    def error(self):
        return self.train_errors

完整代码见github
https://github.com/xudalin0609/dataAnalysisModels/blob/master/LogisticRegression.py

你可能感兴趣的:(数据分析模型学习(二)——逻辑回归)