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

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.csdn.net/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著,唐学韬等译

         

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python实现softmax regression(也称为多类别逻辑回归)可以使用NumPy库来进行数值计算。下面是一个简单的示例代码: ```python import numpy as np def softmax_regression(X, y, num_classes, learning_rate, num_iterations): num_features = X.shape[1] theta = np.zeros((num_features, num_classes)) for i in range(num_iterations): scores = np.dot(X, theta) exp_scores = np.exp(scores) probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) # 计算损失函数 loss = -np.log(probs[range(len(X)), y]) data_loss = np.sum(loss) / len(X) # 计算梯度 d_probs = probs d_probs[range(len(X)), y] -= 1 d_probs /= len(X) d_theta = np.dot(X.T, d_probs) # 更新参数 theta -= learning_rate * d_theta return theta # 示例数据 X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]) y = np.array([0, 1, 2, 1]) # 调用softmax_regression函数进行训练 num_classes = len(np.unique(y)) learning_rate = 0.01 num_iterations = 1000 theta = softmax_regression(X, y, num_classes, learning_rate, num_iterations) print("训练得到的参数theta:") print(theta) ``` 这段代码实现了softmax regression的训练过程。首先,定义了一个softmax_regression函数,该函数接受输入特征矩阵X、标签向量y、类别数量num_classes、学习率learning_rate和迭代次数num_iterations作为参数。在函数内部,首先初始化参数theta为全零矩阵。然后,通过迭代更新参数theta,直到达到指定的迭代次数。在每次迭代中,计算得分矩阵scores、概率矩阵probs和损失函数loss。然后,计算梯度d_theta,并使用学习率更新参数theta。最后,返回训练得到的参数theta。 在示例数据部分,定义了一个简单的输入特征矩阵X和标签向量y。调用softmax_regression函数进行训练,并打印训练得到的参数theta。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值