1、二项逻辑回归模型
二项回归模型是一种二分类模型,由条件概率分布 P(Y|X) 表示,形式为参数化的逻辑分布。这里的随机变量 X 取值为实数,随机变量 Y 取值为 1或0 ,通过监督学习的方法来估计模型参数。
定义1:二项逻辑回归模型是如下的条件概率分布:
这里x为输入,y为{0,1}输出,w为权值参数向量,b为偏置向量,wx为w和x的内积。
2、模型参数的估计
逻辑回归模型学习时,对于给定的数据集 T={(x1,y1),(x2,y2),...,(xn,yn)} 其中x属于R,yi属于{0,1},可以用极大似然估计法估计模型参数,从而得到逻辑回归模型:
设:P(Y=1|x) = h(x), P(Y=0|x) = 1-h(x),其似然函数为:
|
|
|
对L(w)函数求极大值,就可以得到w的估计值。
这样,问题就变成了以对数似然函数为目标函数的最优化问题。逻辑回归学习中通常采用的方法是梯度下降法以及牛顿法,下文使用梯度下降法。
假设w的极大似然估计值是w^,那么学到的逻辑回归模型为:
3、利用梯度下降法训练获取逻辑回归模型的参数
把上述中的似然函数作为模型参数估计的损失函数,通过梯度下降法对其进行求解,其梯度为:
|
于是得到更新公式:
模型估计似然函数——损失函数的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
梯度下降法算法的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
权值保存函数的Python实现:
# 保存最终的模型参数
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()
Logistic Regression算法实践完整Python代码:
# -*- 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/1-Logistic%20Regression
参考书目:
[1].统计方法.李航
[2].Python机器学习算法.赵志勇
[3].利用Python进行数据分析.WesKinney著,唐学韬等译