第一次更新:2024/4/29
目录
一. 主要思想
- 判别分析是在已知分类的前提下,将给定的新样品按照某种分类规则判入某个类中,它是研究如何将个体"归类”的一种统计分析方法。
1. 判别模型与生成模型的对比
在对于数据的分类中,我们在上一篇文章中详细讲解了朴素贝叶斯分类器这一模型,朴素贝叶斯是一种典型的生成模型;与之相对的是判别模型,那我们继续来阐述一下判别模型分类的主要思想。
判别模型通过学习数据来建立一个清晰的分类边界,以达到快速分类的效果。相比于生成模型,判别模型所需要的样本量更少,判别模型可以基于少量数据来建立分类边界;判别模型可以对样本特征数据进行处理和抽象,以简化问题或获得更有效的特征,比如可以对特征进行降维,或者通过特征交叉等方式构造新的特征,对于生成模型原始数据再处理就很难识别概率分布函数。判别模型无法在存在隐变量的情况下使用,生成模型可用于存在隐变量的情况。
判断一个模型是生成模型还是判别模型的唯一标准就是该模型学习的是联合概率分布还是条件概率分布,学习联合概率分布的是生成模型,学习条件概率分布的是判别模型。
2. 判别模型分类
模型在进行数据分类的时候所建立的“分类边界”实际上就是一种判别规则,常见的判别规则分为两类:确定性的判别规则,统计性(又称概率性)的判别规则。依据判别规则的差异性,通常将判别分析划分为以下几种方式:
二. 算法原理及R代码实现
1. 距离判别法(直观判别法)
(1)算法原理
- 核心思想:样本与哪个总体的距离最近,就判别它来自该总体。
那如何来衡量样本与总体间的距离呢,在多元统计的学科中通常用马氏距离来衡量样本间的距离,样本x到一个总体均值为μ,协方差为∑的总体的马氏距离为:
作为一个立志于讲清每一个知识点的博主,接下来来理解一下这个公式,首先:
- 协方差是用来描述两个随机变量之间的相关性的量,在马氏距离中,样本与总体的相关性越强,协方差就也大;反之,样本与总体的相关性越弱,协方差越小。
- 均值是刻画数据的集中趋势。
如果数据集中的变量高度相关,则协方差将很高,除以较大的协方差将有效缩短距离。
同样,如果新样本与总体相关性不高,则协方差也不高,马氏距离也较大。
因此,它有效地解决了规模问题以及前文中谈到的变量之间的相关性。
欧氏距离与马氏距离的详细差异可参考这篇博文:马氏距离详解(数学原理、适用场景、应用示例代码)-CSDN博客
(2)r代码实现
码源来自:
#set.seed(1234)是r语言中用来设置随机种子的函数,使得每次运行随机数生成的结果都相同,便于我们进行重复性实验
set.seed(1234)
#从1到150的整数范围内随机抽取100个整数作为样本,样本遵循均匀分布
sa<-sample(1:150,100)
#从'iris'数据集中选择了与'sa'变量相对应的样本,并将结果存储在'dtrain'变量中,创建训练集
dtrain<-iris[sa,]
#显示了'dtrain'的前几行数据
head(dtrain)
#从'iris'数据集中删除了与'sa'变量相对应的样本,并选择了前四个特征的数据,结果存储在'dtest'变量中。创建测试集
dtest<-iris[-sa,1:4]
#查看测试集的初始数据
head(dtest)
#创建一个新的数据集d1,d1是从训练集dtrain中选取的,条件是Species列的值等于'setosa/versicolor/virginica'。
#dim(di)返回数据集的行数与列数
> d1<-subset(dtrain,Species=="setosa");dim(d1)
[1] 32 5
> d2<-subset(dtrain,Species=="versicolor");dim(d2)
[1] 32 5
> d3<-subset(dtrain,Species=="virginica");dim(d3)
[1] 36 5
#mahalanobis函数计算dtest和di[,1:4]之间的马氏距离
#colMeans(di[,1:4])是用来估计协方差矩阵的
#cov(di[,1:4])则是用来获取协方差矩阵。
ma1<-mahalanobis(dtest,colMeans(d1[,1:4]),cov(d1[,1:4]))
ma2<-mahalanobis(dtest,colMeans(d2[,1:4]),cov(d2[,1:4]))
ma3<-mahalanobis(dtest,colMeans(d3[,1:4]),cov(d3[,1:4]))
#创建新的数据框distance包含四个数据行(ma1, ma2, ma3)和iris数据框的剩余部分
distance<-cbind(ma1,ma2,ma3,iris[-sa,5])
#查看distance的数据,三个ma值最小的对应的类即为样本所属的类
head(distance)
#加载包
library(WMDB)
#从iris数据集中选择前四列的数据并将其存储在变量dta中
dta<-iris[,1:4]
#创建了一个长度为50的组变量species,其中包含3个类别的元素
species<-gl(3,50)
#调用了一个函数wmd,判断分类效率
wmd(dta,species)
2. 线性判别法(Fisher)
(1) 算法原理
- 核心思想:基于降维的方式将所有的样本数据投影到一维坐标轴上,然后设定一定的阈值,将样本进行区分。
- 基本步骤:它首先会将所有的样本向一个向量做投影,此时我们会获得新的坐标轴上的坐标位置,我们希望的是新的坐标类内距离小,类间距离大,也就是同类样本映射后的坐标尽可能的聚在一起,而不同类的样本映射后尽可能的远离。
step1. 向量在某一向量方向投影
首先如何找到投影方向?类似于计算机中的“松耦合,高内聚”思想,找到一个能将不同类别的样本能够分开的方向。
限定w向量的模为1,xi在w方向上的投影用内积表示为:
我们通常将投影记作:
我们将xi投影后记作zi,此时投影点的均值为:
其对应的方差为:
step2. 不同类别间的投影及方差
假设属于C1类的样本的投影点均值为:
对应组内方差为:
同理属于C2的样本的投影点均值为:
组内方差为:
step3. 类内小,类间大
- 类内表示:
- 类间表示:
根据“类内小,类间大”定义其目标函数J(ω):
进一步化简分子分母:
得到目标函数简化为:
其中引入类内方差定义(between_class):
类间方差定义(with-class):
得到目标函数最简式为:
step4. 求解w超平面
目标函数J(w)对w求导,化简得到w向量方向为:
(2)r代码实现
#加载库
library(MASS)
#获取iris数据集
data(iris)
#创建一个新的数据框(data.frame)diris,其中包含了iris数据集的前三个特征以及对应的三个类别标签
#将'species'列中的每个值设置为重复的1,2,3,总共50个样本
diris<-data.frame(rbind(iris3[,,1],iris3[,,2],iris3[,,3]),species=rep(c(1,2,3),rep(50,3)))
#显示了新创建的数据框数据
head(diris)
#划分训练集测试集
sa<-sample(1:150,75)
sa
#获取'diris'数据框中名为'species'的列中,索引为'sa'的行的数据,并计算这些数据的频数。
table(diris$species[sa])
#lda线性判别分类
z<-lda(species~.,diris,prior=c(1,1,1)/3,subset=sa)
#对z进行预测,预测的对象是'diris'数据集的'sa'列以外的部分,然后将预测结果存储在名为'pre'的变量中,同时包含了预测结果的类别信息。
pre<-predict(z,diris[-sa,])
pre$class
#判别结果准确度
#对变量'class'和'species[-sa]'进行比较,检查两者是否相等,如果相等则将值为1,否则为0。最后使用sum函数计算相等值的数量
class<-pre$class
diris$species[-sa]
sum(class==diris$species[-sa])
参考: