荐 逻辑(Logistic)回归原理及Python实现(含数据集)
程序员文章站
2024-01-22 14:33:40
二元逻辑回归的损失函数(极大似然函数)极小化的求解,有比较多的方法,最常见的有梯度下降法,坐标轴下降法,等牛顿法等,最常用的是梯度下降来不断逼近最优解。梯度下降法:随机梯度下降(SGD)、批量梯度下降(BGD)、小批量梯度下降(MBGD)。优缺点优点:(1)训练速度较快,分类的时候,计算量仅仅只和特征的数目相关;(2)简单易理解,模型的可解释性非常好,从特征的权重可以看到不同的特征对最后结果的影响;(3)适合二分类问题,不需要缩放输入特征;(4)内...
原理
基本原理
损失函数的求解方法
- 二元逻辑回归的损失函数(极大似然函数)极小化的求解,有比较多的方法,最常见的有梯度下降法,坐标轴下降法,等牛顿法等,最常用的是梯度下降来不断逼近最优解。
- 梯度下降法:随机梯度下降(SGD)、批量梯度下降(BGD)、小批量梯度下降(MBGD)。
优缺点
优点:
(1)训练速度较快,分类的时候,计算量仅仅只和特征的数目相关;
(2)简单易理解,模型的可解释性非常好,从特征的权重可以看到不同的特征对最后结果的影响;
(3)适合二分类问题,不需要缩放输入特征;
(4)内存资源占用小,因为只需要存储各个维度的特征值;
缺点:
(1)不能用Logistic回归去解决非线性问题,因为Logistic的决策面试线性的;
(2)对多重共线性数据较为敏感;
(3)很难处理数据不平衡的问题;
(4)准确率并不是很高,因为形式非常的简单(非常类似线性模型),很难去拟合数据的真实分布;
(5)逻辑回归本身无法筛选特征,有时会用gbdt来筛选特征,然后再上逻辑回归。
Python实现
LR_Train训练模型
# coding:UTF-8
# Author:xwj
# Date:2020-7-2
# Email:xwj770427414@126.com
# Environment:Python3.7
import numpy as np
def sig(x):
"""
对数几率函数 Sigmoid函数
:param x: feature * x + b
:return:P(y=1|x,w,b)
"""
return 1.0/(1+np.exp(-x))
def lr_train_bfd(feature, label, maxCycle, alpha):
"""
利用梯度下降法训练LR模型
:param feature:mat,特征
:param label: mar,标签
:param maxCycle: int,最大迭代次数
:param alpha: float,学习率
:return: w,权重
"""
n = np.shape(feature)[1] # 特征的个数
w = np.mat(np.ones((n, 1))) # 初始化权重
i = 0
while i <= maxCycle: # 在最大迭代次数内循环
i += 1
h = sig(feature * w) # 计算Sigmoid的值
err = label - h # 误差
if i % 100 == 0: # 没迭代一百次进行一次
print('\t--------迭代次数 = ' + str(i) + ',训练错误率 = ' + str(error_rate(h, label)) )
w = w + alpha * feature.T * err # 权重修正
return w
def error_rate(h, label):
"""
计算损失函数值
:param h: mat,预测值
:param label: mat,实际值
:return: float,err/m错误率
"""
m = np.shape(h)[0] # 预测值的个数
sum_err = 0.0 # 初始化错误率
for i in range(m): # 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
def load_data(file_name):
"""
清洗数据,导入数据
:param file_name: 数据集名称
:return: 矩阵形式的特征值和标签
"""
f = open(file_name)
feature_data = [] # 特征数据
label_data = [] # 标签数据
for line in f.readlines(): # 数据集逐行读取
feature_tmp = [] # 暂存特征
label_tmp = [] # 暂存标签
lines = line.strip().split('\t') # 去除数据收尾特殊符号(\n等),以\t为间隔,将数据分割成列表。
feature_tmp.append(1) # 初始偏置项b为1 合并至特征中
for i in range(len(lines) - 1): # 特征数据逐个读取,除去末尾的标签
feature_tmp.append(float(lines[i])) # 将特征逐个浮点数化并加入暂存特征,构成列表
label_tmp.append(float(lines[-1])) # 将标签加入暂存标签,构成列表
feature_data.append(feature_tmp) # 将暂存列表加入总列表
label_data.append(label_tmp) # 将暂存列表加入总列表
f.close()
return np.mat(feature_data), np.mat(label_data) # 将特征序列、标签序列 矩阵化
def save_model(file_name, w):
"""
保存最终模型的权重
:param file_name:数据集名称
:param w: 权重
:return: 保存模型的文件
"""
m = np.shape(w)[0]
f_w = open(file_name, '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()
if __name__ == "__main__":
print('------1.导入数据------')
feature, label = load_data("data.txt")
print('------2.训练模型------')
w = lr_train_bfd(feature, label, 1000, 0.01)
print('------3.保存模型------')
save_model("weights.txt", w)
测试模型
# coding:UTF-8
# Author:xwj
# Date:2020-7-2
# Email:xwj770427414@126.com
# Environment:Python3.7
import numpy as np
def sig(x):
"""
对数几率函数 Sigmoid函数
:param x: feature * x + b
:return:P(y=1|x,w,b)
"""
return 1.0/(1+np.exp(-x))
def load_weight(w):
"""
导入LR训练模型
:param w: w权重存储位置
:return: np.mat(w),权重的矩阵
"""
f = open(w)
w = []
for line in f.readlines():
lines = line.strip().split('\t')
w_tmp = []
for x in lines:
w_tmp.append(float(x))
w.append(w_tmp)
f.close()
return np.mat(w)
def load_data(file_name, n):
"""
导入测试数据
:param file_name:测试数据位置
:param n: 特征的个数
:return: np.mat(feature)测试集的特征
"""
f = open(file_name)
feature_data = []
for line in f.readlines():
feature_tmp = []
lines = line.strip().split('\t')
if len(lines) != n - 1:
continue
feature_tmp.append(1) # 初始偏置项b为1 合并至特征中
for x in lines:
feature_tmp.append(float(x))
feature_data.append(feature_tmp)
f.close()
return np.mat(feature_data)
def predict(data, w):
"""
对测试数据进行预测
:param data: mat,模型的特征
:param w: 模型的参数
:return: h,mat,最终预测结果
"""
h = sig(data * w.T)
m = np.shape(h)[0]
for i in range(m):
if h[i, 0] < 0/5:
h[1, 0] = 0.0
else:
h[i, 0] = 1.0
return h
def save_result(file_name, result):
"""
保存最终预测结果
:param file_name: 预测结果保存文件名
:param result: mat,预测的结果
"""
m = np.shape(result)[0]
tmp = []
for i in range(m):
tmp.append(str(h[i, 0]))
f_result = open(file_name, "w")
f_result.write("\t".join(tmp))
f_result.close()
if __name__ == "__main__":
print('------1.导入模型------')
w = load_weight("weights.txt")
n = np.shape(w)[1]
print('------2.导入数据------')
testData = load_data("test_data", n)
print('------3.预测数据------')
h = predict(testData, w)
print('------4.保存结果------')
save_result("result.txt", h)
数据集
本文地址:https://blog.csdn.net/weixin_46283583/article/details/107316386
上一篇: Storm入门