美文网首页
逻辑斯蒂回归

逻辑斯蒂回归

作者: 当_下 | 来源:发表于2019-12-15 17:27 被阅读0次

一句话总结逻辑回归:

逻辑回归假设数据服从伯努利分布,通过极大似然函数的方法,运用梯度下降来求解参数,来达到将数据二分类的目的。

逻辑回归是一个非线性模型,但是是其背后是以线性回归为理论支撑的.

为什么要使用sigmoid函数作为假设?

        因为线性回归模型的预测值为实数,而样本的类标记为(0,1),我们需要将分类任务的真实标记y与线性回归模型的预测值联系起来,也就是找到广义线性模型中的联系函数。如果选择单位阶跃函数的话,它是不连续的不可微。而如果选择sigmoid函数,它是连续的,而且能够将z转化为一个接近0或1的值。


逻辑回归的损失函数

使用梯度下降法,就要求出梯度,对每一个向量\theta 中每一个参数,都求出对应的导数:

最终结果:

在求得对一个参数的导数之后,则可以对所有特征维度上对损失函数进行求导,得到向量化后的结果如下:


逻辑回归代码实现

import numpy as np

# 因为逻辑回归是分类问题,因此需要对评价指标进行更改

from sklearn.metrics import accuracy_score

class LogisticRegression:

    def __init__(self):

        """初始化Logistic Regression模型"""

        self.coef_ = None

        self.intercept_ = None

        self._theta = None

    """

    定义sigmoid方法

    参数:线性模型t

    输出:sigmoid表达式

    """

    def _sigmoid(self, t):

        return 1. / (1. + np.exp(-t))

    """

    fit方法,内部使用梯度下降法训练Logistic Regression模型

    参数:训练数据集X_train, y_train, 学习率, 迭代次数

    输出:训练好的模型

    """

    def fit(self, X_train, y_train, eta=0.01, n_iters=1e4):

        assert X_train.shape[0] == y_train.shape[0], \

            "the size of X_train must be equal to the size of y_train"

        """

        定义逻辑回归的损失函数

        参数:参数theta、构造好的矩阵X_b、标签y

        输出:损失函数表达式

        """

        def J(theta, X_b, y):

            # 定义逻辑回归的模型:y_hat

            y_hat = self._sigmoid(X_b.dot(theta))

            try:

                # 返回损失函数的表达式

                return - np.sum(y*np.log(y_hat) + (1-y)*np.log(1-y_hat)) / len(y)

            except:

                return float('inf')

        """

        损失函数的导数计算

        参数:参数theta、构造好的矩阵X_b、标签y

        输出:计算的表达式

        """

        def dJ(theta, X_b, y):

            return X_b.T.dot(self._sigmoid(X_b.dot(theta)) - y) / len(y)

        """

        梯度下降的过程

        """

        def gradient_descent(X_b, y, initial_theta, eta, n_iters=1e4, epsilon=1e-8):

            theta = initial_theta

            cur_iter = 0

            while cur_iter < n_iters:

                gradient = dJ(theta, X_b, y)

                last_theta = theta

                theta = theta - eta * gradient

                if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):

                    break

                cur_iter += 1

            return theta

        X_b = np.hstack([np.ones((len(X_train), 1)), X_train])

        initial_theta = np.zeros(X_b.shape[1])

        # 梯度下降的结果求出参数heta

        self._theta = gradient_descent(X_b, y_train, initial_theta, eta, n_iters)

        # 第一个参数为截距

        self.intercept_ = self._theta[0]

        # 其他参数为各特征的系数

        self.coef_ = self._theta[1:]

        return self

    """

    逻辑回归是根据概率进行分类的,因此先预测概率

    参数:输入空间X_predict

    输出:结果概率向量

    """

    def predict_proba(self, X_predict):

        """给定待预测数据集X_predict,返回表示X_predict的结果概率向量"""

        assert self.intercept_ is not None and self.coef_ is not None, \

            "must fit before predict!"

        assert X_predict.shape[1] == len(self.coef_), \

            "the feature number of X_predict must be equal to X_train"

        X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])

        # 将梯度下降得到的参数theta带入逻辑回归的表达式中

        return self._sigmoid(X_b.dot(self._theta))

    """

    使用X_predict的结果概率向量,将其转换为分类

    参数:输入空间X_predict

    输出:分类结果

    """

    def predict(self, X_predict):

        """给定待预测数据集X_predict,返回表示X_predict的结果向量"""

        assert self.intercept_ is not None and self.coef_ is not None, \

            "must fit before predict!"

        assert X_predict.shape[1] == len(self.coef_), \

            "the feature number of X_predict must be equal to X_train"

        # 得到概率

        proba = self.predict_proba(X_predict)

        # 判断概率是否大于0.5,然后将布尔表达式得到的向量,强转为int类型,即为0-1向量

        return np.array(proba >= 0.5, dtype='int')

    def score(self, X_test, y_test):

        """根据测试数据集 X_test 和 y_test 确定当前模型的准确度"""

        y_predict = self.predict(X_test)

        return accuracy_score(y_test, y_predict)

    def __repr__(self):

        return "LogisticRegression()"

调用:

import numpy as np

import matplotlib.pyplot as plt

from sklearn import datasets

iris = datasets.load_iris()

X = iris.data

y = iris.target

X = X[y<2,:2]

y = y[y<2]

plt.scatter(X[y==0,0], X[y==0,1], color="red")

plt.scatter(X[y==1,0], X[y==1,1], color="blue")

plt.show()

from sklearn.model_selection import train_test_split

# from myAlgorithm.LogisticRegression import LogisticRegression

X_train, X_test, y_train, y_test = train_test_split(X, y)

log_reg = LogisticRegression()

log_reg.fit(X_train, y_train)

# 查看训练数据集分类准确度

log_reg.score(X_test, y_test)

"""

输出:1.0

"""

# 查看逻辑回归得到的概率

log_reg.predict_proba(X_test)

"""

输出:

array([ 0.92972035,  0.98664939,  0.14852024,  0.17601199,  0.0369836 ,

        0.0186637 ,  0.04936918,  0.99669244,  0.97993941,  0.74524655,

        0.04473194,  0.00339285,  0.26131273,  0.0369836 ,  0.84192923,

        0.79892262,  0.82890209,  0.32358166,  0.06535323,  0.20735334])

"""

# 得到逻辑回归分类结果

log_reg.predict(X_test)

"""

输出:

array([1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0])

"""


sklearn中的LogisticRegression

返回sklearn的逻辑回归中的参数及得分 可视化决策边界 多项式项逻辑回归 决策边界

相关文章

网友评论

      本文标题:逻辑斯蒂回归

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