笔记|判别分析基础《Python数学实验与建模》

发布时间 2023-08-07 17:04:47作者: LateSpring

参考图书为:《Python数学实验与建模》司守奎,孙玺菁

定义

根据已掌握的每个类别的样本的数据信息,求出判别函数,再根据判别函数判别未知样本点的类别
“预测”
IMG_20220209_141935_edit_318718914911783-02.jpeg

已知

\(\textit{a}_k\)是某类中的第k个样本(该类中第k行向量)
待判定对象\(x\)又称为判别因子
IMG_20220209_140218_edit_318522422407646.jpg
IMG_20220209_141935_edit_318718914911783-01.jpeg

分类

1.距离判别法

建立判定对象到每类中心的距离,根据距离最近原则进行判别
IMG_20220209_142456_edit_318998804911740-01.jpeg
(对角线元素是每个指标的方差)
另一种思路
IMG_20220209_142939_edit_319256029701285.jpg
IMG_20220209_143620_edit_319659677727265.jpg
然而事实上协方差矩阵总是不相等的
IMG_20220209_143723_edit_319717793963714.jpg

局限性

简单实用,但未考虑每个总体的先验概率,未考虑到错判的误差

代码实现

import numpy as np
from sklearn.neighbors import KNeighborsClassifier
x0=np.array([[1.24,1.27], [1.36,1.74], [1.38,1.64], [1.38,1.82], [1.38,1.90], [1.40,1.70],
    [1.48,1.82], [1.54,1.82], [1.56,2.08], [1.14,1.78], [1.18,1.96], [1.20,1.86],
    [1.26,2.00], [1.28,2.00], [1.30,1.96]])   #输入已知样本数据
x=np.array([[1.24,1.80], [1.28,1.84], [1.40,2.04]])  #输入待判样本点数据

g=np.hstack([np.ones(9),2*np.ones(6)])  # g为已知样本数据的类别标号  np.hstack将参数元组的元素数组按水平方向进行叠加
v=np.cov(x0.T)  # 计算协方差 每行代表一个变量X,另一个行为变量Y
knn=KNeighborsClassifier(2,metric='mahalanobis',metric_params={'V': v})   # 马氏距离分类 有两类
knn.fit(x0,g); pre=knn.predict(x)
print("马氏距离分类结果:",pre)
print("马氏距离已知样本的误判率为:",1-knn.score(x0,g))
knn2=KNeighborsClassifier(2)  # 欧氏距离分类
knn2.fit(x0,g); pre2=knn2.predict(x); print("欧氏距离分类结果:",pre2)
print("欧氏距离已知样本的误判率为:",1-knn2.score(x0,g))

输出结果

马氏距离分类结果: [2. 2. 1.]
马氏距离已知样本的误判率为: 0.0
欧氏距离分类结果: [2. 1. 2.]
欧氏距离已知样本的误判率为: 0.0

2.Fisher判别法

基于方差分析的判别法。
通过取特征值对应的特征向量来降维。为的是使类内方差尽量小,类间方差尽量大。
Stitch_20220209_145521_edit_320124090898548.png

代码实现

import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
x0=np.array([[1.24,1.27], [1.36,1.74], [1.38,1.64], [1.38,1.82], [1.38,1.90], [1.40,1.70],
    [1.48,1.82], [1.54,1.82], [1.56,2.08], [1.14,1.78], [1.18,1.96], [1.20,1.86],
    [1.26,2.00], [1.28,2.00], [1.30,1.96]])   # 输入已知样本数据
x=np.array([[1.24,1.80], [1.28,1.84], [1.40,2.04]])  # 输入待判样本点数据
y0=np.hstack([np.ones(9),2*np.ones(6)])  # y0为已知样本数据的类别
clf = LDA()
clf.fit(x0, y0)
print("判别结果为:",clf.predict(x))
print("已知样本的误判率为:",1-clf.score(x0,y0))

运行结果

判别结果为: [2. 2. 2.]
已知样本的误判率为: 0.0

3.贝叶斯判别法

IMG_20220209_150135-01.jpeg

代码实现

import numpy as np
from sklearn.naive_bayes import GaussianNB
x0=np.array([[1.24,1.27], [1.36,1.74], [1.38,1.64], [1.38,1.82], [1.38,1.90], [1.40,1.70],
    [1.48,1.82], [1.54,1.82], [1.56,2.08], [1.14,1.78], [1.18,1.96], [1.20,1.86],
    [1.26,2.00], [1.28,2.00], [1.30,1.96]])   #输入已知样本数据
x=np.array([[1.24,1.80], [1.28,1.84], [1.40,2.04]])  #输入待判样本点数据
y0=np.hstack([np.ones(9),2*np.ones(6)])  #y0为已知样本数据的类别
clf = GaussianNB()
clf.fit(x0, y0)
print("判别结果为:",clf.predict(x))
print("已知样本的误判率为:",1-clf.score(x0,y0))

结果

判别结果为: [2. 2. 1.]
已知样本的误判率为: 0.0

判别标准的评价

1.回代误判率

将全体训练样本作为新样本,代回判别准则
IMG_20220209_151223_edit_320528404519320.jpg
缺陷:
往往是有偏的,而且比真实误判率小

2.交叉误判率

for i in range(n):
删除一个样品,用剩余的训练样品建立判别准则;
若本属于第k类,却误判为其他类;
\(\textit{N}_k\)+=1;
IMG_20220209_151223_edit_320528404519320.jpg