前言
python期末考试要求的是做一个特征提取的项目,今天我就来展示一下我的成果
一、代码
import numpy as np
# 从sklearn的线性分析库中导入线性判别分析即LDA 最大化类间区分度的坐标轴 做分类预处理的降维
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import pandas as pd
outputfile = 'LDA6.xlsx' # 降维后的数据
def lda(data, target, n_dim):
'''
:param data: (n_samples, n_features)
:param target: data class
:param n_dim: target dimension
:return: (n_samples, n_dims)
'''
clusters = np.unique(target)
if n_dim > len(clusters)-1:
print("K is too much")
print("please input again")
exit(0)
#within_class scatter matrix
# 计算类内距离Sw
Sw = np.zeros((data.shape[1],data.shape[1]))
# 循环每一种类型
for i in clusters:
datai = data[target == i]
datai = datai-datai.mean(0)
Swi = np.mat(datai).T*np.mat(datai)
Sw += Swi
#between_class scatter matrix
# 计算类间距离SB
SB = np.zeros((data.shape[1],data.shape[1]))
u = data.mean(0) #所有样本的平均值
for i in clusters:
Ni = data[target == i].shape[0]
ui = data[target == i].mean(0) #某个类别的平均值
SBi = Ni*np.mat(ui - u).T*np.mat(ui - u)
SB += SBi
S = np.linalg.inv(Sw)*SB
eigVals,eigVects = np.linalg.eig(S) #求特征值,特征向量
eigValInd = np.argsort(eigVals)
eigValInd = eigValInd[:(-n_dim-1):-1]
w = eigVects[:,eigValInd]
data_ndim = np.dot(data, w)
return data_ndim
if __name__ == '__main__':
data1 = pd.read_excel('yy.xlsx', names=range(0, 129))
X = data1.drop([0], axis=1)
data = data1.values
Y = data[:, 0]
# 以字典形式加载数据集
# iris = load_iris()
# X代表数据,Y代表标签
# X = iris.data
# Y = iris.target
data_1 = lda(X, Y, 5)
data_2 = LinearDiscriminantAnalysis(n_components=5).fit_transform(X, Y)
data_3 = lda(X, Y, 5)
data_4 = lda(X, Y, 5)
data_5 = lda(X, Y, 5)
data_6 = lda(X, Y, 7)
data_7 = lda(X, Y, 7)
data_8 = lda(X, Y, 7)
data_9 = lda(X, Y, 7)
data_10 = lda(X, Y, 9)
data_11 = lda(X, Y, 9)
data_12 = lda(X, Y, 9)
data_13 = lda(X, Y, 9)
data_14 = lda(X, Y, 9)
data_15 = lda(X, Y, 9)
data_16 = lda(X, Y, 9)
plt.figure(figsize=(20, 15))
plt.subplot(441)
plt.title("LDA")
plt.xlim([data_1[:, 0].min()*1.2, data_1[:, 0].max()*1.2])
plt.ylim([data_1[:, 1].min()*1.3, data_1[:, 1].max()*1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_1[:, 0], data_1[:, 1], c=Y)
plt.subplot(442)
plt.title("sklearn_LDA")
plt.scatter(data_2[:, 0], data_2[:, 1], c=Y)
plt.subplot(443)
plt.title("LDA2")
plt.xlim([data_3[:, 1].min() * 1.2, data_3[:, 1].max() * 1.2])
plt.ylim([data_3[:, 2].min() * 1.3, data_3[:, 2].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_3[:, 1], data_3[:, 2], c=Y)
plt.subplot(444)
plt.title("LDA3")
plt.xlim([data_4[:, 2].min() * 1.2, data_4[:, 2].max() * 1.2])
plt.ylim([data_4[:, 3].min() * 1.3, data_4[:, 3].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_4[:, 2], data_4[:, 3], c=Y)
plt.subplot(445)
plt.title("LDA4")
plt.xlim([data_5[:, 3].min() * 1.2, data_5[:, 3].max() * 1.2])
plt.ylim([data_5[:, 4].min() * 1.3, data_5[:, 4].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_5[:, 3], data_5[:, 4], c=Y)
plt.subplot(446)
plt.title("LDA5")
plt.xlim([data_6[:, 5].min() * 1.2, data_6[:, 5].max() * 1.2])
plt.ylim([data_6[:, 6].min() * 1.3, data_6[:, 6].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_6[:, 5], data_6[:, 6], c=Y)
plt.subplot(447)
plt.title("LDA6")
plt.xlim([data_7[:, 1].min() * 1.2, data_7[:, 1].max() * 1.2])
plt.ylim([data_7[:, 4].min() * 1.3, data_7[:, 4].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_7[:, 1], data_7[:, 4], c=Y)
plt.subplot(448)
plt.title("LDA7")
plt.xlim([data_8[:, 3].min() * 1.2, data_8[:, 3].max() * 1.2])
plt.ylim([data_8[:, 6].min() * 1.3, data_8[:, 6].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_8[:, 3], data_8[:, 6], c=Y)
plt.subplot(449)
plt.title("LDA8")
plt.xlim([data_9[:, 2].min() * 1.2, data_9[:, 2].max() * 1.2])
plt.ylim([data_9[:, 5].min() * 1.3, data_9[:, 5].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_9[:, 2], data_9[:, 5], c=Y)
plt.subplot(4, 4, 10)
plt.title("LDA9")
plt.xlim([data_10[:, 3].min() * 1.2, data_10[:, 3].max() * 1.2])
plt.ylim([data_10[:, 8].min() * 1.3, data_10[:, 8].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_10[:, 3], data_10[:, 8], c=Y)
plt.subplot(4, 4, 11)
plt.title("LDA10")
plt.xlim([data_11[:, 7].min() * 1.2, data_11[:, 7].max() * 1.2])
plt.ylim([data_11[:, 8].min() * 1.3, data_11[:, 8].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_11[:, 7], data_11[:, 8], c=Y)
plt.subplot(4, 4, 12)
plt.title("LDA11")
plt.xlim([data_12[:, 2].min() * 1.2, data_10[:, 2].max() * 1.2])
plt.ylim([data_12[:, 7].min() * 1.3, data_10[:, 7].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_12[:, 2], data_10[:, 7], c=Y)
plt.subplot(4, 4, 13)
plt.title("LDA12")
plt.xlim([data_13[:, 1].min() * 1.2, data_13[:, 1].max() * 1.2])
plt.ylim([data_13[:, 8].min() * 1.3, data_13[:, 8].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_13[:, 1], data_13[:, 8], c=Y)
plt.subplot(4, 4, 14)
plt.title("LDA13")
plt.xlim([data_14[:, 5].min() * 1.2, data_14[:, 5].max() * 1.2])
plt.ylim([data_14[:, 8].min() * 1.3, data_14[:, 8].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_14[:, 5], data_14[:, 8], c=Y)
plt.subplot(4, 4, 15)
plt.title("LDA14")
plt.xlim([data_15[:, 0].min() * 1.2, data_15[:, 0].max() * 1.2])
plt.ylim([data_15[:, 6].min() * 1.3, data_15[:, 6].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_15[:, 0], data_15[:, 6], c=Y)
plt.subplot(4, 4, 16)
plt.title("LDA15")
plt.xlim([data_16[:, 0].min() * 1.2, data_16[:, 0].max() * 1.2])
plt.ylim([data_16[:, 8].min() * 1.3, data_16[:, 8].max() * 1.3])
plt.xticks([])
plt.yticks([])
plt.scatter(data_16[:, 0], data_16[:, 8], c=Y)
plt.savefig("LDA4.png",dpi=800)
plt.show()
writer=pd.ExcelWriter(outputfile)
pd.DataFrame(data_1).to_excel(writer, sheet_name='LDA',)
pd.DataFrame(data_2).to_excel(writer, sheet_name='sklearn_LDA')
pd.DataFrame(data_3).to_excel(writer, sheet_name='LDA2',)
pd.DataFrame(data_4).to_excel(writer, sheet_name='LDA3',)
pd.DataFrame(data_5).to_excel(writer, sheet_name='LDA4',)
pd.DataFrame(data_6).to_excel(writer, sheet_name='LDA5',)
pd.DataFrame(data_7).to_excel(writer, sheet_name='LDA6',)
pd.DataFrame(data_8).to_excel(writer, sheet_name='LDA7',)
pd.DataFrame(data_9).to_excel(writer, sheet_name='LDA8',)
pd.DataFrame(data_10).to_excel(writer, sheet_name='LDA9',)
pd.DataFrame(data_11).to_excel(writer, sheet_name='LDA10',)
pd.DataFrame(data_12).to_excel(writer, sheet_name='LDA11',)
pd.DataFrame(data_13).to_excel(writer, sheet_name='LDA12',)
pd.DataFrame(data_14).to_excel(writer, sheet_name='LDA13',)
pd.DataFrame(data_15).to_excel(writer, sheet_name='LDA14',)
pd.DataFrame(data_16).to_excel(writer, sheet_name='LDA15',)
# pd.DataFrame(feature_vector).to_excel(writer,sheet_name='特征向量')
# pd.DataFrame(scale).to_excel(writer,sheet_name='标准化数据')
writer.save()
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.ensemble import RandomForestClassifier # 随机森林
# def pca(X, k): # k是咱们想要的组件 (k is the components you want)
# # 每个特征的平均值 (mean of each feature)
# #样本数量。特征数量
# n_samples, n_features = X.shape
# mean = np.array([np.mean(X[:, i]) for i in range(n_features)])
# # 将数据标准化 (normalization)
# norm_X = X - mean
# # 散布矩阵(scatter matrix)
# scatter_matrix = np.dot(np.transpose(norm_X), norm_X)
# # 计算特征向量和特征值 (Calculate the eigenvectors and eigenvalues)
# eig_val, eig_vec = np.linalg.eig(scatter_matrix)
# eig_pairs = [(np.abs(eig_val[i]), eig_vec[:, i]) for i in range(n_features)]
# # 根据eig_val从最高到最低对eig_vec进行排序 (sort eig_vec based on eig_val from highest to lowest)
# eig_pairs.sort(reverse=True)
# # select the top k eig_vec
# feature = np.array([ele[1] for ele in eig_pairs[:k]])
# # get new data
# data = np.dot(norm_X, np.transpose(feature))
# return data
# inputfile = 'wy.csv'#原始数据
# outputfile = r'../DATA/28PCA6.xlsx' # 降维后的数据
outputfile = 'PCA6.xlsx'
data1 = pd.read_excel('yy.xlsx', names=range(0, 129))
print(data1.shape)
# X = data1.drop([0], axis=1)
# 以字典形式加载数据集
# iris = load_iris()
# X代表数据,Y代表标签
# X = iris.data
# Y = iris.target
# data_2 = LinearDiscriminantAnalysis(n_components=5).fit_transform(X, Y)
# data1 = pd.read_excel(r'../DATA/yy.xlsx', engine='open yyxlsx', names=range(129)) # 读入数据
# 特征列
data = data1.drop([0], axis=1)
# 标准化数据
scale = (data - data.mean()) / (data.std())
# 查看数据是否正常
X = data.values
Y = data1.values[:, 0]
from sklearn.decomposition import PCA
# 保留所有成分
pca = PCA(n_components=5)
pca.fit(scale)
data_1 = pca.transform(scale)
# 降维前
plt.figure(figsize=(4, 4))
# plt.subplot(121)
plt.title("PCA")
plt.scatter(data_1[:, 0], data_1[:, 1], c=Y)
plt.savefig("pca.png",dpi=300)
# plt.show()
# 返回模型的各个特征向量
feature_vector = pca.components_
# 返回各个成分各自的方差百分比(也称贡献率)
contri_rate = pca.explained_variance_ratio_
print(contri_rate.sum())
# 查看贡献率
# print(contri_rate.shape)
# 选取累计贡献率大于80%的主成分(3个主成分)
# pca = PCA(6)
# pca.fit(scale)
# # 降低维度
# low_d = pca.transform(scale)
# newx = pca.inverse_transform(low_d)
# print(newx)
# print(newx.shape)
# 将结果写入excel
writer=pd.ExcelWriter(outputfile)
pd.DataFrame(data_1).to_excel(writer,sheet_name='主成分')
pd.DataFrame(contri_rate).to_excel(writer,sheet_name='贡献率')
pd.DataFrame(feature_vector).to_excel(writer,sheet_name='特征向量')
pd.DataFrame(scale).to_excel(writer,sheet_name='标准化数据')
writer.save()
# 降维后
# plt.subplot(122)
# plt.title("A_PCA")
# plt.scatter(data_2[:, 0], data_2[:, 1], c=Y)
# plt.savefig("LDA4.png", dpi=600)
二、运行结果
1.图片
2.数据集
暂时没有放上来,运行代码即会生成
三.设计报告
1.目的和意义
目的:对数据集进行特征提取,将原始变量的初始集合降维至更易于管理的组别(特征)进行处理,同时仍准确、完整地描述原始数据集,以便于后续的使用。
意义:对数据进行处理,首先能够减少数据存储和输入数据带宽,减少冗余。其次,数据处理后,低纬上分类性会提高,能够发现更有意义的潜在变量,帮助对数据产生跟深入的了解。最后,在众多特征中求出那些对分类识别最有效的特征,从而实现特征空间维数的压缩,即可获取一组少而精且分类错误概率小的分类特征。
2. 程序详细设计
首先,先用主成分分析法即PCA算法来对数据集进行降维处理,即对数据
生成特征向量矩阵、计算每一特征的平均值、令每一维度都减去该列的特征平均值来计算特征的散布矩阵,然后针对散布矩阵进行特征值和特征向量的计算、对计算得到的特征值进行从大到小的排序,最后取出前K个特征向量和特征值,并进行回退,就得到了降维后的特征矩阵。同时通过计算得到数据集的主成分、贡献率、特征向量和标准化数据。
另一方面,用线性判别分析法即LDA算法对数据集进行处理,降维后主要从不同类型进行组合分类,并用matplotlib进行可视化处理,画出多种组合对比图和数据分析结果。
下列流程图中,左边的为利用PCA算法处理数据集的主要流程图,右边的为利用LDA算法处理数据集的主要流程图。
3.程序运行结果
基于LDA进行降维的运行结果:
基于LDA进行降维的运行结果之部分数据集:
基于PCA进行降维的运行结果:
基于PCA进行降维的运行结果之部分数据集:
4.报告总结
此次对数据集的特征提取主要通过了LDA和PCA两种方法对其进行了降维处理,分别得到了降维之后不同类型分类组合的特征排列结果,制成了散点图、数据集等,多方面展示了基于LDA和PCA算法处理数据集得到的一系列成果:降维后分类组合特征的排列结果对比图,分析而来的主成分、贡献率、特征向量和标准化数据集等。
在本次项目过程中,锻炼了自己的实操能力和学习总结能力,学习了机器学习的特征提取、PCA和LDA算法降维分类,另外学习了matplotlib可视化作图的知识。一方面巩固了python的学习,一方面学习了新知识,在降维算法,可视化作图排列等方面也有了自己的一些感悟。
总之,这次的项目还是有挺多不足的,不过相比当初什么也不会,没怎么上手练过的我已经有了很大的进步,这次的项目也让我对特征提取的降维算法、可视化作图等有了很大的兴趣,学海无涯,学无止境,接下来的我还会从本次项目中不断吸取经验和教训,继续学习钻研下去,且对本次项目进行更好的完善和补充。