机器学习第6天——线性模型(2)
文章目录
- 3. 线性模型(2)
-
- 3.1 线性判别分析
- 3.2 多分类学习
- 3.3 类别不平衡问题
- 4. 第三章线性模型课后习题
3. 线性模型(2)
3.1 线性判别分析
- 概念
- 线性判别分析 (Linear Discriminant Analysis , 简称 LDA)。- 是一种经典的线性学习方法。- 最早由 Fisher 提出,亦称 "Fisher" 判别分析。
- LDA 的思想
1. 给定训练样例集2. 设法将样例投影到一条直线上3. 使得同类样例的投影点尽可能接近。4. 异类样例的投影点尽可能远离。- 在对新样本进行分类时,将其投影- 根据投影的点的位置确定新的样本类别。
- 怎样让同类样例的投影点尽可能近?
分析
已知:给定数据集 D = {(x1,y1), ..., (xm,ym)}, yi ∈ {0, 1}。这是一个二分类问题。令:Xk, Uk, ∑K 分别表示第 k ∈ {0, 1}类示例的,集合,均值向量,协方差矩阵操作:将数据投影到直线 W 上直线 w 是已知训练好的直线。结论:一、两类样本的中心在直线上的投影分别为:0类:W^T*U01类:W^T*U1二、两类样本的协方差分别为:0类:W^T*∑0W1类:W^T*∑1W
公式
结论
1. 欲使同类样例的投影点尽可能接近即 W^T*∑0W+W^T*∑1W 尽可能小2. 欲使异类样例的投影点尽可能远离||W^T*U0-W^T*U1|| 尽可能大
- 最优线性(最大化线性判别分析的条件)
使 J 值最大
类内散度矩阵
类间散度矩阵
重写 J 值
确定 w
3.2 多分类学习
- 思路
拆解法即将多分类任务拆分为若干个二分类任务求解。具体来讲就是:先对问题进行拆分,然后为拆分出的每个二分类任务训练一个分类器。
- 拆分策略
1. 一对一,One vs One, OvO- 两两配对组成一个新样本,一个作为正例,一个作为反例。- 新样本将同时提交给所有的分类器。- 把预测结果最多的作为最终的分类结果。2. 一对其余,One vs Rest, OvR- 每次将一个类作为正例,其余类作为反例。- 若有一个分类器预测为正例,则对应类标记为最终结果。3. 多对多,Many vs Many, MvM- 将若干个类作为正类,若干个作为反类。- 但正,反类构造必须有特殊的设计。- 有一种常用的 MvM 技术:纠错输出码,简称 ECOC
3.3 类别不平衡问题
- 问题导入
- 前面介绍的分类学习方法都有一个共同的基本假设,即不同类别的训练样例数目相当.- 如果不同类别的训练样例数目稍有差别,通常影响不大,- 但若差别很大,则会对学习过程造成困扰.- 例如有 998 个反例,但正例只有2个,- 那么学习方法只需返回一个永远将新样本预测为反例的学习器,就能达到 99.8% 的精度;- 然而这样的学习器往往没有价值,因为它不能预测出任何正例.
- 类别不平衡
- 类别不平衡(class imbalance) 就是指分类任务中不同类别的训练样例数目差别很大的情况.- 本节假定正类样例较少,反类样例较多.
- 解决方法
往期回顾
观测几率
当训练集中正、反例的数目不同时。令m+表示正例数目,m-表示反例数目则观测几率是 m+/m-,只要分类器的预测几率高于观测几率就应判定为 正例
数学公式
结论
- 我们的分类器是基于 y/(1-y) > 1来进行决策的。- 因此,需对其预测值进行调整。- 同时对两边乘以 m-/m+(观测几率的倒数)- 这就是类别不平衡学习的一个基本策略一"再缩放" (rescaling).
- 实际情况
实际操作不简单
- 主要因为"训练集是真实样本总体的无偏采样"这个假设往往并不成立。- 也就是说 我们未必能有效地基于训练集观测几率来推断出真实几率。
现有技术大体上有三类做法
1. 第一类- 是直接对训练集里的反类样例进行"欠采样" (undersampling) ,- 即去除一些反倒使得正、反例数日接近然后再进行学习;2. 第二类- 是对训练集里的正类样例进行"过来样" (oversampling) ,- 即增加一些正例使得正、反例数目接近,然后再进行学习;3. 第三类- 是直接基于原始训练集进行学习,- 但在用训练好的分类器进行预测时,将式(3.48) 嵌入到其决策过程中,称为"阔值移动" (threshold-moving).
4. 第三章线性模型课后习题
- 题3.1
试析在什么情况下f(x)=w^(T)+b中不必考虑偏置项b。
- 为什么要加偏置项,它的作用是什么?1. 加偏置项是为了更好的拟合数据。2. 在f(x)进行归一化处理时消除偏置。3. 当只需要考虑x的取值对y的影响的话,则可以不用考虑b。
- 题3.2
试证明,对于参数 w,对率回归的目标函数(3.18) 是非凸的,但其对数似然函数(3.27) 是凸的。
提供个思路:求二阶导,二阶导小于零,图像为凸。反之。过程:后面我写到纸上
- 题3.3
编程实现对率回归,并给出西瓜数据集3.0a上的结果。
python 代码
# as 重命名# numpy 支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。import numpy as npimport math# Matplotlib(绘图库)import matplotlib.pyplot as pltdata_x = [[0.697, 0.460], [0.774, 0.376], [0.634, 0.264], [0.608, 0.318], [0.556, 0.215], [0.403, 0.237], [0.481, 0.149], [0.437, 0.211], [0.666, 0.091], [0.243, 0.267], [0.245, 0.057], [0.343, 0.099], [0.639, 0.161], [0.657, 0.198], [0.360, 0.370], [0.593, 0.042], [0.719, 0.103] ]data_y = [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]# 线性回归模型的基本公式 y = w^Tx + b# b 在这里省略了def combine(param_w, param_x): # 创建矩阵 np.mat([1, 2, 3]) -> matrix([1, 2, 3]) param_x = np.mat(param_x + [1.]).T # .T作用于矩阵,用作球矩阵的转置 return param_w.T * param_x # w^Tx# 对数几率函数 : y = 1 / (1 + e^-z)# z 在这里是为上面的线性回归模型的基本公式 w^Tx + bdef logistic_function(param_w, param_x): return 1 / (1 + math.exp(-combine(param_w, param_x))) # math.exp( x ) 返回x的指数,e^x。# 对数几率回归模型 : y = 1 / (1 + e^-(w^Tx+b))def predict(param_w, param_x): return math.exp(combine(param_w, param_x)) / (1 + math.exp(combine(param_w, param_x)))# 这里用 w 来代表 欧米噶,形似w = np.mat([0.] * 3).Tsteps = 50# 训练样本for step in range(steps): # >>> np.zeros((3,1)) # array([[0.], # [0.], # [0.]]) param_1 = np.zeros((3, 1)) # 生成一个3*1的全0数组 for i in range(len(data_x)): x = np.mat(data_x[i] + [1.]).T param_1 = param_1 - x * (data_y[i] - predict(w, data_x[i])) param_2 = np.zeros((3, 3)) # 生成一个3*3的全0数组 for i in range(len(data_x)): x = np.mat(data_x[i] + [1.]).T param_2 = param_2 + x * x.T * predict(w, data_x[i]) * (1 - predict(w, data_x[i])) last_w = w w = last_w - param_2.I * param_1 # param_2.I ??? # norm则表示范数,范数是一种强化了的距离概念 if np.linalg.norm(last_w.T - w.T) < 1e-6: # 1e-6已经被认为是可处理的最小 print(step) break# 绘图for i in range(len(data_x)): if data_y[i] == 1: # 蓝色园点表示好瓜 plt.plot(data_x[i][0], data_x[i][1], 'ob') # "b"为蓝色, "o"为圆点, ":"为点线 else: # 绿色三角表示坏瓜 plt.plot(data_x[i][0], data_x[i][1], '^g') # '^g' : 上三角形状,绿色 #详情搜 plt.plot()函数详解w_0 = w[0, 0]w_1 = w[1, 0]b = w[2, 0]print(w_0, w_1, b)x_0 = -b / w_0 # (x_0, 0)x_1 = -b / w_1 # (0, x_1)plt.plot([x_0, 0], [0, x_1])plt.show()