Python数据挖掘项目:基于三种肝癌样本数据的PCA分析以及神经网络分类模型的构建

本文主要是介绍Python数据挖掘项目:基于三种肝癌样本数据的PCA分析以及神经网络分类模型的构建,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者CSDN:进击的西西弗斯
本文链接:https://blog.csdn.net/qq_42216093/article/details/116994199
版权声明:本文为作者原创文章,未经作者同意禁止转载或盗用



1.项目说明及流程概要:



项目说明


本文项目是我本科毕设项目其中的数据挖掘部分,包括对三种类型的肝癌基因表达数据的PCA分析以及构建神经网络分类模型。


以下是在本文的数据挖掘工作开始之前所做的准备工作:

在TCGA数据库中检索并下载41位肝细胞癌患者的基因表达数据以及相应的癌旁组织的基因表达数据共82个样本数据,数据结构是82行 × \times × 6万列(6万列对应6万种基因表达产物的表达水平),样本包含三种不同类型(3个巴塞罗那病理学分期,1期、2期、3期),使用Python对数据进行预处理,借助R相关软件包分析不同组样本间的差异表达基因,提取其中部分基因进行 GO富集分析(细胞成分和生物学过程的分析),根据结果总结其中的生物学意义, 筛选出20个关键基因,最终,以41个肝癌样本数据为行,20个关键基因为列,原始数据的结构被降维到41 × \times × 20。



样本数据集


使用上述已经处理好的41例肝癌患者的基因表达数据,如下图,每行是一个样本数据(除去首行共41行),前20列是20个关键基因以及它们的基因表达数据,最后一列是每个样本的类别标签(共3种类别)

链接:样本数据集下载



项目流程(全流程通过Python代码实现)


1). 对数据进行标准化预处理,包括均值标准化和方差标准化。

2). 对标准化后的数据进行PCA分析,将数据降维并将结果可视化。

3). 对数据集绘制Andrews曲线,观察各类别之间的差异性

4). 对数据集划分训练集(80%)和测试集(20%),使用训练集构建神经网络分类模型并做5折交叉验证。

5). 调整模型参数:最大迭代次数,并绘制模型得分图像。

6). 调整模型参数:隐藏层层数,并绘制模型得分图像。

7). 最终使用调整好的最优参数构建神经网络模型,并用测试集评估模型效果,同时绘制学习曲线,观察模型训练过程的运行情况。



关于PCA算法和神经网络的算法原理,可以参阅我另一篇博文:


链接:机器学习算法归详细纳整理




2.对数据集进行主成分分析(PCA)和可视化



流程概要


先对数据进行标准化预处理,包括均值标准化和方差标准化(特征缩放);再对标准化后的数据进行PCA分析,将数据降维到10维,提取其中最大主成分的前2个维度,并可视化绘图;最后再对整个数据集绘制Andrews曲线(Andrews曲线是一种用来对多维数据降维可视化的工具),从整个维度上观察各类别之间的差异性。


主要用到的Python库:numpypandasmatplotlibsklearnsklearn.decompositionsklearn.preprocessing



完整代码(附注释)


#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 14 17:47:47 2020: 2021/5/7 下午10:30
@Author  : liudong
@Software: PyCharm
"""import numpy as np
import pandas as pd
from sklearn.decomposition import PCA
from sklearn.preprocessing import scale
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['Heiti TC']    # 指定默认字体:解决plot不能显示中文问题
plt.rcParams['axes.unicode_minus'] = False           # 解决保存图像是负号'-'显示为方块的问题def Normalization(data):        # 先对数据进行标准化处理data = scale(data, axis=0, with_mean=True, with_std=True)   # with_mean:均值标准化;with_std:方差标准化;axis=0:标准化每个特征(列),如果取1则标准化每个观测样本(行)mean = round(data.mean(), 1)std = round(data.std(), 1)print("已完成均值标准化:均值 =",mean)print("已完成特征缩放:方差 =", std)return datadef my_PCA(data, k):       # 把数据data降到k维pca = PCA(n_components = k)   # 创建PCA对象,声明主成分个数,也就是要降到的维度res = pca.fit_transform(data)   # 用data来训练PCA模型,同时返回降维后的数据print("原始数据结构: ", data.shape)print("降维后数据结构: ", res.shape)var_ratio = pca.explained_variance_ratio_   # pca的这个属性用来获取各个主成分对原始数据的差异性(方差)保留比率。num = 1for var in var_ratio:print("第{}个主成分保留的差异性:{:.2f}%".format(num,var * 100))num += 1print("总保留的差异性:{:.2f}%".format(np.sum(var_ratio * 100)))return resdef Visualization(res):        # 将PCA结果可视化df = pd.DataFrame(res)df1 = df.iloc[:19]df2 = df.iloc[18:30]df3 = df.iloc[30:]fig = plt.figure(figsize=(12,9),dpi= 200)ax = fig.add_axes([0.1,0.1,0.8,0.8])x1 = list(df1.iloc[:,0])y1 = list(df1.iloc[:,1])x2 = list(df2.iloc[:,0])y2 = list(df2.iloc[:,1])x3 = list(df3.iloc[:,0])y3 = list(df3.iloc[:,1])ax.scatter(x1, y1, alpha = 0.5, color = 'r')ax.scatter(x2, y2, alpha = 0.5, color = 'b')ax.scatter(x3, y3, alpha = 0.5, color = 'g')ax.set_xlim(-2, 2)ax.set_ylim(-4, 4)ax.set_title('三种肝癌类型的基因表达数据PCA',fontsize=30)ax.set_xlabel('第一个主成分',fontsize=20)ax.set_ylabel('第二个主成分',fontsize=20)ax.xaxis.set_tick_params(labelsize=15)ax.yaxis.set_tick_params(labelsize=15)ax.legend(labels=['stage1','stage2','stage3'],fontsize=20)plt.savefig('三种肝癌类型的基因表达数据PCA.jpg')plt.show()if __name__ == '__main__':data = pd.read_csv('data.csv', index_col=False)data.drop(columns=['Stage_Class'])data = Normalization(data)res = my_PCA(data, 10)Visualization(res)# 绘制Andrews曲线df = pd.read_csv('data.csv')plt.figure(figsize=(12,9),dpi= 200)pd.plotting.andrews_curves(df, 'Stage_Class', color=['r','b','g'], linewidth=2)plt.grid(alpha=0.3)plt.title('三种肝癌类型的基因表达数据Andrews曲线', fontsize=30)plt.savefig('三种肝癌类型的基因表达数据Andrews曲线.jpg')plt.show()


结果及分析


1). PCA运行输出结果

可以看出,均值和方差的标准化过程正常,处理后每个样本数据的均值为0,方差为1;经过PCA后,数据结构被成功降维到(41,10);此时这10个维度(也就是10个主成分)总共保留了原数据89.24%的差异性。


2). PCA可视化结果

图像显示,三种类型的肝癌数据样本之间的分开效果比较差,分析其原因,这主要是因为第一个主成分和第二个主成分所保留的样本差异性不够大,总共只有41%左右,所以二维可视化之后不足以显示出样本数据之间的类别差异性。


3). Andrews曲线图像

三种肝癌类型的基因表达数据Andrews曲线

Andrews曲线是一种用来对多维数据降维可视化的工具,能够在整个维度上观察不同类别数据样本的差异性,这里直接对全体数据集作Andrews曲线,图像显示,三种类别的肝癌样本数据之间有明显的差异性,因此接下来可以放心地去构建神经网络分类模型。




3.构建神经网络分类模型



流程概要


对数据集划分训练集(80%)和测试集(20%),使用训练集进行5折交叉验证来构建神经网络分类模型;为了寻找到最优的模型参数,首先调整最大迭代次数,绘制出模型得分曲线,然后调整隐藏层层数,绘制出模型得分曲线;最终使用调整好的最优参数构建神经网络模型,并用测试集评估模型效果,同时绘制学习曲线,观察整个模型训练过程的运行情况。


主要用到的Python库:numpypandasmatplotlibsklearnsklearn.model_selectionsklearn.neural_network



完整代码(附注释)


#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 14 17:47:47 2020: 2021/5/6 下午4:19
@Author  : liudong
@Software: PyCharm
"""import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocator
from sklearn.model_selection import train_test_split, cross_val_score, learning_curve
from sklearn.neural_network import MLPClassifier
plt.rcParams['font.sans-serif'] = ['Heiti TC']    # 指定默认字体:解决plot不能显示中文问题
plt.rcParams['axes.unicode_minus'] = False           # 解决保存图像是负号'-'显示为方块的问题def Data_split():       # 预处理:样本数据集划分,训练集80%,测试集20%data = pd.read_csv('./data.csv')    # 读取数据集x_train, x_test, y_train, y_test = train_test_split(data.iloc[:, 0:(data.shape[1]-1)],  # 数据集中的自变量集(第一列到倒数第二列)data['Stage_Class'],   # 数据集中的因变量集(表示类别标签的最后一列)stratify = data['Stage_Class'],   # 按照该列的比例来分层抽样划分训练集和测试集random_state = 8,     # 指定随机状态train_size = 0.8)     # 训练集比例return x_train, x_test, y_train, y_testdef NN_para_iter(x_train,y_train):        # 构建神经网络模型,并调整参数:最大迭代次数,绘制得分图像x = list()y1 = list()y2 = list()for i in np.arange(100, 2000, 100):# 构建神经网络模型mlp = MLPClassifier(solver='sgd',  # 反向传播中的优化算法,这里选用随机梯度下降算法activation='tanh',  # 激活函数,这里选用tanh双曲函数alpha=0.001,  # 正则化惩罚系数hidden_layer_sizes=(50, 50),  # 神经网络隐藏层结构:每层神经元数和层数random_state=1,  # 指定随机状态max_iter=i,  # 最大迭代次数verbose=0)  # 是否将进度消息打印输出,取值一般同参数max_iter,0表示不打印输出结果mlp.fit(x_train, y_train)       # 用模型拟合数据集scores = cross_val_score(mlp, x_train, y_train, cv=5)   # 用数据训练模型,5次交叉验证,得到包含5个得分的列表score = scores.mean()       # 求出五次交叉验证得分的平均值x.append(i)y2.append(score)y1.append(mlp.score(x_train, y_train))# 将结果可视化:fig = plt.figure(dpi=200, figsize=(12, 9))ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])ax.plot(x, y1, color='r',marker='o')ax.plot(x, y2, color='b',marker='s')ax.legend(labels=['训练集得分', '交叉验证得分'], loc='upper right',fontsize=20)ax.set_title('神经网络模型得分关于迭代次数的变化曲线',fontsize=30)ax.set_xlabel('迭代次数', fontsize=20)ax.set_ylabel('模型得分', fontsize=20)ax.xaxis.set_tick_params(labelsize=15)ax.yaxis.set_tick_params(labelsize=15)plt.savefig('神经网络模型得分关于迭代次数的变化曲线.jpg')plt.show()def NN_para_layer(x_train,y_train):        # 构建神经网络模型,并调整参数:隐藏层层数,绘制得分图像x = list()y1 = list()y2 = list()for i in np.arange(1, 60):# 构建神经网络模型mlp = MLPClassifier(solver='sgd',  # 反向传播中的优化算法,这里选用随机梯度下降算法activation='tanh',  # 激活函数,这里选用tanh双曲函数alpha=0.001,  # 正则化惩罚系数hidden_layer_sizes=(50, i),  # 神经网络隐藏层结构:每层神经元数和层数random_state=1,  # 指定随机状态max_iter=2000,  # 最大迭代次数verbose=0)  # 是否将进度消息打印输出,取值一般同参数max_iter,0表示不打印输出结果mlp.fit(x_train, y_train)       # 用模型拟合数据集scores = cross_val_score(mlp, x_train, y_train, cv=5)   # 用数据训练模型,5次交叉验证,得到包含5个得分的列表score = scores.mean()       # 求出五次交叉验证得分的平均值x.append(i)y2.append(score)y1.append(mlp.score(x_train, y_train))# 将结果可视化:fig = plt.figure(dpi=200, figsize=(12, 9))ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])ax.plot(x, y1, color='r',marker='o')ax.plot(x, y2, color='b',marker='s')ax.legend(labels=['训练集得分', '交叉验证得分'], loc='center right',fontsize=20)ax.set_title('神经网络模型得分关于隐藏层层数的变化曲线',fontsize=30)ax.set_xlabel('隐藏层层数', fontsize=20)ax.set_ylabel('模型得分', fontsize=20)ax.xaxis.set_tick_params(labelsize=15)ax.yaxis.set_tick_params(labelsize=15)ax.xaxis.set_major_locator(MultipleLocator(1))      # 设置x轴的刻度间隔为1plt.savefig('神经网络模型得分关于隐藏层层数的变化曲线.jpg')plt.show()def draw_learning_curve(x_train, y_train):      # 绘制学习曲线,观察模型训练过程是否正常# 调用学习曲线函数,返回三个值:训练样本数递增的一维数组、交叉验证中训练集得分的二维表(包括每次cv)、交叉验证中验证集得分的二维表(包括每次cv)train_sizes, train_scores, validation_scores = learning_curve(MLPClassifier(solver='sgd', activation='tanh', alpha=0.001, hidden_layer_sizes=(50, 7), random_state=1, max_iter=2000, verbose=0),  # 用到的机器学习模型x_train,    # 样本的自变量集y_train,    # 样本的因变量集cv=5,   # 交叉验证折叠数train_sizes=np.linspace(0.1,1,10)   # 训练样本数量的递增比例情况,默认为np.linspace(0.1,1,5))train_scores_mean = np.mean(train_scores, axis=1)   # 求每次训练样本数量对应的训练集得分关于多次cv的均值train_scores_std = np.std(train_scores, axis=1)     # 求每次训练样本数量对应的验证集得分关于多次cv的方差validation_scores_mean = np.mean(validation_scores, axis=1)     # 求每次训练样本数量对应的验证集得分关于多次cv的均值validation_scores_std = np.std(validation_scores, axis=1)       # 求每次训练样本数量对应的验证集得分关于多次cv的方差# 将结果可视化:fig = plt.figure(figsize=(12, 9), dpi=200)ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])ax.plot(train_sizes, train_scores_mean, color='r',marker='o')ax.plot(train_sizes, validation_scores_mean, color='b',marker='s')ax.fill_between(train_sizes, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std, alpha=0.1, color="r")ax.fill_between(train_sizes, validation_scores_mean - validation_scores_std, validation_scores_mean + validation_scores_std, alpha=0.1, color="b")ax.legend(labels=['训练集得分', '交叉验证得分'], loc='best',fontsize=20)ax.set_title('神经网络模型的学习曲线',fontsize=30)ax.grid(True)ax.xaxis.set_tick_params(labelsize=15)ax.yaxis.set_tick_params(labelsize=15)ax.set_xlabel('训练样本数量', fontsize=20)ax.set_ylabel('模型得分', fontsize=20)plt.savefig('神经网络模型的学习曲线.jpg')plt.show()def final_model_evaluate(x_train, x_test, y_train, y_test):     # 对最终的神经网络模型评估效果mlp = MLPClassifier(solver='sgd',  # 反向传播中的优化算法,这里选用随机梯度下降算法activation='tanh',  # 激活函数,这里选用tanh双曲函数alpha=0.001,  # 正则化惩罚系数hidden_layer_sizes=(50, 7),  # 神经网络隐藏层结构:每层神经元数和层数random_state=1,  # 指定随机状态max_iter=2000,  # 最大迭代次数verbose=0)  # 是否将进度消息打印输出,取值一般同参数max_iter,0表示不打印输出结果mlp.fit(x_train, y_train)  # 用模型拟合数据集train_score = mlp.score(x_train, y_train)       # 训练集得分scores = cross_val_score(mlp, x_train, y_train, cv=5)  # 用数据训练模型,5次交叉验证,得到包含5个得分的列表validation_score = np.mean(scores)     # 五次交叉验证得分的平均值validation_max_score = np.amax(scores)     # 五次交叉验证得分的最大值test_score = mlp.score(x_test, y_test)print('神经网络模型对于训练集的得分是:{}'.format(round(train_score,2)))print('神经网络模型5次交叉验证的最高得分是:{}'.format((round(validation_max_score,2))))print('神经网络模型5次交叉验证的平均得分是:{}'.format(round(validation_score,2)))print('神经网络模型对于测试集的得分是:{}'.format(round(test_score,2)))if __name__ == '__main__':x_train, x_test, y_train, y_test = Data_split()NN_para_iter(x_train, y_train)NN_para_layer(x_train, y_train)draw_learning_curve(x_train, y_train)final_model_evaluate(x_train, x_test, y_train, y_test)


结果及分析


1). 神经网络模型得分关于迭代次数的变化曲线

神经网络模型得分关于迭代次数的变化曲线

图像显示,模型的迭代次数大约1000次左右时训练集的拟合得分和交叉验证的得分开始达到最优,并趋于收敛,因此,神经网络模型中的迭代次数参数应该至少取1000以上的数值,而在sklearn中该参数的默认取值是200,远远达不到我们模型的需求,故进行调整。


2). 神经网络模型得分关于隐藏层层数的变化曲线

神经网络模型得分关于隐藏层层数的变化曲线

从图像可以看出,神经网络的隐藏层层数大于2时,训练集的拟合效果达到最优,并持续处于最优拟合状态,但是验证集的得分并不稳定,这是因为神经网络的结构会影响它对数据的预测效果,应当选择适合该数据集的神经网络结构。因此,对于该神经网络模型,参数隐藏层层数应该取7,此时它的预测能力达到最优。


3). 神经网络模型的学习曲线(Learning curve)

神经网络模型的学习曲线

学习曲线是一种用来检测算法模型运行情况的有效工具。观察该模型的学习曲线:

(1). 当训练样本数量很少时,训练集得分很高(为满分1),因为此时模型很容易达到完全拟合状态,但是验证集得分很低,因为学习样本太少导致模型预测能力很差。

(2). 随着样本数的增加,训练集得分逐渐下降,因为此时模型不可能对每个样本都完全拟合,样本数很多时,模型对于整个数据集的拟合能力就会下降,但是验证集的得分在上升,因为此时学习数据增多,模型的预测能力逐渐增强。

(3). 最终,理论上训练集和验证集的得分曲线会最趋于水平,且保持一个较近的间隔,这在该模型的图像中并不明显,分析其原因,主要是因为样本数据集的数量限制,如果能有更多的样本数据,就能够进一步提升模型的训练效果。


4). 最终神经网络模型的预测效果

截屏2021-05-16 下午5.02.51

这是最终的模型得分(也就是预测准确率)情况,训练集的拟合度达到84.38%,验证集最高得分是85.71%,验证集平均得分是71.43%,测试集得分是71.43%,总体来讲模型的预测准确率较高,分类效果较为良好。但是还不够优秀,今后如果有机会可以再进一步进行优化。

这篇关于Python数据挖掘项目:基于三种肝癌样本数据的PCA分析以及神经网络分类模型的构建的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/527106

相关文章

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python正则表达式匹配和替换的操作指南

《Python正则表达式匹配和替换的操作指南》正则表达式是处理文本的强大工具,Python通过re模块提供了完整的正则表达式功能,本文将通过代码示例详细介绍Python中的正则匹配和替换操作,需要的朋... 目录基础语法导入re模块基本元字符常用匹配方法1. re.match() - 从字符串开头匹配2.

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

通过Docker容器部署Python环境的全流程

《通过Docker容器部署Python环境的全流程》在现代化开发流程中,Docker因其轻量化、环境隔离和跨平台一致性的特性,已成为部署Python应用的标准工具,本文将详细演示如何通过Docker容... 目录引言一、docker与python的协同优势二、核心步骤详解三、进阶配置技巧四、生产环境最佳实践

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函