🤵♂️ 个人主页:@艾派森的个人主页
✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+
喜欢大数据分析项目的小伙伴,希望可以多多支持该系列的其他文章
大数据分析案例-基于随机森林算法预测人类预期寿命 |
大数据分析案例-基于随机森林算法的商品评价情感分析 |
大数据分析案例-用RFM模型对客户价值分析(聚类) |
大数据分析案例-对电信客户流失分析预警预测 |
大数据分析案例-基于随机森林模型对北京房价进行预测 |
大数据分析案例-基于RFM模型对电商客户价值分析 |
大数据分析案例-基于逻辑回归算法构建垃圾邮件分类器模型 |
大数据分析案例-基于决策树算法构建员工离职预测模型 |
大数据分析案例-基于KNN算法对茅台股票进行预测 |
大数据分析案例-基于多元线性回归算法构建广告投放收益模型 |
大数据分析案例-基于随机森林算法构建返乡人群预测模型 |
大数据分析案例-基于决策树算法构建金融反欺诈分类模型 |
1.项目背景
乳腺癌是女性最常见的恶性肿瘤之一,在全球范围内都具有高发病率和死亡率。根据世界卫生组织(WHO)的统计数据,每年全球约有200万新发乳腺癌病例,并且每年大约有60万患者因乳腺癌而死亡。乳腺癌的早期检测和诊断对于提高治愈率和生存率至关重要,因为在早期阶段进行有效治疗可以显著改善患者的预后。
随着医学影像技术的进步,乳腺癌的早期检测变得更加准确和可靠。然而,随着数据量的增加,传统的乳腺癌诊断方法面临着一些挑战,例如特征提取复杂,容易受到主观因素影响,且存在一定的误诊率。因此,利用机器学习和人工智能技术对乳腺癌进行分类预测成为了一个备受关注的研究领域。
LightGBM(Light Gradient Boosting Machine)是一种基于梯度提升决策树的机器学习算法,它以其高效性和准确性在分类、回归和排名任务中广泛应用。相比于传统的梯度提升决策树算法,LightGBM具有更快的训练速度和更低的内存占用,因此在大规模数据集上表现优异。
因此,本研究旨在利用LightGBM算法构建乳腺癌分类预测模型,通过对医学影像和患者临床数据进行综合分析,实现对乳腺癌患者的准确分类和预测。通过该预测模型,可以帮助医生快速、准确地诊断乳腺癌,并及早制定个性化治疗方案,从而提高患者的治愈率和生存率。此外,该研究还有望为乳腺癌的早期筛查和诊断提供一种可行的辅助手段,为公共卫生领域提供有益的帮助。
2.项目简介
2.1项目说明
本项目旨在利用LightGBM算法构建乳腺癌分类预测模型,结合医学影像数据和患者临床数据,对乳腺癌患者进行准确的分类和预测。通过该预测模型,实现以下目标:
- 提高乳腺癌早期检测的准确性:利用机器学习算法对医学影像数据进行分析,帮助医生及早发现乳腺癌病变,提高早期诊断的准确性。
- 改善乳腺癌患者治疗策略:通过对患者临床数据的综合分析,预测乳腺癌患者的病情和预后,为医生制定个性化治疗方案提供依据。
- 辅助医生决策:将构建的预测模型作为辅助工具,为医生在乳腺癌诊断和治疗过程中提供科学客观的参考意见。
通过本项目的实施,我们期望构建出一个基于LightGBM算法的乳腺癌分类预测模型,并将其应用于医学影像和临床数据的分析中。这个预测模型可以帮助医生在乳腺癌早期发现和治疗方案制定上做出更加准确和科学的决策,从而提高乳腺癌患者的治愈率和生存率。此外,项目的研究结果和模型也可能会被用于学术研究和学术交流,并为乳腺癌分类预测领域的进一步研究提供有益的参考。
2.2数据说明
本数据集来源于kaggle,Breast Cancer Dataset | Kaggle 原始数据集共有569条,32个特征变量。
2.3技术工具
Python版本:3.9
代码编辑器:jupyter notebook
3.算法原理
LightGBM算法基本原理
GBDT算法的基本思想是把上一轮的训练残差作为下一轮学习器训练的输入,即每一次的输入数据都依赖于上一次训练的输出结果。因此,这种训练迭代过程就需要多次对整个数据集进行遍历,当数据集样本较多或者维数过高时会增加算法运算的时间成本,并且消耗更高的内存资源。
而XGBoost算法作为GBDT的一种改进,在训练时是基于一种预排序的思想来寻找特征中的最佳分割点,这种训练方式同样也会导致内存空间消耗极大,例如算法不仅需要保存数据的特征值,还需要保存特征排序的结果;在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大,特别是当数据量级较大时,这种方式会消耗过多时间。
为了对这些问题进行优化,2017年微软公司提出了LightGBM算法(Light Gradient Boosting Machine),该算法也是基于GBDT算法的改进,,但相较于GBDT、XGBoost算法,LightGBM算法有效地解决了处理海量数据的问题,在实际应用中取得出色的效果。LightGBM算法主要包括以下几个特点:直方图算法(寻找最佳分裂点、直方图差加速)、Leaf-wise树生长策略、GOSS、EFB、支持类别型特征、高效并行以及Cache命中率优化等。
(1)直方图Histogram算法(减少大量计算与内存占用)
XGBoost算法在进行分裂时需要预先对每一个特征的原始数据进行预排序,而直方图Histogram算法则是对特征的原始数据进行“分桶#bin”,把数据划分到不同的离散区域中,再对离散数据进行遍历,寻找最优划分点。这里针对特征值划分的每一个“桶”有两层含义,一个是每个“桶”中样本的数量;另一个是每个“桶”中样本的梯度和(一阶梯度和的平方的均值等价于均方损失)。
可以看出,通过直方图算法可以让模型的复杂度变得更低,并且特征“分桶”后仅保存了的离散值,大大降低内存的占用率。其次,这种“分桶”的方式从某种角度来看相当于对模型增加了正则化,可以避免模型出现过拟合。
值得注意的是,直方图算法是使用了bin代替原始数据,相当于增加了正则化,这也意味着有更多的细节特征会被丢弃,相似的数据可能被划分到相同的桶中,所以bin的数量选择决定了正则化的程度,bin越少惩罚越严重,过拟合的风险就越低。
另外,在LightGBM直方图算法中还包括一种直方图作差优化,即LightGBM在得到一个叶子的直方图后,能够通过直方图作差的方式用极小的代价得到其兄弟叶子的直方图,如上图所示,当得到某个叶子的直方图和父节点直方图后,另一个兄弟叶子直方图也能够很快得到,利用这种方式,LightGBM算法速度得到进一步提升。
(2)带深度限制的Leaf-wise的叶子生长策略(减少大量计算、避免过拟合)
GBDT与XGBoost模型在叶子生长策略上均采用按层level-wise分裂的方式,这种方式在分裂时会针对同一层的每一个节点,即每次迭代都要遍历整个数据集中的全部数据,这种方式虽然可以使每一层的叶子节点并行完成,并控制模型的复杂度,但也会产生许多不必要搜索或分裂,从而消耗更多的运行内存,增加计算成本。
而LightGBM算法对其进行了改进,使用了按叶子节点leaf-wise分裂的生长方式,即每次是对所有叶子中分裂增益最大的叶子节点进行分裂,其他叶子节点则不会分裂。这种分裂方式比按层分裂会带来更小的误差,并且加快算法的学习速度,但由于没有对其他叶子进行分裂,会使得分裂结果不够细化,并且在每层中只对一个叶子不断进行分裂将增大树的深度,造成模型过拟合[25]。因此,LightGBM算法在按叶子节点生长过程中会限制树的深度来避免过拟合。
(3)单边梯度采样技术 (减少样本角度)
在梯度提升算法中,每个样本都有不同梯度值,样本的梯度可以反映对模型的贡献程度,通常样本的梯度越大贡献给模型的信息增益越多,而样本的梯度越小,在模型中表现的会越好。
举个例子来说,这里的大梯度样本可以理解为“练习本中的综合性难题”,小梯度样本可以理解为“练习本中的简单题”,对于“简单题”平时做的再多再好,而“难题”却做的很少,在真正的“考试”时还是会表现不好。但并不意味着小梯度样本(“简单题”)就可以直接剔除不用参与训练,因为若直接剔除小梯度样本,数据的分布会发生改变,从而影响模型的预测效果。
因此,LightGBM算法引入了单边梯度采样技术(Gradient-based One-Side Sampling,GOSS),其基本思想就是从减少样本的角度出发,利用样本的梯度大小信息作为样本重要性的考量,保留所有梯度大的样本点(“保留所有难题”),对于梯度小的样本点(“简单题”)按比例进行随机采样,这样既学习了小梯度样本的信息,也学习了大梯度样本的信息(“平时难题都做,简单题做一部分,在面临真正的考试时才可能稳定发挥,甚至超水平发挥”),在不改变原始数据分布的同时,减小了样本数量,提升了模型的训练速度。
(4)互斥特征捆绑(减少特征角度)
高维度的数据通常是非常稀疏的,并且特征之间存在互斥性(例如通过one-hot编码后生成的几个特征不会同时为0),这种数据对模型的效果和运行速度都有一定的影响。
通过互斥特征捆绑算法(Exclusive Feature Bundling,EFB)可以解决高维度数据稀疏性问题,如下图中,设特征1、特征2以及特征3互为互斥的稀疏特征,通过EFB算法,将三个特征捆绑为一个稠密的新特征,然后用这一个新特征替代原来的三个特征,从而实现不损失信息的情况下减少特征维度,避免不必要0值的计算,提升梯度增强算法的速度。
总的来说,LightGBM是一个性能高度优化的GBDT 算法,也可以看成是针对XGBoost的优化算法,可以将LightGBM的优化用公式表达,如下式:LightGBM = XGBoost + Histogram + GOSS + EFB
4.项目实施步骤
4.1理解数据
导入本次实验用到的第三方库并加载数据
查看数据大小
查看数据基本信息
查看数值型变量的描述性统计
4.2数据预处理
删除缺失值和重复值,发现数据大小没有发生变化,说明原始数据集不存在缺失值和重复值
4.3探索性数据分析
4.4特征工程
对非数值变量进行编码处理
准备建模用到的数据并拆分数据集为训练集和测试集
4.5模型构建
对比这四个模型,我们发现LightGBM算法模型的准确率最高,故我们最终选择其作为最终的模型。
4.6模型评估
特征重要性评分
4.7模型预测
5.实验总结
在本次实验中,我们成功地基于LightGBM算法构建了乳腺癌分类预测模型。通过对医学影像数据和患者临床数据的综合分析,该模型能够对乳腺癌患者进行准确的分类和预测,为医生提供科学客观的诊断参考意见。
实验步骤包括数据收集、数据预处理、特征工程、数据集划分、模型构建、、模型评估、结果解释和可视化。在数据预处理阶段,我们对收集到的数据进行了清洗、去噪和归一化处理,确保了数据的质量和可用性。在特征工程阶段,我们从医学影像和临床数据中提取了有意义的特征,为模型构建提供了输入。
在模型构建阶段,我们采用了LightGBM算法,该算法以其高效和准确的特性在分类和回归任务中表现出色。在模型评估阶段,我们使用测试集对模型进行了评估,统计了分类准确率、召回率、F1值等指标,验证了模型的性能。
实验结果表明,我们构建的乳腺癌分类预测模型在准确性和可靠性上都取得了良好的表现。该模型可以帮助医生在乳腺癌的早期检测和治疗方案制定上做出更准确的决策,从而提高了乳腺癌患者的治愈率和生存率。同时,该模型也具有较高的可解释性,能够对预测结果进行解释和可视化分析。
最终,我们将构建好的乳腺癌分类预测模型部署到了实际医疗环境中,供医生使用。这将有效提高乳腺癌的早期诊断准确性和效率,为乳腺癌的治疗和管理提供有益的帮助。我们相信该实验结果和模型还可以为乳腺癌分类预测领域的进一步研究提供参考,并在其他医学领域的机器学习应用中产生积极的影响。
虽然本次实验取得了较为满意的结果,但也存在一些局限性。例如,数据量较小或者不均衡可能会影响模型的表现。因此,未来可以继续扩大数据集规模并采用更多的数据增强技术来改进模型的性能。此外,还可以尝试结合其他机器学习算法或深度学习方法,进一步提高乳腺癌分类预测模型的准确性和稳健性。总体来说,该实验为乳腺癌诊断与治疗领域的机器学习应用提供了有益的探索和实践。
心得与体会:
通过这次Python项目实战,我学到了许多新的知识,这是一个让我把书本上的理论知识运用于实践中的好机会。原先,学的时候感叹学的资料太难懂,此刻想来,有些其实并不难,关键在于理解。
在这次实战中还锻炼了我其他方面的潜力,提高了我的综合素质。首先,它锻炼了我做项目的潜力,提高了独立思考问题、自我动手操作的潜力,在工作的过程中,复习了以前学习过的知识,并掌握了一些应用知识的技巧等
在此次实战中,我还学会了下面几点工作学习心态:
1)继续学习,不断提升理论涵养。在信息时代,学习是不断地汲取新信息,获得事业进步的动力。作为一名青年学子更就应把学习作为持续工作用心性的重要途径。走上工作岗位后,我会用心响应单位号召,结合工作实际,不断学习理论、业务知识和社会知识,用先进的理论武装头脑,用精良的业务知识提升潜力,以广博的社会知识拓展视野。
2)努力实践,自觉进行主角转化。只有将理论付诸于实践才能实现理论自身的价值,也只有将理论付诸于实践才能使理论得以检验。同样,一个人的价值也是透过实践活动来实现的,也只有透过实践才能锻炼人的品质,彰显人的意志。
3)提高工作用心性和主动性。实习,是开端也是结束。展此刻自我面前的是一片任自我驰骋的沃土,也分明感受到了沉甸甸的职责。在今后的工作和生活中,我将继续学习,深入实践,不断提升自我,努力创造业绩,继续创造更多的价值。
这次Python实战不仅仅使我学到了知识,丰富了经验。也帮忙我缩小了实践和理论的差距。在未来的工作中我会把学到的理论知识和实践经验不断的应用到实际工作中,为实现理想而努力。
源代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(font='SimHei')
import warnings
warnings.filterwarnings('ignore')
df = pd.read_csv('breast-cancer.csv')
df.head()
df.shape
df.info()
df.describe().T
df.dropna(inplace=True)
df.drop_duplicates(inplace=True)
df.shape
df['diagnosis'].value_counts().plot(kind='bar', color=['blue', 'red'])
print(df['diagnosis'].value_counts())
plt.show()
sns.scatterplot(x='id',y='radius_mean',data=df,hue='diagnosis')
plt.show()
sns.scatterplot(x='id',y='texture_mean',data=df,hue='diagnosis')
plt.show()
sns.distplot(df.perimeter_mean,kde=True,color='g')
plt.show()
sns.distplot(df.area_mean,kde=False,color='b')
plt.show()
sns.regplot(x='id',y='smoothness_mean',data=df)
plt.show()
sns.lmplot(x='id',y='radius_worst',data=df,hue='diagnosis')
plt.show()
sns.distplot(df['perimeter_worst'],kde=True,color='m')
plt.show()
df['diagnosis'].replace(to_replace={'B':0,'M':1},inplace=True)
df['diagnosis'].value_counts()
from sklearn.model_selection import train_test_split
# 准备建模的数据
X = df.drop('diagnosis',axis=1)
y = df['diagnosis']
# 划分数据集
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42)
print('训练集大小:',X_train.shape[0])
print('测试集大小:',X_test.shape[0])
# 构建逻辑回归模型
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(X_train,y_train)
print('逻辑回归模型准确率:',lr.score(X_test,y_test))
# 构建KNN模型
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(X_train,y_train)
print('KNN模型准确率:',knn.score(X_test,y_test))
# 构建决策树模型
from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier()
tree.fit(X_train,y_train)
print('决策树模型准确率:',tree.score(X_test,y_test))
# 构建lightgbm模型
from lightgbm import LGBMClassifier
gbm = LGBMClassifier()
gbm.fit(X_train,y_train)
print('lightgbm模型准确率:',gbm.score(X_test,y_test))
from sklearn.metrics import f1_score,r2_score,confusion_matrix,classification_report,auc,roc_curve
# 模型评估
y_pred = gbm.predict(X_test)
print('gbm模型的F1值:',f1_score(y_test,y_pred))
print('gbm模型的R方值:',r2_score(y_test,y_pred))
print('模型混淆矩阵:','\n',confusion_matrix(y_test,y_pred))
print('模型分类报告:','\n',classification_report(y_test,y_pred))
# 画出ROC曲线
y_prob = gbm.predict_proba(X_test)[:,1]
false_positive_rate, true_positive_rate, thresholds = roc_curve(y_test, y_prob)
roc = auc(false_positive_rate, true_positive_rate)
plt.title('ROC')
plt.plot(false_positive_rate,true_positive_rate, color='red',label = 'AUC = %0.2f' % roc)
plt.legend(loc = 'lower right')
plt.plot([0, 1], [0, 1],linestyle='--')
plt.axis('tight')
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.show()
# 特征重要性评分
feat_labels = X_train.columns[0:]
importances = gbm.feature_importances_
indices = np.argsort(importances)[::-1]
index_list = []
value_list = []
for f,j in zip(range(X_train.shape[1]),indices):
index_list.append(feat_labels[j])
value_list.append(importances[j])
plt.figure(figsize=(10,6))
plt.barh(index_list[::-1],value_list[::-1])
plt.yticks(fontsize=12)
plt.title('各特征重要程度排序',fontsize=14)
plt.show()
# 模型预测
res = pd.DataFrame()
res['真实值'] = y_test
res['预测值'] = y_pred
res.sample(10)