机器学习(课堂笔记)Day08:逻辑回归 Logistic Regression

0x00 什么是逻辑回归 Logistic Regression

逻辑回归:逻辑回归既是一个回归算法,也是一个分类算法,通常用来解决二分类问题

回归算法如何解决分类问题呢?

逻辑回归的预测值是一个概率值,我们根据概率值的大小进行分类。概率值可以被解释为输入样本属于某个类别的概率。逻辑回归中使用 Sigmoid 函数(逻辑函数)将线性回归的预测值映射为0和1之间的概率值。

例如:给你一个病人的信息,你计算出该病人得恶性肿瘤的概率,当该概率大于0.5时,我们将其分类为恶性肿瘤,当该概率小于0.5时,我们将其分类为良性肿瘤。

逻辑回归如何进行预测概率值呢?

我们之间讨论的线性回归,直接通过训练数据集 得到模型参数theta ,然后theta 和 新样本矩阵 点乘就可以得到预测值向量。但是因为概率值的值域范围必定是在[0,1]之间的,所以我们还需要将预测值向量送入一个称为sigmoid的函数中,将其映射到[0,1]之间。

分析:

当t趋近与正无穷时,函数值无限逼近1

当t趋近与负无穷时,函数值无限逼近0

当t等于0时,函数值为1/2

编程实现:

0x01 逻辑回归的损失函数

该损失函数没有公式解,只能使用梯度下降法求解。

0x02 逻辑回归损失函数的梯度

向量化:

对逻辑回归的梯度进行向量化:

0x03 实现逻辑回归算法

'''
Author: your name
Date: 2020-11-12 14:21:32
LastEditTime: 2020-12-03 14:58:50
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: /ML/playML/LinearRegression.py
'''
import numpy as np
from .metrics import accuracy_score


class LogisticRegression:
    def __init__(self):
        self.coef_ = None  # 系数
        self.interception = None  # 截距
        self._theta = None  # θ
    def _sigmoid(self,t):
        return 1./(1.+np.exp(-t))
        
    # 批量梯度下降法
    def fit(self, X_train, y_train, eta=0.01, n_iters=1e4):
        #损失函数
        def J(theta, X_b, y):
            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)
            # theta 向量 和 X 列向量 相乘 就是预测结果组成的向量
            except:
                return float('inf')

        def dJ(theta, X_b, y):  
            """ 向量化的方式計算梯度 """
            return X_b.T.dot(self._sigmoid( X_b.dot(theta) )-y ) / len(X_b)

        def gradient_descent(X_b, y, initial_theta, eta, n_iters=1e4, epsilon=1e-8):
            theta = initial_theta
            i_iter = 0
            while i_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
                i_iter += 1
            return theta
        X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
        initial_theta = np.zeros(X_b.shape[1])  # 等于Xb的列数
        self._theta = gradient_descent(
            X_b, y_train, initial_theta, eta, n_iters)
        self.interception = self._theta[0]
        self.coef_ = self._theta[1:]
        return self    

    def predict_proba(self, X_predict):
        """ 給定待預測的數據集 X_predict ,返回y_predict對應的概率值 組成的列向量"""
        assert self.interception is not None and self.coef_ is not None,\
            "在predict之前请先fit"
        X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
        return self._sigmoid( X_b.dot(self._theta) ) 
       
    def predict(self, X_predict):
        """ 根據概率值是否大於0.5 進行分類 """
        proba = self.predict_proba(X_predict)
        return np.array(proba>=0.5,dtype='int')

    def score(self, X_test, y_test):
        y_predict = self.predict(X_test)
        return accuracy_score(y_test, y_predict)

    def __repr__(self):
        return "LogisticRegression()"

使用我们封装的逻辑回归算法:(使用鸢尾花数据集)

0x04 决策边界

因为 t = theta.T.dot(Xb) 所以:

y_hat 到底是1还是0,取决于 theta.T.dot(Xb) 和0的关系,我们将theta.T.dot(Xb) =0 称为决策边界

也就是说决策边界 实际上就是我们通过逻辑回归训练出来的那条直线。

不规则的决策边界的绘制方法:

思路: 将x轴 和y轴 构成的平面 划分为许多个小点,对于这些小点都使用模型进行预测,得到一个分类值

那么我们根据不同分类值所占领的区域 就可以圈出决策边界

例如:

参考代码:(仅供参考)

逻辑回归算法中实际是将决策边界的表达式直接求出来了,但是knn算法中是没有这个表达式的,我们可以按照上述将平面划分为许多个点的思路就求下kNN算法的决策边界

例如:只考虑两类鸢尾花

考虑三类鸢尾花,决策边界非常弯曲,是过拟合的征兆

将k的值变大,模型变得更加简单,重新绘图:

0x05 逻辑回归中使用多项式特征

0x06 scikit-learn中的逻辑回归

对正则化的过程进行改进:

添加一个大C,用来配置正则项L的比重

编程实践:

0x07 OvR与OvO

我们之前说逻辑回归只能解决二分类问题,但是有两种改造方案可以让逻辑回归解决多分类问题:

OvR 和OvO

#OvR (One vs Rest)一针对剩余

比如我们现在有一个四分类问题,我们可以将这个四分类问题转化为四个二分类问题:

#OvO (One vs One)一对一

比如我们现在有一个四分类问题,我们从中取两个类别,直接判断新来的样本点是这两个类别中某一个的概率

将一个四分类问题 归约为六个二分类问题。

编程实践:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值