文章目录
前言
入门机器学习,记录学习日常,如有错误请多指正。
参考书目:机器学习及Python应用
数据集可在陈强教授主页下载
一、数据处理
1.数据介绍
案例采用iris数据。该数据集包含了4个特征变量:
Sepal.Length(花萼长度),单位是cm;
Sepal.Width(花萼宽度),单位是cm;
Petal.Length(花瓣长度),单位是cm;
Petal.Width(花瓣宽度),单位是cm;
响应变量:
Iris Setosa(山鸢尾)、
Iris Versicolour(杂色鸢尾),
以及Iris Virginica(维吉尼亚鸢尾)
可通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。
2.导入模块和数据文件
1)导入案例所需的全部模块
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
2)sklearn模块自带iris数据,使用load_iris()函数载入:
iris=load_iris()
3.数据概况
1)考察iris数据信息
print(type(iris))
print(dir(iris))#dir()函数用于查看组成部分
print(iris.feature_names)#考察其特征变量名称
返回结果如下:
<class 'sklearn.utils._bunch.Bunch'>#iris为sklearn的Bunch对象
['DESCR', 'data', 'data_module', 'feature_names', 'filename', 'frame', 'target', 'target_names']
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
由于特征变量名称繁琐(带有空格和括号),将特征变量名称进行如下更新:
iris.feature_names=['sepal_length','sepal_width','petal_length','petal_width']#更新变量名
2)计算相关系数
为考察特征变量之间的相关系数,将数据矩阵转化为数据框:
X=pd.DataFrame(iris.data,columns=iris.feature_names)#数据矩阵转化为数据框
使用corr()方法计算相关系数矩阵
print(X.corr())
sepal_length sepal_width petal_length petal_width
sepal_length 1.000000 -0.117570 0.871754 0.817941
sepal_width -0.117570 1.000000 -0.428440 -0.366126
petal_length 0.871754 -0.428440 1.000000 0.962865
petal_width 0.817941 -0.366126 0.962865 1.000000
将相关系数矩阵可视化
sns.heatmap(X.corr(),cmap='Blues',annot=True)#相关系数热力图
plt.tight_layout()
plt.show()
二、线性判别分析
1.使用全样本(不区分训练集和测试集)进行线性判别分析
1)使用sklearn模块LinearDiscriminantAnalysis类进行线性判别分析
y=iris.target#将响应变量iris.target记为y
model=LinearDiscriminantAnalysis()
model.fit(X,y)
2)考察相应指标
print('预测准确率:',model.score(X,y))#预测准确率
print('先验概率:',model.priors_)#先验概率
print('特征变量的分组平均值:\n',model.means_)#特征变量的分组平均值
print('线性判元对组间方差的贡献:',model.explained_variance_ratio_)#线性判元对组间方差的贡献
print('线性判元系数估计值:\n',model.scalings_)#线性判元系数估计值
预测准确率: 0.98
先验概率: [0.33333333 0.33333333 0.33333333]
特征变量的分组平均值:
[[5.006 3.428 1.462 0.246]
[5.936 2.77 4.26 1.326]
[6.588 2.974 5.552 2.026]]
线性判元对组间方差的贡献: [0.9912126 0.0087874]
'''
99.12%的组间方差可由第一个线性判元所解释
'''
线性判元系数估计值:
[[ 0.82937764 -0.02410215]
[ 1.53447307 -2.16452123]
[-2.20121166 0.93192121]
[-2.81046031 -2.83918785]]
为更好展现线性判别系数,将其变为数据框
lda_loadings=pd.DataFrame(model.scalings_,index=iris.feature_names,columns=['LD1','LD2'])#数组变为数据框
print(lda_loadings)
LD1 LD2
sepal_length 0.829378 -0.024102
sepal_width 1.534473 -2.164521
petal_length -2.201212 0.931921
petal_width -2.810460 -2.839188
计算线性判别得分
lda_scores=model.fit_transform(X,y)#线性判别得分
print(lda_scores.shape)
print(lda_scores[:5,:])
(150, 2)#线性判别得分形状
[[ 8.06179978 -0.30042062]
[ 7.12868772 0.78666043]
[ 7.48982797 0.26538449]
[ 6.81320057 0.67063107]
[ 8.13230933 -0.51446253]]#前5行观测值
3)线性判元散点图
先对数据进行一系列处理
LDA_scores=pd.DataFrame(lda_scores,columns=['LD1','LD2'])#将lda_scores变为数据框
LDA_scores['Species']=iris.target#在此数据框中加入响应变量Species:
d={0:'setosa',1:'versicolor',2:'virginica'}#定义字典
LDA_scores['Species']=LDA_scores['Species'].map(d)
#将响应变量Species取值由{1,2,3}变为相应的{setosa,versicolor,virginica}
print(LDA_scores.head())
LD1 LD2 Species
0 8.061800 -0.300421 setosa
1 7.128688 0.786660 setosa
2 7.489828 0.265384 setosa
3 6.813201 0.670631 setosa
4 8.132309 -0.514463 setosa
使用seaborn模块的scatterplot()函数,画出线性判元的散点图
sns.scatterplot(x='LD1',y='LD2',data=LDA_scores,hue='Species',style='Species')
#第一与第二判元散点图
#hue='Species'表示根据变量Species不同取值上色,
#style='Species'表示用不同图标区分散点图
plt.show()
在降维后的线性判元空间(LD1,LD2)空间中,鸢尾花setosa与另外两种可以很好地区分开。这种区分能力几乎完全来自于LD1,因为从LD2维度几乎无法区分三种鸢尾花的区别。
4)为更为直观展示线性判别分析(画出决策边界),选取两个特征变量(petal_length和petal_width)进行线性判别分析
X2=X.iloc[:,2:4]#选取两个特征变量petal_length和petal.width展示线性判别分析
model=LinearDiscriminantAnalysis()
model.fit(X2,y)
print('预测准确率:',model.score(X2,y))#准确率
print('两个线性判元对组间方差贡献:',model.explained_variance_ratio_)
预测准确率: 0.96
两个线性判元对组间方差贡献: [0.99470499 0.00529501]
使用mlxtend模块画出决策边界
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')
plt.show()
2.使用训练集和测试集进行线性判别分析
1)进行分层抽样,线性判别分析
X_train,X_test,y_train,y_test=train_test_split(X, y, test_size=0.3,stratify=y,random_state=123)
model=LinearDiscriminantAnalysis()
model.fit(X_train,y_train)
2)考察相应指标
print('预测准确率:',model.score(X_test,y_test))
y_prob=model.predict_proba((X_test))
print('预测测试集每个样例的分类概率:',y_prob[:5])
y_pred=model.predict(X_test)
print('预测测试集每个样例的品种:',y_pred[:5])
预测准确率: 0.9777777777777777
预测测试集每个样例的分类概率:
[[1.37493315e-32 5.86839618e-01 4.13160382e-01]
[4.87880054e-42 4.08368248e-04 9.99591632e-01]
[1.49908347e-19 9.99998532e-01 1.46841688e-06]
[2.45317549e-24 9.97417042e-01 2.58295753e-03]
[1.76506456e-50 1.80298359e-07 9.99999820e-01]]
预测测试集每个样例的品种:
[1 2 1 1 2]
计算混淆矩阵和基于混淆矩阵的一系列预测效果指标
print(pd.crosstab(y_test,y_pred,rownames=['Actual'],colnames=['Predicted']))
print(classification_report(y_test,y_pred))
Predicted 0 1 2
Actual
0 15 0 0
1 0 14 1
2 0 0 15
----------------------------------------------------------------
precision recall f1-score support
0 1.00 1.00 1.00 15
1 1.00 0.93 0.97 15
2 0.94 1.00 0.97 15
accuracy 0.98 45
macro avg 0.98 0.98 0.98 45
weighted avg 0.98 0.98 0.98 45
计算科恩的kappa值
print(cohen_kappa_score(y_test,y_pred))
0.9666666666666667
三、二次判别分析
1)使用sklearn的QuadraticDiscriminantAnalysis类进行二次判别分析
model=QuadraticDiscriminantAnalysis()
model.fit(X_train,y_train)
2)考察相应指标
print('预测准确率:',model.score(X_test,y_test))
y_prob=model.predict_proba(X_test)
print('预测测试集每个样例的分类概率\n:',y_prob[:5])
y_pred=model.predict(X_test)
print('预测测试集每个样例的品种:',y_pred[:5])
预测准确率: 0.9777777777777777
预测测试集每个样例的分类概率
: [[1.30728298e-117 4.25364516e-001 5.74635484e-001]
[4.80474602e-185 1.17558005e-003 9.98824420e-001]
[1.12275433e-056 9.99994095e-001 5.90465247e-006]
[1.46316743e-102 9.99459623e-001 5.40377069e-004]
[9.87276194e-236 3.84799384e-005 9.99961520e-001]]
预测测试集每个样例的品种: [2 2 1 1 2]
计算测试集混淆矩阵、预测效果指标、Kappa值
print(confusion_matrix(y_test,y_pred))
print(classification_report(y_test,y_pred))
print(cohen_kappa_score(y_test,y_pred))
[[15 0 0]
[ 0 14 1]
[ 0 0 15]]
-------------------------------------------------------
precision recall f1-score support
0 1.00 1.00 1.00 15
1 1.00 0.93 0.97 15
2 0.94 1.00 0.97 15
accuracy 0.98 45
macro avg 0.98 0.98 0.98 45
weighted avg 0.98 0.98 0.98 45
0.9666666666666667#Kappa值
3)使用全样本,两个特征变量(petal_length和petal_width)画出二次判别分析决策边界
先进行QDA分析
X2=X.iloc[:,2:4]
model=QuadraticDiscriminantAnalysis()
model.fit(X2,y)
print(model.score(X2,y))
0.98#预测准确率
使用mlxtend模块画出QDA决策边界
plot_decision_regions(np.array(X2),y,model)
plt.xlabel('petal_length')
plt.ylabel('petal_width')
plt.title('Decision Boundary for QDA')
plt.show()