本系列所有的代码和数据都可以从陈强老师的个人主页上下载:Python数据程序

参考书目:陈强.机器学习及Python应用. 北京:高等教育出版社, 2021.

本系列基本不讲数学原理,只从代码角度去让读者们利用最简洁的Python代码实现机器学习方法。


与逻辑回归类似,判别分析是用来做分类的。判别分析也是比较经典的多元统计分析方法。它有点类似于主成分,尽可能的将数据从不同的方向投影开,因此判别分析还具有降维的功能。判别分析有判别函数和系数,根据判别函数的不同,可以分为线性判别和二次判别。最初的判别分析是用来做分类的,后来也推广到可以做多分类,目前好像不能用于回归问题。

判别分析Python案例:

导入sklearn包,本次采用鸢尾花数据集,因为判别分析提出的时候就是采用 的这个数据集验证其有效性的。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import cohen_kappa_score

iris = load_iris()  #加载数据
dir(iris)    #查看数据里面的东西
iris.feature_names  #查看特征变量x的名称
iris.feature_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']  #重命名
X = pd.DataFrame(iris.data, columns=iris.feature_names)  #变为数据框
print(X)

 可以看到是150个样本,四个特征变量,下面画出相关系数热力图:

X.corr()
sns.heatmap(X.corr(), cmap='Blues', annot=True)

 查看y的取值,只有三种鸢尾花

y = iris.target
y

 开始判别分析!

model = LinearDiscriminantAnalysis()
model.fit(X, y)     #拟合
model.score(X, y)   #计算预测精度

#先验概率
model.priors_
#特征变量分组均值
model.means_
#线性判元对于组间方差的贡献
model.explained_variance_ratio_
#线性判元的估计系数
model.scalings_
#变为数据框展示
lda_loadings = pd.DataFrame(model.scalings_, index=iris.feature_names, columns=['LD1', 'LD2'])
lda_loadings

画出每个样本的线性判别得分

lda_scores = model.fit(X, y).transform(X) #或lda_scores = model.fit_transform(X, y)
lda_scores.shape
lda_scores[:5, :]

LDA_scores = pd.DataFrame(lda_scores, columns=['LD1', 'LD2'])
LDA_scores['Species'] = iris.target
LDA_scores.head()

d = {0: 'setosa', 1: 'versicolor', 2: 'virginica'}
LDA_scores['Species'] = LDA_scores['Species'].map(d) 
LDA_scores.head()

sns.scatterplot(x='LD1', y='LD2', data=LDA_scores, hue='Species')

 

 可以看出LD1这个维度上很好区分不同的鸢尾花品种。

下面只采用两个特征变量,直观的画出线性判别的决策边界

X2 = X.iloc[:, 2:4]
model = LinearDiscriminantAnalysis()
model.fit(X2, y)
model.score(X2, y)

model.explained_variance_ratio_

from mlxtend.plotting import plot_decision_regions

plot_decision_regions(np.array(X2), y, model)
plt.xlabel('petal_length')
plt.ylabel('petal_width')
plt.title('Decision Boundary for LDA')

 

 二次判别分析

X_train, X_test, y_train, y_test =  train_test_split(X, y, test_size=0.3, stratify=y, random_state=123)

model = QuadraticDiscriminantAnalysis()
model.fit(X_train, y_train)
model.score(X_test, y_test)    # Accuracy

prob = model.predict_proba(X_test)
prob[:3]

pred = model.predict(X_test)
pred[:5]

confusion_matrix(y_test, pred)

print(classification_report(y_test, pred))

cohen_kappa_score(y_test, pred)

同样选取两个特征变量进画出其决策边界

X2 = X.iloc[:, 2:4]
model = QuadraticDiscriminantAnalysis()
model.fit(X2, y)
model.score(X2, y)

plot_decision_regions(np.array(X2), y, model)
plt.xlabel('petal_length')
plt.ylabel('petal_width')
plt.title('Decision Boundary for QDA')

 判别分析用于降维

线性判别类似主成分可以降维,但是不同的是线性判别利用了标签y的信息。并且降维后的数据也是原始数据的线性组合,失去了其意义,不好解释。下面将鸢尾花四个特征变为2个特征。

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
model=LDA(n_components=2)
model.fit_transform(X,y)

 

更多推荐