机器学习算法(2)—— Softmax Regression

本文深入探讨了Softmax Regression算法模型,介绍了其概率模型、代价函数及求解方法,并提供了Python代码实现,适合于多分类问题的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、前言

由于逻辑回归算法复杂度低、容易实现的特点,在工业界得到广泛的应用。如计算广告中的点击率预估等。但是逻辑回归主要用于二分类问题,若需要处理的是多分类问题,如手写数字识别这一类的多分类问题,此时可能需要的是能够处理多分类问题的算法。

2、Softmax Regression算法模型

2.1、Softmax Regression 概率模型

假设有 m 个训练样本:                       

\large \left \{ (X^{(1)},y^{(1)}),(X^{(2)},y^{(2)}) ,...,(X^{(m)},y^{(m)}) \right \}

其中 X 为输入特征,y 为类标记。

对于每一个样本估计其所属类别的概率为:

\large P(y^{(i)}=j|X^{(i)};\theta)=\frac{e^{\theta_{j}^{T}X^{(i)}}}{\sum_{l=1}^{k} e^{\theta_{l}^{T}X^{(i)}}}

2.2、Softmax Regression 的代价函数:

类似于逻辑回归算法,在 Softmax Regression 算法中的损失函数中引入指示函数 I(*) , 其具体的形式为:

\large I(x)=\left\{\begin{matrix} 0, & if& x=False\\ 1,& if& x=True\end{matrix}\right.

那么,对于 Softmax Regression 算法的损失函数为:

\large J(\theta)=-\frac{1}{m}\left [ \sum_{i=1}^{m}\sum_{j=1}^{k} I\left \{ y^{i}=j \right \}log \frac{e^{\theta_{j}^{T}X^{(i)}}}{\sum_{l=1}^{k}e^{\theta_{j}^{T}X^{(i)}}}\right ]

2.2、Softmax Regression 的求解:

对上述的代价函数,可以用梯度下降法对其进行求解,首先对其进行求梯度:

最终的结果为:

通过梯度下降法的公式可以更新参数为:

\large \theta_{j} = \theta_j+\alpha\bigtriangledown_{\theta_{j}}J(\theta)


Softmax Regression 的代价函数 Cost() 的 Python 代码实现:

# 定义损失函数
def error_rate(h, label):
    '''计算当前的损失函数值
    input:  h(mat):预测值
            label(mat):实际值
    output: err/m(float):错误率
    '''
    m = np.shape(h)[0]
    sum_err = 0.0
    for i in range(m):
        if h[i, 0] > 0 and (1 - h[i, 0]) > 0:
            sum_err -= (label[i, 0] * np.log(h[i, 0]) + (1 - label[i, 0]) * np.log(1 - h[i, 0]))
        else:
            sum_err -= 0
    return sum_err / m

Softmax Regression 的梯度下降法求解参数函数的 Python 代码实现:         

# 定义 BGD 梯度下降法
def lr_train_bgd(feature, label, maxCycle, alpha):
    n = np.shape(feature)[1]    # 特征的个数
    w = np.mat(np.ones((n, 1)))   # 初始化权重
    i = 0
    while i <= maxCycle:
        i += 1
        h = Sigmoid(feature * w)
        error = label - h
        if i % 100 == 0:
            print('\t 迭代次数为=:' + str(i) + ',训练误差率为:' + str(error_rate(h, label)))
        w = w + alpha * feature.T * error
    return w

Softmax Regression 完整实践代码:

# -*- coding: utf-8 -*-
# @Time    : 2019-1-8 18:27
# @Author  : Chaucer_Gxm
# @Email   : gxm4167235@163.com
# @File    : Logsitic_Regression.py
# @GitHub  : https://github.com/Chaucergit/Code-and-Algorithm
# @blog    : https://blog.youkuaiyun.com/qq_24819773
# @Software: PyCharm
import numpy as np


# 定义 Sigmoid 函数
def Sigmoid(x):
    return 1.0 / (1 + np.exp(-x))


# 定义损失函数
def error_rate(h, label):
    '''计算当前的损失函数值
    input:  h(mat):预测值
            label(mat):实际值
    output: err/m(float):错误率
    '''
    m = np.shape(h)[0]
    sum_err = 0.0
    for i in range(m):
        if h[i, 0] > 0 and (1 - h[i, 0]) > 0:
            sum_err -= (label[i, 0] * np.log(h[i, 0]) + (1 - label[i, 0]) * np.log(1 - h[i, 0]))
        else:
            sum_err -= 0
    return sum_err / m


# 定义 BGD 梯度下降法
def lr_train_bgd(feature, label, maxCycle, alpha):
    n = np.shape(feature)[1]    # 特征的个数
    w = np.mat(np.ones((n, 1)))   # 初始化权重
    i = 0
    while i <= maxCycle:
        i += 1
        h = Sigmoid(feature * w)
        error = label - h
        if i % 100 == 0:
            print('\t 迭代次数为=:' + str(i) + ',训练误差率为:' + str(error_rate(h, label)))
        w = w + alpha * feature.T * error
    return w


def load_data(file_name):
    f = open(file_name)  # 打开文件
    feature_data = []
    label_data = []
    for line in f.readlines():
        feature_tmp = []
        lable_tmp = []
        lines = line.strip().split("\t")
        feature_tmp.append(1)  # 偏置项
        for i in range(len(lines) - 1):
            feature_tmp.append(float(lines[i]))
        lable_tmp.append(float(lines[-1]))

        feature_data.append(feature_tmp)
        label_data.append(lable_tmp)
    f.close()  # 关闭文件
    return np.mat(feature_data), np.mat(label_data)


# 保持最终的模型
def save_model(filename, w):
    m = np.shape(w)[0]
    f_w = open(filename, 'w')
    w_array = []
    for i in range(m):
        w_array.append(str(w[i, 0]))
    f_w.write('\t'.join(w_array))
    f_w.close()


def main():
    print('***************** 导入模型 *****************')
    features, labels = load_data('data.txt')
    print('***************** 训练模型 *****************')
    w = lr_train_bgd(features, labels, 1000, 0.01)
    print('***************** 保存模型 *****************')
    save_model('weights', w)


if __name__ == '__main__':
    main()


训练结果:

1.3941777508748279	4.527177129107412	-4.793981623770905

完整程序(训练程序+测试程序)与数据集地址:

 https://github.com/Chaucergit/Code-and-Algorithm/tree/master/ML/2-Softmax%20Regression          


参考书目:

[1].统计方法.李航

[2].Python机器学习算法.赵志勇

[3].利用Python进行数据分析.WesKinney著,唐学韬等译

         

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值