机器学习判别分析算法——线性判别分析实操代码详解(2)

完成代码

#第七章  判别分析算法
#7.2.1  载入分析所需要的模块和函数
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
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
from mpl_toolkits.mplot3d import Axes3D
from sklearn.datasets import make_classification
from sklearn.decomposition import PCA
#7.2.2  线性判别分析降维优势展示
#绘制三维数据的分布图
X, y = make_classification(n_samples=500, n_features=3, n_redundant=0,
                           n_classes=3, n_informative=2, n_clusters_per_class=1,
                           class_sep=0.5, random_state=100)#生成三类三维特征的数据
plt.rcParams['axes.unicode_minus']=False# 解决负号不显示问题
fig = plt.figure()
ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=20, azim=20)
ax.scatter(X[:, 0], X[:, 1], X[:, 2], marker='o', c=y)
#使用PCA进行降维
pca = PCA(n_components=2)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
X_new = pca.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1], marker='o', c=y,s=50)
plt.show()
#使用LDA进行降维
lda = LinearDiscriminantAnalysis()
lda.fit(X, y)
X_new = lda.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1], marker='o', c=y)
plt.show()#降维后样本特征信息之间的关系得以保留
#7.2.3  数据读取及观察
data=pd.read_csv(r'数据7.1.csv')
data.info()
len(data.columns)
data.columns
data.shape
data.dtypes
data.isnull().values.any()
data.isnull().sum()
data.head()
data.V1.value_counts()

#7.3  特征变量相关性分析
X = data.drop(['V1'],axis=1)#设置特征变量,即除V1之外的全部变量
y = data['V1']#设置响应变量,即V1
X.corr()
sns.heatmap(X.corr(), cmap='Blues', annot=True)

#7.4  使用样本示例全集开展线性判别分析
#7.4.1  模型估计及性能分析
# 使用样本示例全集开展LDA
model = LinearDiscriminantAnalysis()#使用LDA算法
model.fit(X, y)#使用fit方法进行拟合
model.score(X, y)
model.priors_
model.means_
np.set_printoptions(suppress=True)#不以科学计数法显示,而是直接显示数字
model.coef_#输出模型系数
model.intercept_#输出模型截距项
model.explained_variance_ratio_#输出可解释方差比例
model.scalings_

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

LDA_scores = pd.DataFrame(lda_scores, columns=['LD1', 'LD2'])
LDA_scores['网点类型'] = data['V1']
LDA_scores.head()

d = {0: '未转型网点', 1: '一般网点', 2: '精品网点'}
LDA_scores['网点类型'] = LDA_scores['网点类型'].map(d)
LDA_scores.head()
plt.rcParams['axes.unicode_minus']=False# 解决图表中负号不显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']#解决图表中中文显示问题。
sns.scatterplot(x='LD1', y='LD2', data=LDA_scores, hue='网点类型')

#7.4.2  运用两个特征变量绘制LDA决策边界图
#安装mlxtend
#pip --default-timeout=123 install mlxtend#大家在运行时把前面的“#”去掉,可能时间较长,需耐心等待
from mlxtend.plotting import plot_decision_regions#导入plot_decision_regions


X2 = X.iloc[:,0:2]#仅选取V2存款规模、V3EVA作为特征变量
model = LinearDiscriminantAnalysis()#使用LDA算法
model.fit(X2, y)#使用fit方法进行拟合
model.score(X2, y)
model.explained_variance_ratio_

plot_decision_regions(np.array(X2), np.array(y), model)
plt.xlabel('存款规模')#将x轴设置为'存款规模'
plt.ylabel('EVA')#将y轴设置为'EVA'
plt.title('LDA决策边界')#将标题设置为'LDA决策边界'


#7.5  使用分割样本开展线性判别分析
X_train, X_test, y_train, y_test =  train_test_split(X,y,test_size=0.3, stratify=y, random_state=123)
model = LinearDiscriminantAnalysis()#使用LDA算法
model.fit(X_train, y_train)#基于训练样本使用fit方法进行拟合
model.score(X_test, y_test)#基于测试样本计算模型预测的准确率

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

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

confusion_matrix(y_test, pred)#输出测试样本的混淆矩阵

print(classification_report(y_test, pred))

cohen_kappa_score(y_test, pred)

#7.6  使用分割样本开展二次判别分析
#7.6.1  模型估计
model = QuadraticDiscriminantAnalysis()#使用QDA算法
model.fit(X_train, y_train)#基于训练样本使用fit方法进行拟合
model.score(X_test, y_test)#计算模型预测的准确率

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

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

confusion_matrix(y_test, pred)

print(classification_report(y_test, pred))

cohen_kappa_score(y_test, pred)#计算cohen_kappa得分

#7.6.2  运用两个特征变量绘制QDA决策边界图
X2 = X.iloc[:, 0:2]
model = QuadraticDiscriminantAnalysis()
model.fit(X2, y)
model.score(X2, y)

plot_decision_regions(np.array(X2), np.array(y), model)
plt.xlabel('存款规模')#将x轴设置为'存款规模'
plt.ylabel('EVA')#将y轴设置为'EVA'
plt.title('QDA决策边界')#将标题设置为'QDA决策边界'
#绘图

数据准备

以“数据7.1”文件中的数据为例进行讲解。​“数据7.1”文件记录的是某商业银行在山东地区的部分支行的经营数据(虚拟数据,不涉及商业秘密)​,案例背景是该商业银行正在推动支行开展转型,实现所有支行的做大做强。

数据文件中的变量包括这些商业银行全部支行的V1(转型情况)​、V2(存款规模)​、V3(EVA)​、V4(中间业务收入)​、V5(员工人数)​。V1(转型情况)又分为3个类别:​“0”表示“未转型网点”​,​“1”表示“一般网点”​,​“2”表示“精品网点”​。​“数据7.1”文件中的数据内容如图所示。

下面以V1(转型情况)为响应变量,以V2(存款规模)​、V3(EVA)​、V4(中间业务收入)​、V5(员工人数)为特征变量,构建线性判别分析(Linear Discriminant Analysis, LDA)模型。

1 导入分析所需要的模块和函数

在进行分析之前,首先导入分析所需要的模块和函数,读取数据集并进行观察。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
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
from mpl_toolkits.mplot3d import Axes3D
from sklearn.datasets import make_classification
from sklearn.decomposition import PCA

2 线性判别分析降维优势展示

前面提到线性判别分析不仅可以用来进行任务分类,还可以进行降维处理。由于线性判别分析降维的依据是贝叶斯规则,充分利用了既有分类信息,因此在降维时可以很好地保存样本特征和类别的信息关联。

下面我们先通过生成的数据进行演示,对比线性判别分析降维和PCA降维。

1.绘制三维数据的分布图

首先生成一组三维数据,并通过绘制图形的方式观察其特征。

#绘制三维数据的分布图
X, y = make_classification(n_samples=500, n_features=3, n_redundant=0,
                           n_classes=3, n_informative=2, n_clusters_per_class=1,
                           class_sep=0.5, random_state=100)#生成三类三维特征的数据
plt.rcParams['axes.unicode_minus']=False# 解决负号不显示问题
fig = plt.figure()
ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=20, azim=20)
ax.scatter(X[:, 0], X[:, 1], X[:, 2], marker='o', c=y)

2.使用PCA进行降维

#使用PCA进行降维
pca = PCA(n_components=2)
pca.fit(X)
print(pca.explained_variance_ratio_)
print(pca.explained_variance_)
  1. 使用主成分分析(Principal Component Analysis,PCA)进行数据降维。

  2. pca = PCA(n_components=2)

    • 创建一个 PCA 对象,PCA 是 scikit-learn 库中用于主成分分析的类。
    • n_components=2 参数指定将数据降维到 2 个主成分。这意味着经过 PCA 处理后,原始数据将被转换为只有两个特征的新数据集。
  3. pca.fit(X)

    • 使用输入数据 X 来拟合 PCA 模型。X 通常是一个二维数组,其中每一行代表一个样本,每一列代表一个特征。
    • 在这个步骤中,PCA 算法会计算数据的协方差矩阵,并确定能够最大程度地保留数据方差的主成分方向。
  4. print(pca.explained_variance_ratio_)

    • 打印出每个主成分解释的方差比例
    • explained_variance_ratio_ 是一个属性,它是一个数组,其中每个元素表示相应主成分解释的方差占总方差的比例。例如,如果有两个主成分,这个数组可能是 [0.7, 0.2],表示第一个主成分解释了 70% 的方差,第二个主成分解释了 20% 的方差。
  5. print(pca.explained_variance_)

    • 打印出每个主成分解释的方差值
    • explained_variance_ 是一个属性,它是一个数组,其中每个元素表示相应主成分解释的方差大小。方差越大,说明该主成分在数据中的重要性越高。

 结果:

可以发现第一主成分能够解释的方差比例为50.10%,第二主成分能够解释的方差比例为35.12%,提取的两个主成分能够涵盖初始变量中的大部分信息。

使用PCA降维后的散点图:

从图中可以发现两点:

一是PCA分析将原始的三维特征数据成功降维成了二维数据,在图形上的直观表现就是将立体化的数据展现到了一个平面上,横轴和纵轴分别是第一主成分和第二主成分,各个散点反映的是样本;

二是PCA分析降维方法并未保留样本特征和类别的信息关联,体现在各种类型的样本散点混合在一起。

3.使用LDA进行降维

#使用LDA进行降维
lda = LinearDiscriminantAnalysis()
lda.fit(X, y)
X_new = lda.transform(X)
plt.scatter(X_new[:, 0], X_new[:, 1], marker='o', c=y)
plt.show()#降维后样本特征信息之间的关系得以保留

 

  1. 使用线性判别分析(Linear Discriminant Analysis,LDA)进行数据降维。

  2. lda = LinearDiscriminantAnalysis()

    • 创建一个 LinearDiscriminantAnalysis 对象,这是 scikit-learn 库中用于线性判别分析的类。
  3. lda.fit(X, y)

    • 使用输入数据 X 和对应的类别标签 y 来拟合 LDA 模型。
    • X 通常是一个二维数组,其中每一行代表一个样本,每一列代表一个特征。y 是一个一维数组,包含每个样本的类别标签。
    • 在这个步骤中,LDA 算法会计算类内散度矩阵和类间散度矩阵,并确定能够最大程度地分离不同类别数据的投影方向。
  4. X_new = lda.transform(X)

    • 使用已经拟合好的 LDA 模型对输入数据 X 进行降维变换,得到降维后的新数据 X_new
    • X_new 的维度通常会小于原始数据 X 的维度,具体取决于 LDA 模型的设置。
  5. plt.scatter(X_new[:, 0], X_new[:, 1], marker='o', c=y)

    • 使用 matplotlib 的 scatter 函数绘制降维后的数据点。
    • X_new[:, 0] 和 X_new[:, 1] 分别表示降维后数据的第一维和第二维特征。
    • marker='o' 设置数据点的标记样式为圆形。
    • c=y 根据类别标签 y 为数据点设置不同的颜色。
  6. plt.show()

    • 显示绘制的图形,展示降维后样本特征信息之间的关系。

3 数据读取及观察

data=pd.read_csv(r'数据7.1.csv')
data.info()
len(data.columns)
data.columns
data.shape
data.dtypes
data.isnull().values.any()
data.isnull().sum()
data.head()
data.V1.value_counts()

即数据集中共有48个样本(48 entries, 0 to 47)​、5个变量(total 5columns)​。5个变量分别是V1~V5,均包含48个非缺失值(48non-null)​,其中V1、V5的数据类型为整型(int64)​,V2、V3、V4的数据类型为浮点型(float64)​。数据文件中共有3个浮点型(float64)变量、2个整型(int64)变量,数据内存为2.0KB。

即“0”表示“未转型网点”​,样本个数为25个;​“1”表示“一般网点”​,样本个数为18个;​“2”表示“精品网点”​,样本个数为5个。

V1(转型情况)为响应变量,以V2(存款规模)​、V3(EVA)​、V4(中间业务收入)​、V5(员工人数)为特征变量,构建线性判别分析(Linear Discriminant Analysis, LDA)模型。

3 特征变量相关性分析

X = data.drop(['V1'],axis=1)#设置特征变量,即除V1之外的全部变量
y = data['V1']#设置响应变量,即V1
X.corr()
sns.heatmap(X.corr(), cmap='Blues', annot=True)
  1. X = data.drop(['V1'], axis=1)

    • 这里从名为 data 的数据集(可能是一个 pandas 的 DataFrame)中删除名为 'V1' 的列,并将剩余的列赋值给变量 X,作为特征变量集合。使用 drop 方法时,axis=1 表示按列进行删除操作。
  2. y = data['V1']

    • 从 data 中提取名为 'V1' 的列,并将其赋值给变量 y,作为响应变量。
  3. X.corr()

    • 计算特征变量集合 X 中各列之间的相关性。这会返回一个相关性矩阵,其中每个元素表示相应两列之间的相关系数。
  4. sns.heatmap(X.corr(), cmap='Blues', annot=True)

    • 使用 seaborn 库的 heatmap 函数绘制特征变量相关性的热力图。
    • X.corr() 作为参数传入,表示要绘制的相关性矩阵数据。
    • cmap='Blues' 设置热力图的颜色映射为蓝色系。
    • annot=True 表示在热力图的每个单元格中显示相关系数的具体数值。

4 使用样本全集开展线性判别分析

# 使用样本示例全集开展LDA
model = LinearDiscriminantAnalysis()#使用LDA算法
model.fit(X, y)#使用fit方法进行拟合
model.score(X, y)
model.priors_
model.means_
np.set_printoptions(suppress=True)#不以科学计数法显示,而是直接显示数字
model.coef_#输出模型系数
model.intercept_#输出模型截距项
model.explained_variance_ratio_#输出可解释方差比例
model.scalings_
  1. 使用全部样本数据进行线性判别分析(LDA)。

  2. model = LinearDiscriminantAnalysis()

    • 创建一个 LinearDiscriminantAnalysis 对象,即初始化一个 LDA 模型。
  3. model.fit(X, y)

    • 使用特征变量 X 和响应变量 y 对 LDA 模型进行拟合。在这个过程中,模型会计算类内散度矩阵和类间散度矩阵,并确定能够最大程度地分离不同类别数据的投影方向。
  4. model.score(X, y)

    • 计算模型在给定数据 X 和 y 上的得分。
  5. model.priors_

    • 返回每个类别的先验概率。先验概率是在没有看到任何数据之前对不同类别出现的概率的估计。
  6. model.means_

    • 返回每个类别的特征均值向量。这可以帮助我们了解不同类别的数据在特征空间中的中心位置。
  7. np.set_printoptions(suppress=True)

    • 设置 numpy 的打印选项,使得输出不以科学计数法显示,而是直接显示数字。这可以使输出更加易读。
  8. model.coef_

    • 返回模型的系数。在 LDA 中,系数表示投影方向,可以用于将原始数据投影到低维空间。
  9. model.intercept_

    • 返回模型的截距项。在某些情况下,模型可能需要一个截距项来进行预测。
  10. model.explained_variance_ratio_

  • 返回每个线性判别(主成分)解释的方差比例。类似于主成分分析(PCA)中的解释方差比例,这个值可以帮助我们了解每个线性判别对数据方差的解释程度。

11.model.scalings_

  • 返回特征的缩放因子。这些缩放因子可以用于将原始数据标准化,以便更好地进行模型拟合和预测。

计算模型预测准确率,运行结果为:0.8333333333333334,说明模型预测的准确率在 83.33%。

先验概率是指基于既有样本分类计算的分布概率,​“未转型网点”的先验概率为52.08%,​“一般网点”的先验概率为37.5%,​“精品网点”的先验概率为10.42%。

未转型网点中,V2(存款规模)​、V3(EVA)​、V4(中间业务收入)​、V5(员工人数)的均值分别为1802.276,562.3628,115.990712,40.84;

一般网点中,V2(存款规模)​、V3(EVA)​、V4(中间业务收入)​、​(V5员工人数)的均值分别为2608.84166667,895.94333333,284.68953333,37.27777778;

精品网点中,V2(存款规模)​、V3(EVA)​、V4(中间业务收入)​、V5(员工人数)的均值分别为5163.62,1222.01,673.16048,38.2。

基于模型系数和常数项,我们可以写出线性分类函数方程,有多少个分类就有多少个线性分类函数。

● 未转型网点:

V1=-0.00091301×V2-0.00510986×V3-0.00132272×V4+0.00811066×V5+4.56877967

● 一般网点:

V1=0.00044724×V2+0.00318443×V3+0.00005389×V4-0.01101929×V5-4.33624197

● 精品网点:

V1=0.00295497×V2+0.01408534×V3+0.0064196×V4-0.00088386×V5-30.33779818

第一线性判元的可解释组间方差比例为0.98316198,第二线性判元可解释方差组间比例为0.01683802,或者说,第一线性判元对于样本类别的区分度很高。

输出线性判别系数(注意“线性判别系数”不同于前面所提的“分类函数系数”),

线性判别系数即线性判元对于特征变量的载荷,也是原理讲解部分提到的权重系数w,其中第一线性判元在V2(存款规模)​、V3(EVA)​、V4(中间业务收入)​、V5(员工人数)上的载荷分别为-0.00070198、-0.00362065、-0.00128565、0.00304935,即运行结果的第一列;第二线性判元在V2(存款规模)​、V3(EVA)​、V4(中间业务收入)​、V5(员工人数)上的载荷分别为-0.0001132、0.00263812、-0.00301653、-0.03282909,即运行结果的第二列。

5 运用两个特征变量绘制LDA决策边界图

首先需要安装mlxtend,代码如下:

pip --default-timeout=123 install mlxtend

如果安装不成功可尝试以下代码:

conda install mlxtend --channel conda-forge

from mlxtend.plotting import plot_decision_regions#导入plot_decision_regions

X2 = X.iloc[:,0:2]#仅选取V2存款规模、V3EVA作为特征变量
model = LinearDiscriminantAnalysis()#使用LDA算法
model.fit(X2, y)#使用fit方法进行拟合
model.score(X2, y)
model.explained_variance_ratio_

plot_decision_regions(np.array(X2), np.array(y), model)
plt.xlabel('存款规模')#将x轴设置为'存款规模'
plt.ylabel('EVA')#将y轴设置为'EVA'
plt.title('LDA决策边界')#将标题设置为'LDA决策边界'

第一线性判元的可解释组间方差比例为0.98904178,第二线性判元可解释方差组间比例为0.01095822,或者说第一线性判元对于样本类别的区分度很高。 

从图中可以发现,使用LDA方法的决策边界是直线,两条直线将所有参与分析的样本分为三个类别,最右侧区域为精品网点区域,特点是存款规模足够高,或者EVA足够高且存款不能太低;中间区域是一般网点区域,特点是存款规模或EVA有一方面表现相对较好,可以是EVA很高但存款规模很低,也可以是存款规模比较高(但还没有达到精品网点的标准)但EVA相对较低,也可以是存款规模和EVA都处于中等水平;左下方区域是未转型网点区域,特点是EVA与存款规模同时较低。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值