1、前言
由于逻辑回归算法复杂度低、容易实现的特点,在工业界得到广泛的应用。如计算广告中的点击率预估等。但是逻辑回归主要用于二分类问题,若需要处理的是多分类问题,如手写数字识别这一类的多分类问题,此时可能需要的是能够处理多分类问题的算法。
2、Softmax Regression算法模型
2.1、Softmax Regression 概率模型
假设有 m 个训练样本:
其中 X 为输入特征,y 为类标记。
对于每一个样本估计其所属类别的概率为:
2.2、Softmax Regression 的代价函数:
类似于逻辑回归算法,在 Softmax Regression 算法中的损失函数中引入指示函数 I(*) , 其具体的形式为:
那么,对于 Softmax Regression 算法的损失函数为:
2.2、Softmax Regression 的求解:
对上述的代价函数,可以用梯度下降法对其进行求解,首先对其进行求梯度:
最终的结果为:
通过梯度下降法的公式可以更新参数为:
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著,唐学韬等译