本文包括:
- 随机梯度下降法
- SGDM
- RMSProp
- Adam
- 其它有关数据分析,机器学习的文章及社群
逻辑斯蒂回归理论知识:
舟晓南:统计学习方法 - 逻辑斯蒂回归解析 | 数据分析,机器学习,学习历程全记录
数据集mnist下载地址(csv格式),以及完整代码:
Zhouxiaonnan/machine-learning-notesandcode
如果觉得对您有帮助,还烦请点击上面的链接,帮忙github点个star~谢谢~
Talk is cheap, let's check the code ^_^
逻辑斯蒂回归 - 随机梯度下降法:
'''
逻辑斯蒂回归 - 随机梯度下降法
-------------------------------------
数据集:Mnist
训练集数量:60000
测试集数量:10000
---------------------------------
训练结果:
迭代次数:100
训练时间:3.54s
测试时间:0.53s
正确率:0.76
'''
import numpy as np
import time
from itertools import islice
import random
'''
readlines方法读取训练数据
--------
输入:
file:数据地址
--------
输出:
data:转换后的数据
label:转换后的标记
'''
def LoadData(file):
# 打开数据文件
fr = open(file, 'r')
# 准备两个list存储data和label
data = []
label = []
# 逐行读取数据,使用islice可以直接跳过第一行表头进行逐行读取
for line in islice(fr,1,None):
# 对每一行消去空格,并根据','进行分割
splited = line.strip().split(',')
# 逐行存储数据,此处对特征进行归一化
data.append([int(num)/255 for num in splited[1:]])
# 因为逻辑斯蒂回归是二分类问题,我们将大于4的类归为1,小于4的类归为0
a = int(splited[0])
if a > 4:
label.append(1)
else:
label.append(0)
# 采用书中的方法,我们将b作为一个元素放在w向量的最后一个
# 同样也需要在每个特征向量后面加上一个1
SampleNum = len(data)
for i in range(SampleNum):
data[i].append(1)
# 返回数据的特征部分和标记部分
return data, label
'''
预测
-------
输入:
w:目前的权值向量
x:一条样本的特征向量
-----------
输出:类别
'''
def predict(w, x):
exp_wx = np.exp(np.dot(w, x))
P = exp_wx / (1 + exp_wx)
if P > 0.5:
return 1
return 0
'''
逻辑斯蒂回归 - 随机梯度下降法
--------------
输入:
data:训练集数据
label:训练集标记
itertime:迭代次数
-------------
输出:
w:最优化的权值向量
'''
def Logistic(data, label, itertime):
# 初始化w
FeatureNum = np.shape(data)[1]
w = np.zeros(FeatureNum)
# 设定学习率
h = 0.001
# 样本数
SampleNum = len(data)
# 将data转换成ndarray格式,方便后续的计算
data = np.array(data)
# 迭代
for i in range(itertime):
# 随机选择误分类点
a = 0
while a == 0:
# 随机选择
s = random.sample(range(0, SampleNum - 1),1)[0]
# 得到该样本的特征向量和标记
xi = data[s]
yi = label[s]
# 如果分类错误,更新w
if predict(w, xi) != yi:
exp_wxi = np.exp(np.dot(w,xi))
w += h * (xi * yi - (xi * exp_wxi) / (1 + exp_wxi))
# 进行下一次迭代
a = 1
return w
'''
模型测试
------------
输入:
data:测试集数据
label:测试集标记
w:最优化的权值向量
-----------
输出:
Acc:正确率
'''
def Classifier(data, label, w):
# 样本数
SampleNum = len(data)
# 初始化错误分类的数量
errorCnt = 0
# 遍历每一个样本
for i in range(SampleNum):
# 对该样本的分类
result = predict(w, data[i])
# 判断是否分类正确
if result != label[i]:
# 分类错误,errorCnt+1
errorCnt += 1
# 计算正确率
Acc = 1 - errorCnt / SampleNum
return Acc
'''测试模型'''
if __name__ == "__main__":
print('start loading')
# 输入训练集
train_data, train_label = LoadData('E:/我的学习笔记/统计学习方法/实战/训练数据/mnist_train.csv')
# 输入测试集
test_data, test_label = LoadData('E:/我的学习笔记/统计学习方法/实战/训练数据/mnist_test.csv')
print('end loading')
# 最优化参数
print('start training')
start = time.time()
w = Logistic(train_data, train_label, 200)
print('end training')
end = time.time()
print('training time: ', end - start)
# 进行分类
start = time.time()
print('start testing')
accurate = Classifier(test_data, test_label, w)
print('end testing')
end = time.time()
print('testing time: ', end - start)
print(accurate)
逻辑斯蒂回归比较简单,可以与感知机模型进行对比学习,并且也比较适合一些梯度下降法的改进形式,这里给出SGDM;RMSProp;Adam三种梯度下降的改进方法,更简单的梯度下降法和Adagrad已经在感知机模型中给出:
舟晓南:感知机模型python复现 - 随机梯度下降法;梯度下降法;adagrad;对偶形式
持续更新其它梯度下降法改进形式,待更新:SWATS;AMSGrad;AdaBound;Cyclical LR;SGDR;One-Cycle LR;RAdam;Nadam;Lookahead等。
逻辑斯蒂回归 - SGDM:
接下来的SGDM;RMSProp;Adam三种梯度下降法的改进形式,基本上只需要将训练的部分修改一下就行,篇幅所限,这里仅贴出修改后的模型训练部分。
'''
逻辑斯蒂回归 - SGDM
-------------------------------------
数据集:Mnist
训练集数量:60000
测试集数量:10000
---------------------------------
训练结果:
迭代次数:400
训练时间:171s
测试时间:1s
正确率:0.86
'''
'''
逻辑斯蒂回归 - SGDM
--------------
输入:
data:训练集数据
label:训练集标记
itertime:迭代次数
-------------
输出:
w:最优化的权值向量
'''
def Logistic(data, label, itertime):
# 初始化w
FeatureNum = np.shape(data)[1]
w = np.zeros(FeatureNum)
# 设定学习率
h = 0.001
# 样本数
SampleNum = len(data)
# 将data转换成ndarray格式,方便后续的计算
data = np.array(data)
# 初始化动量
momentum = np.zeros(FeatureNum)
# 设置超参数,用于设置动量中对前一次动量和速度的依赖程度
beita = 0.9
# 迭代
for i in range(itertime):
# 初始化梯度
v = np.zeros(FeatureNum)
# 遍历每一个样本点
for j in range(SampleNum):
# 得到该样本的特征向量和标记
xi = data[j]
yi = label[j]
# 如果分类错误,更新w_i
if predict(w, xi) != yi:
# 计算梯度
exp_wxi = np.exp(np.dot(w,xi))
v += xi * yi - (xi * exp_wxi) / (1 + exp_wxi)
# 记录动量,其中beita是超参数
momentum = beita * momentum + (1 - beita) * v
# 更新w
w += h * momentum
return w
逻辑斯蒂回归 - RMSProp:
'''
逻辑斯蒂回归 - RMSProp
-------------------------------------
数据集:Mnist
训练集数量:60000
测试集数量:10000
---------------------------------
训练结果:
迭代次数:400
训练时间:157s
测试时间:0.59s
正确率:0.86
'''
'''
逻辑斯蒂回归 - RMSProp
--------------
输入:
data:训练集数据
label:训练集标记
itertime:迭代次数
-------------
输出:
w:最优化的权值向量
'''
def Logistic(data, label, itertime):
# 初始化w
FeatureNum = np.shape(data)[1]
w = np.zeros(FeatureNum)
# 设定学习率
h = 0.001
# 样本数
SampleNum = len(data)
# 将data转换成ndarray格式,方便后续的计算
data = np.array(data)
# 设置超参数,用于设置动量中对前一次动量和速度的依赖程度
beita = 0.9
# 初始化分母项
v_i = np.zeros(FeatureNum)
# 迭代
for i in range(itertime):
# 初始化梯度
v = np.zeros(FeatureNum)
# 遍历每一个样本点
for j in range(SampleNum):
# 得到该样本的特征向量和标记
xi = data[j]
yi = label[j]
# 如果分类错误,更新w_i
if predict(w, xi) != yi:
# 计算梯度
exp_wxi = np.exp(np.dot(w,xi))
v += xi * yi - (xi * exp_wxi) / (1 + exp_wxi)
# 梯度的均方根
v2 = np.square(v)
# 计算分母项
v_i = beita * v_i + (1 - beita) * v2
# 更新w
w += h * v / (np.sqrt(v_i) + 1e-8)
return w
逻辑斯蒂回归 - Adam:
'''
逻辑斯蒂回归 - Adam
-------------------------------------
数据集:Mnist
训练集数量:60000
测试集数量:10000
---------------------------------
训练结果:
迭代次数:400
训练时间:148s
测试时间:0.56s
正确率:0.85
'''
'''
逻辑斯蒂回归 - Adam
--------------
输入:
data:训练集数据
label:训练集标记
itertime:迭代次数
-------------
输出:
w:最优化的权值向量
'''
def Logistic(data, label, itertime):
# 初始化w
FeatureNum = np.shape(data)[1]
w = np.zeros(FeatureNum)
# 设定学习率
h = 0.001
# 样本数
SampleNum = len(data)
# 将data转换成ndarray格式,方便后续的计算
data = np.array(data)
# 设置超参数,用于设置动量中对前一次动量和速度的依赖程度
beita1 = 0.9
beita2 = 0.999
# 初始化分母项
v_i = np.zeros(FeatureNum)
momentum = np.zeros(FeatureNum)
# 迭代
for i in range(itertime):
# 初始化梯度
v = np.zeros(FeatureNum)
# 遍历每一个样本点
for j in range(SampleNum):
# 得到该样本的特征向量和标记
xi = data[j]
yi = label[j]
# 如果分类错误,更新w_i
if predict(w, xi) != yi:
# 计算梯度
exp_wxi = np.exp(np.dot(w,xi))
v += xi * yi - (xi * exp_wxi) / (1 + exp_wxi)
# 梯度的均方根
v2 = np.square(v)
# 计算分母项
v_i = beita2 * v_i + (1 - beita2) * v2
v_i_hat = v_i / (1 - np.power(beita2, i + 1))
# 计算动量
momentum = beita1 * momentum + (1 - beita1) * v
momentum_hat = momentum / (1 - np.power(beita1, i + 1))
# 更新w
w += h * momentum_hat / (np.sqrt(v_i_hat) + 1e-8)
return w
github:
如果觉得对您有帮助,还烦请点击下面的链接,帮忙github点个star~谢谢~
Zhouxiaonnan/machine-learning-notesandcode
欢迎关注专栏:
学习笔记:数据分析,机器学习,深度学习zhuanlan.zhihu.com机器学习模型Python复现:
舟晓南:感知机模型python复现 - 随机梯度下降法;梯度下降法;adagrad;对偶形式
舟晓南:k近邻(KNN)模型python复现 - 线性扫描;带权值的近邻点优化方法
舟晓南:朴素贝叶斯(Bayes)模型python复现 - 贝叶斯估计;下溢出问题
舟晓南:决策树(Decision Tree)模型python复现 - ID3;C4.5;CART;剪枝
机器学习模型理论部分:
舟晓南:统计学习方法 - 感知机模型解读 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 感知机模型的收敛性解读 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - k近邻模型解读 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 朴素贝叶斯模型解读 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 朴素贝叶斯之后验概率最大化的含义 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 决策树,CART决策树解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 逻辑斯蒂回归解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 最大熵模型解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 改进的迭代尺度法IIS解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 线性可分支持向量机解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 线性支持向量机解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 非线性支持向量机解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 序列最小最优化算法(SMO)解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 提升算法Adaboost解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - 提升树算法解析 | 数据分析,机器学习,学习历程全记录
舟晓南:统计学习方法 - EM算法解析 | 数据分析,机器学习,学习历程全记录
MySQL:
舟晓南:转行数据分析师如何开始学习SQL | 工科生三个月转行数据分析学习心得
舟晓南:MySQL的执行逻辑和表的结构 | 数据分析学习历程全记录
舟晓南:MySQL优化查询1:索引及其使用技巧 | 数据分析学习历程全记录
舟晓南:MySQL优化查询2:如何查找低效率语句 | 数据分析学习历程全记录
舟晓南:MySQL优化查询3:explain和show profiles | 数据分析学习历程全记录
舟晓南:MySQL优化查询4:24种查询优化的具体方法 | 数据分析学习历程全记录
转行数据分析相关:
舟晓南:如何转行和学习数据分析 | 工科生三个月成功转行数据分析心得浅谈
舟晓南:求职数据分析师岗位,简历应该如何写?|工科生三个月成功转行数据分析心得浅谈
数据分析,机器学习学习社群正式启动~
需要学习资料,想要加入社群均可私信~
在这里会分享各种数据分析相关资源,技能学习技巧和经验等等~
详情私信,一起进步吧!
写于成都 2020-10-1