本篇博客主要是逻辑回归的手撸代码,但是还有我的简单理解,用QW的形式描述。并不是逻辑回归的介绍,如有错误还望指出。
逻辑回归与线性回归关系
逻辑回归与线性回归同属于广义线性模型。逻辑回归就是用线性回归模型的预测值去拟合真实标记的对数几率。相当于在线性回归模型上加了一层非线性映射。
逻辑回归和线性回归就是得到一条直线。线性回归的直线是尽可能去拟合输入向量x的分布,使得训练集中所有样本点到直线的距离最短;而逻辑回归的直线是尽可能去拟合决策边界,使得训练集中的样本点尽可能分离开。因此他们的目的是不同的。
逻辑回归为什么用交叉熵损失函数,而不用平方损失函数
平方损失函数是线性回归假设样本误差服从高斯分布,利用极大似然估计推导而得;交叉熵损失函数是逻辑回归假设样本服从二项分布,利用极大似然估计推导而得。这是由于模型优化目标不同而推导得到不同的损失函数。
对于逻辑回归而言,交叉熵损失函数是凸函数,而平方损失函数不是凸函数。凸函数有着良好的优化性质,可以保证局部最优就是全局最优。而非凸函数,存在很多局部极小值,不宜优化。
交叉熵损失函数可以很好的衡量逻辑回归决策函数的好坏。
相对于其他分类算法,逻辑回归的优势
逻辑回归是对分类可能性建模,不需事先假设数据分布,避免了因假设不准确而带来的后果。
逻辑回归不仅可以预测类别,还可以得到近似的概率预测。
逻辑回归的对率函数是任意阶可导函数,数学性质好,易于优化。
代码如下:
import numpy as np import matplotlib.pyplot as plt import warnings warnings.filterwarnings('ignore') %matplotlib inline #这里的数据是用的机器学习实战上的数据,其中也参考了上面的代码 data = [] label = [] for line in open('testSet.txt').readlines(): tmpLine = line.strip().split() data.append([1.0, float(tmpLine[0]), float(tmpLine[1])]) label.append(int(tmpLine[2])) data = np.matrix(data) label = np.matrix(label).transpose() #定义sigmoid函数 def sigmoid(x): return 1 / (1 + np.exp(-x)) # 随机梯度下降 # data: 特征数据 # label: 标签 # alpha: 学习率 # epoch: 迭代次数 def SGD(data, label, alpha, epoch): m, n = np.shape(data) weights = np.ones((n, 1)) for i in range(epoch): for j in np.random.permutation(m): h = sigmoid(np.dot(data[j], weights)) error = h - label[j] weights = weights - (alpha * error * data[j]).transpose() return weights # 批梯度下降 # data: 特征数据 # label: 标签 # alpha: 学习率 # epoch: 迭代次数 def BSG(data, label, alpha, epoch): m, n = np.shape(data) weights = np.ones((n, 1)) for i in range(epoch): h = sigmoid(np.dot(data, weights)) error = h - label weights = weights - np.dot(data.T, error) * alpha / m return weights # 小批量梯度下降 # data: 特征数据 # label: 标签 # alpha: 学习率 # epoch: 迭代次数 # miniBatch: 一个小批量的大小 def miniBSG(data, label, alpha, epoch, miniBatch): m, n = np.shape(data) weights = np.ones((n, 1)) for i in range(epoch): arr_reflash = np.random.permutation(m) miniBatch_arr = np.array_split(arr_reflash, miniBatch) for mini in miniBatch_arr: h = sigmoid(np.dot(data[mini], weights)) error = h - label[mini] weights = weights - np.dot(data[mini].T, error) * alpha / miniBatch return weights def plotLine(data, label, weights): m = np.shape(data)[0] x1 = [] y1 = [] x2 = [] y2 = [] for i in range(m): if(label[i] == 1): x1.append(data[i, 1]) y1.append(data[i, 2]) else: x2.append(data[i, 1]) y2.append(data[i, 2]) plt.figure(figsize=(10, 5)) plt.scatter(x1, y1, c='r', marker='o') plt.scatter(x2, y2, c='g', marker='x') x = np.arange(-4, 4, 0.1) y = ((- weights[0] - weights[1] * x) / weights[2]).T plt.plot(x, y) plt.xlabel('X1') plt.ylabel('X2')
参考
统计学习方法 -李航
机器学习 -周志华
机器学习实战 -Peter Harrington
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦