机器学习专栏——(五)线性模型之Softmax回归

线性模型——Softmax回归

    前面讲到了逻辑回归,将逻辑回归理解了,softmax回归便好理解。softmax实际上是逻辑回归的拓展,它将逻辑回归的二分类推广到了多分类,用逻辑回归的方法解决多分类问题。
    在学习softmax回归之前,需要先了解两个知识点,一个是softmax函数,另一个是One-Hat编码。softmax函数和逻辑回归中的sigmoid函数的作用一样,都是为了将线性回归的连续值转换为离散值,从而完成分类任务,不同之处在于,sigmoid将连续值转换为0和1,而对于一个 C C C分类问题来说,softmax函数则是转换为 { 1 , 2 , 3... , C } \{1,2,3...,C\} {1,2,3...,C}。softmax函数表达式为:
p ( y = c ∣ x ) = softmax ( w c T x ) = e w c T x ∑ c ′ = 1 C e w c T x p(y=c|x) = \text{softmax}(w_c^Tx) = \frac{e^{w_c^Tx}}{\sum_{c'=1}^Ce^{w_c^Tx}} p(y=cx)=softmax(wcTx)=c=1CewcTxewcTx

    在了解了softmax函数之后,再来看一看One-Hot编码。One-Hot编码又称为一位有效编码,急用 N N N个状态为来进行编码。以分类中的应用为例,假设某一个数据集共有三种标签,分别为1,2,3。我们可以使用One-Hot编码来对他们表示,将三种状态按顺序组成一个列表{1,2,3}。One-Hot编码的编码规则为,码元由0,1两种组成,再同一个码组中,有且仅有一位为1,该1位表示对应元素被选中。例如{0,1,0}表示该样本的标签为2。

    在softmax回归中,考虑一个数据集 D D D,其中样本数量为 N N N,每个样本的特征数量为 M M M,类别为 C C C。为了实现这样一个多分类问题:

    1、首先需要准备数据,这里以矩阵为例:1)增广特征矩阵 X M + 1 , N = { x 1 , x 2 , . . . x N } X_{M+1,N} = \{\bf x_1,x_2, ... x_N\} XM+1,N={x1,x2,...xN},其中${\bf x_i} = [x_{i,1},…,x_{i,M},1]^\text T 表示第 表示第 表示第i 个样本的增广特征向量。 2 )标签 个样本的增广特征向量。2)标签 个样本的增广特征向量。2)标签Y_{N,1} = [y_1,y_2,…y_N]^\text T 。 3 ) O n e − H o t 矩阵 。3)One-Hot矩阵 3OneHot矩阵O_{C,N} 。 4 )增广权重矩阵 。4)增广权重矩阵 4)增广权重矩阵W_{M+1,C} = {\bf w_1,w_2,…w_C} ,其中 ,其中 ,其中{\bf w_i} = [w_{i,1},…w_{i,M}]^\text T 表示第 表示第 表示第i$个类别的增广权重向量。

    2、然后,需要计算线性回归输出 Y C , N L I N = W T X Y^{LIN}_ {C,N} = W^\text T X YC,NLIN=WTX。然后,将线性回归的输出作为softmax函数的输入,得到预测值 Y ^ C , N = softmax ( W T X ) \hat Y_{C,N} = \text{softmax}(W^\text T X) Y^C,N=softmax(WTX)
    3、随后,写函数函数(矩阵点乘) L 1 , 1 = − 1 N ∑ 1 N O ∗ log ⁡ Y ^ C , N \mathcal{L}_{1,1} = \frac{-1}{N}\sum_{1}^NO*\log\hat Y_{C,N} L1,1=N11NOlogY^C,N
    4、最后,根据如下公式更新参数 W M + 1 , C t + 1 = W M + 1 , C t + α X M + 1 , N ( O C , N − Y ^ C , N ) T W_{M+1,C}^{t+1} = W_{M+1,C}^{t} + \alpha X_{M+1,N}(O_{C,N} - \hat Y_{C,N})^\text T WM+1,Ct+1=WM+1,Ct+αXM+1,N(OC,NY^C,N)T

    实现代码

"""
@File     :   SoftmaxRegression.py   
@Author   :   CheckOneA
@Contact  :   932261247@qq.com
@License  :   (C)Copyright 2018-2021
@Version  :   V1.0
@Date     :   2022/9/11
@Encoding :   UTF-8
@Des      :   None
"""
import numpy as np


class SoftmaxRegression:
    def __init__(self, data, interation_max, n_class, learning_rate, bath_size, gradient_descent_model):
        self.data = data
        self.n_data = data.shape[0]
        self.n_feature = data.shape[1]
        self.n_class = n_class
        self.interation_max = interation_max
        self.lr = learning_rate
        self.bath_size = bath_size
        self.gradient_descent_model = gradient_descent_model
        self.data_train = self.get_data_train()
        self.data_train_n_data = self.data_train.shape[0]
        self.data_train_n_feature = self.data_train.shape[1] - 1

    def train(self):
        w = np.random.random((self.data_train_n_feature + 1, self.n_class))
        loss_dis = []
        for interation_index in range(self.interation_max):
            data_train = self.get_data_train()
            feature, label = self.get_feature_and_label(data_train)
            one_hot = self.one_hot(label)
            line_out = w.T @ feature
            label_pro = self.soft_max_function(line_out)
            loss = self.loss_function(one_hot, label_pro)
            loss_dis.append(loss)
            parameter_update = (feature @ (one_hot - label_pro).T)
            w = w + self.lr * parameter_update
        return loss_dis, w

    def get_data_train(self):
        data_train = None
        if self.gradient_descent_model == 1:
            data_train = self.data
        elif self.gradient_descent_model == 2:
            data_train = self.data[np.random.randint(0, self.n_data), :]
        elif self.gradient_descent_model == 3:
            data_index = np.random.randint(low=0, high=self.n_data, size=self.bath_size)
            data_train = self.data[data_index, :]
        return data_train

    @staticmethod
    def get_feature_and_label(data_train):
        feature = data_train[:, 0:2]
        n_data_train, n_feature_train = data_train.shape
        x = np.insert(feature, n_feature_train - 1, np.ones(n_data_train), axis=1).T
        label = data_train[:, 2].astype(int).reshape(-1, 1)
        return x, label

    @staticmethod
    def soft_max_function(input_data):
        sum_each_col = (np.sum(input_data, axis=1)).reshape(-1, 1)
        return np.exp(input_data) / sum_each_col

    def loss_function(self, one_hot, label_pr):
        loss = -np.sum(one_hot * np.log10(label_pr)) / self.data_train_n_data / self.n_class
        return loss

    def one_hot(self, label):
        one_hot = np.zeros((self.n_class, self.data_train_n_data))
        temp = np.linspace(0, self.n_class - 1, self.n_class, dtype=int)
        for class_index in range(self.n_class):
            for data_index in range(self.data_train_n_data):
                if label[data_index] == class_index:
                    one_hot[class_index][data_index] = 1
        return one_hot

    测试代码

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

from SoftmaxRegression import SoftmaxRegression

if __name__ == '__main__':
    data_df = pd.read_csv("train_dataset.txt")
    data_np = data_df.to_numpy()
    # 获取特征标签 大小为 (M+1) N
    # print(data_np)
    n_data, n_feature = data_np.shape
    softmax_regression = SoftmaxRegression(data=data_np,
                                           interation_max=20000,
                                           n_class=4,
                                           learning_rate=0.0000000001,
                                           bath_size=128,
                                           gradient_descent_model=1)
    loss, w = softmax_regression.train()
    print(loss)
    print(w)
    plt.figure()
    x = np.linspace(1, len(loss), len(loss))
    plt.plot(x, loss)
    plt.show()

    数据集下载

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值