iris_LogisticRegression_optimization

(1)背景

  • 常规任务是利用给定的类别、已知的训练数据来学习分类规则和分类器,然后对未知数据进行分类(或预测)。逻辑回归常用来解决二分类的问题。与线性回归有很多相同之处,去除Sigmoid映射函数的话,逻辑回归算法就是一个线性回归。

(2)基本假设

  • 面对一个回归或者分类问题,建立代价函数,然后通过优化方法(通过train_data训练我们的model)迭代求解出最优的模型参数,然后测试验证我们这个求解的模型的好坏
  • 优化的部分是不用手动指定迭代次数,原理是当损失函数变化不大时停止迭代,而要实现这个功能我们需要一个期望的差值(exp_gap)对损失函数进行判定,是否可以停止迭代。

二,目标函数

  • 是我们最终要优化的函数

三,训练LogisticRegression_model

  • 这里简单介绍一下交叉熵损失函数
  • 对于在二分类损失函数中应用,交叉熵损失函数为以下形式。

逻辑回归校准曲线 逻辑回归改进_迭代

  • 在python中的实现为:
第一种实现方法
cost = - np.sum(y * np.log(p) + (1 - y) * np.log(1 - p)) # 损失函数
第二种实现方法
cost = - np.dot(y, np.log(p)) - np.dot(1-y, np.log(1-p))
  • 交叉熵能够衡量同一个随机变量中的两个不同概率分布的差异程度,在机器学习中就表示为真实概率分布与预测概率分布之间的差异。
  • 交叉熵的值越小,模型预测效果就越好
  • 交叉熵经常搭配softmax使用,将输出的结果进行处理,使其多个分类的预测值和为1,再通过交叉熵来计算损失。
  • 参数更新:
self.w_[1:] += self.learning_rate*np.dot(X.T, y - p)
  • python实现:
def train(self, X, y):
	X = np.asarray(X)
	y = np.asarray(y)
	self.w_ = np.zeros(1 + X.shape[1])
	self.loss_ = []
	flag = True
	self.times = 0  #迭代次数初始化为0
	while flag:
	z = np.dot(X, self.w_[1:]) + self.w_[0]
	p = self.Sigmoid(z)
	cost = - np.sum(y * np.log(p) + (1 - y) * np.log(1 - p))/len(y) # 损失函数
	# cost = - np.dot(y, np.log(p)) - np.dot(1-y, np.log(1-p))
	self.loss_.append(cost)
	# 通过不断调整权重值,选取最优的参数
	self.w_[0] += self.learning_rate*np.sum(y - p)
	self.w_[1:] += self.learning_rate*np.dot(X.T, y - p)
	self.times += 1  #记录迭代的次数
	if self.times != 1 and self.loss_[-2] > self.loss_[-1]:
	gap = self.loss_[-2] - self.loss_[-1]
	if gap <= self.exp_gap:
	break
	# self.exp_gap:就是我们期望的差值

四,预测Predict

  • 这里使用的z = np.dot(X, self.w_[1:]) + self.w_[0],z的值域为负无穷到正无穷,并不能达到我们想要进行二分类的目的,所以我们引入了sigmoid函数
  • 简单介绍一下sigmoid函数:
1.逻辑函数(logistic function)也成为对数几率函数,其函数为:

逻辑回归校准曲线 逻辑回归改进_python_02


2.典型的Sigmoid函数,他把可能在较大范围内变化的输入值“挤压到”(0,1),输出范围内,因此又时也成为“挤压函数”(squashing function)


3.在分类问题中,我们经常需要找到一个单调可微函数将分类任务的真实标记y(分类结果所得数值一般是0-1之间的数,如0.99,0.35等,当我们需要的结果是0或者1)与线性回归模型的预测值联系起来。


4.考虑二分类任务,其输入标记y∈{0, 1},但实际情况产生值处于0和1之间,如线性回归模型产生的预测值为z = wx +b 实际值。为了实际值转换为0 或者 1。 我们需要一个函数以0.5来区分,最理想的是单位阶跃函数(unti-step function)


y= {0, x<0 ; 1,x > 0}


5.函数图像为:

逻辑回归校准曲线 逻辑回归改进_机器学习_03

  • 此处Python预测运用了sigmoid函数,进行二分类
def Pre_pro(self, X):
	X = np.asarray(X)
	z = np.dot(X, self.w_[1:]) + self.w_[0]
	p = self.Sigmoid(z)
	p = p.reshape(-1, 1)
	# print(np.concatenate([1-p, p], axis=1))
	return np.concatenate([1-p, p], axis=1)
def Pre(self, X):
	# print(self.Pre_pro(X))
	return np.argmax(self.Pre_pro(X), axis=1)

五,实验

(1)数据集的使用:

  • 这里我选择的是一个简单的数据集–鸢尾花iris
  • 该数据集有5个变量,其中4个特征变量1个目标分类变量。共有150个样本,目标变量为 花的类别 其都属于鸢尾属下的三个亚属,分别是山鸢尾 (Iris-setosa),变色鸢尾(Iris-versicolor)和维吉尼亚鸢尾(Iris-virginica)。包含的三种鸢尾花的四个特征,分别是花萼长度(cm)、花萼宽度(cm)、花瓣长度(cm)、花瓣宽度(cm),这些形态特征在过去被用来识别物种。
  • 数据只选取了其中目标变量为0,1的鸢尾花,现在数据集只有100个样本。
  • 代码:
from sklearn.datasets import load_iris
import numpy as np
iris = load_iris()
data = np.concatenate([iris['data'], iris['target'].reshape(-1, 1)], axis=1)
t1 = data[data[:, -1] == 0]
t2 = data[data[:, -1] == 1]

(2)训练集:

# 选取了t1的前35个样本,t2的前35个样本
train_X = np.concatenate([t1[:35, :-1], t2[:35, :-1]], axis=0)
train_y = np.concatenate([t1[:35, -1], t2[:35, -1]], axis=0)
# 对训练集进行打乱
np.random.seed(0)
np.random.shuffle(train_X)
np.random.seed(0)
np.random.shuffle(train_y)

(3)测试集:

# 测试集,选取t1,t2的后35条数据
test_X = np.concatenate([t1[35:, :-1], t2[35:, :-1]], axis=0)
test_y = np.concatenate([t1[35:, -1], t2[35:, -1]], axis=0)
# 对测试集进行打乱
np.random.seed(0)
np.random.shuffle(test_X)
np.random.seed(0)
np.random.shuffle(test_y)

(4)运行结果

  • 真实值与预测值:
  • 逻辑回归校准曲线 逻辑回归改进_迭代_04

  • Loss值:
  • 逻辑回归校准曲线 逻辑回归改进_损失函数_05

六,实验总结

  • 这里说说逻辑回归的优缺点:
  • 优点:
  1. 实现简单,广泛的应用于工业问题上;
  2. 分类时计算量非常小,速度很快,存储资源低;
  3. 便利的观测样本概率分数;
  4. 对逻辑回归而言,多重共线性并不是问题,它可以结合L2正则化来解决该问题;
  5. 计算代价不高,易于理解和实现。
  • 缺点:
  1. 当特征空间很大时,逻辑回归的性能不是很好;
  2. 容易欠拟合,一般准确度不太高;
  3. 不能很好地处理大量多类特征或变量;
  4. 只能处理两分类问题(在此基础上衍生出来的softmax可以用于多分类),且必须线性可分;
  5. 对于非线性特征,需要进行转换.