您现在的位置是:首页 >学无止境 >大数据分析案例-基于Adaboost算法构建糖尿病预测模型网站首页学无止境
大数据分析案例-基于Adaboost算法构建糖尿病预测模型
?♂️ 个人主页:@艾派森的个人主页
✍?作者简介:Python学习者
? 希望大家多多支持,我们一起进步!?
如果文章对你有帮助的话,
欢迎评论 ?点赞?? 收藏 ?加关注+
喜欢大数据分析项目的小伙伴,希望可以多多支持该系列的其他文章
目录
4.3.5分析不同性别和糖化血红蛋白水平在血糖蛋白水平上的差异
1.项目背景
糖尿病是一种常见的慢性代谢性疾病,全球范围内影响着大量人口的健康。根据国际糖尿病联合会(IDF)的数据,全球成年人患有糖尿病的人数预计超过5.1亿,这个数字预计在未来几年还会继续增加。糖尿病患者常常需要长期监测和管理血糖水平,以减少并发症的风险。
随着机器学习和数据挖掘技术的发展,利用这些技术来构建糖尿病预测模型已经成为可能。这些模型可以基于患者的临床数据和生化指标,辅助医生进行早期诊断、风险评估和治疗决策,从而提高糖尿病患者的生活质量。
Adaboost(自适应增强)是一种集成学习算法,已在许多领域取得了成功应用。它通过迭代训练一系列弱分类器,每个弱分类器都试图修正前一个分类器的错误。通过组合这些弱分类器的预测结果,Adaboost算法可以构建一个强分类器,具有更高的准确性和泛化能力。
在糖尿病预测中,使用Adaboost算法可以将不同的临床特征和生化指标组合起来,构建一个强大的预测模型。这样的模型可以识别和利用患者的潜在模式和关联性,以预测糖尿病的发生风险。通过这种方式,医生可以更好地评估患者的糖尿病风险,并采取相应的干预措施,如生活方式调整、药物治疗等,以防止糖尿病的发展和并发症的出现。
因此,基于Adaboost算法构建糖尿病预测模型具有重要的临床应用前景,可以为医生提供决策支持,改善糖尿病患者的管理和治疗效果。
2.项目简介
2.1项目说明
本项目旨在通过分析糖尿病病人的历史数据,找出影响患糖尿病的因素,最后使用机器学习算法构建糖尿病预测模型。
2.2数据说明
本数据来源于kaggle,原始数据集共有100000条,9列。该数据集是来自患者的医疗和人口统计数据的集合,以及他们的糖尿病状态(阳性或阴性)。这些数据包括年龄、性别、体重指数(BMI)、高血压、心脏病、吸烟史、糖化血红蛋白水平和血糖水平等特征。
2.3技术工具
Python版本:3.9
代码编辑器:jupyter notebook
3.算法原理
Adaboost算法基本原理就是将多个弱分类器(弱分类器一般选用单层决策树)进行合理的结合,使其成为一个强分类器。Adaboost采用迭代的思想,每次迭代只训练一个弱分类器,训练好的弱分类器将参与下一次迭代的使用。也就是说,在第N次迭代中,一共就有N个弱分类器,其中N-1个是以前训练好的,其各种参数都不再改变,本次训练第N个分类器。其中弱分类器的关系是第N个弱分类器更可能分对前N-1个弱分类器没分对的数据,最终分类输出要看这N个分类器的综合效果。
AdaBoost自适应是Boosting算法最著名的代表。Kearns和Valiant首先提出了“强可学”和“弱可学”的概念。指出在概率近似正确学习的框架下,如果有一个多项式学习算法可以学习一个概念(一个类),并且正确概率很高,则称这个概念(一个类)是强可学习的。一个概念如果有多项式学习算法可以学习,就说它是弱可学习的,而且学习的准确率只比随机猜测的准确率略高。后来Schapire证明了概念强可学的充要条件是概念弱可学。
找到弱学习算法通常比找到强学习算法容易得多。这样一来,如果已经找到了一个“弱学习算法”,如何将其提升为“强学习算法”?具体的实现方法成为开发推广方法时要解决的问题。关于提升方法的研究很多,也提出了很多算法。最有代表性的就是AdaBoost算法。Boosting又称强化学习或提升方法,是一种重要的集成学习技术,可以将一个预测精度仅略高于随机猜测的弱学习者增强为预测精度高的强学习者。这在直接构造一个强学习器非常困难的情况下,为学习算法的设计提供了一种有效的新思路和新方法。最成功的应用是1995年由Yoav Freund和Robert Schapire提出的AdaBoost算法。
AdaBoost是英文'自适应增强的缩写。它的适应性在于,被前一个基本分类器错误分类的样本的权重会增加,而被正确分类的样本的权重会减少,它将被用来再次训练下一个基本分类器。同时,在每次迭代中,增加一个新的弱分类器,直到预定的错误率足够小或者达到预设的最大迭代次数,才确定最终的强分类器。
首先,初始化训练数据的权重分布D1。假设有n个训练样本数据,在开始时,每个训练样本被赋予相同的权重:w1=1/n .然后,训练弱分类器hi。在具体的训练过程中,如果某个训练样本点被弱分类器hi准确分类,那么在构造下一个训练集时要降低其对应的权重;相反,如果训练样本点被错误分类,则应该增加其权重。具有更新的权重的样本集用于训练下一个分类器,并且整个训练过程迭代进行。最后,将训练得到的弱分类器组合成一个强分类器。在每个弱分类器的训练过程结束后,增加分类错误率小的弱分类器的权重,使其在最终的分类函数中起较大的决定性作用,同时减少分类错误率大的弱分类器的权重,使其在最终的分类函数中起较小的决定性作用。换句话说,错误率低的弱分类器在最终分类器中的权重较大,反之则较小。
AdaBoost是典型的Boosting算法,属于Boosting家族。在AdaBoost之前,先说一下Boosting算法。Boosting算法是将“弱学习算法”升级为“强学习算法”的过程,主要思想是“三个臭皮匠顶个诸葛亮".一般来说,找到一个弱学习算法相对容易,然后通过反复学习得到一系列弱分类器,将这些弱分类器组合起来得到一个强分类器。Boosting算法包括两部分,加性模型和正向逐步算法。加法模型是指强分类器由一系列弱分类器线性相加而成。
在综合学习原理的总结中提到,根据个体学习者之间是否存在依赖关系,综合学习可以分为两类。第一种是个体学习者之间有很强的依赖关系,另一种是个体学习者之间没有很强的依赖关系。前者的代表算法是boosting级数算法。在boosting算法中,Adaboost是最著名的算法之一。Adaboost既可以用作分类,也可以用作回归。
4.项目实施步骤
4.1理解数据
导入本实验用到的第三方库,导入原始数据集
查看数据大小,查看数据基本信息
从结果可看出,原始数据集共有100000行,9列。从基本信息可看出各列特征不存在缺失值及其数据类型。
查看数值型和非数值型数据类型的描述性统计数据
数值型描述性统计可看出各变量的均值、方差、最大最小值、四分位数等信息。
非数值型描述性统计可看出各变量的唯一值个数、最高频次的值及其频次。
4.2数据预处理
统计数据各列缺失值总数,使用any检测数据集是否存在重复值。
从结果可看出,数据不存在缺失值,但存在重复值,需要处理。这里我们直接删除处理。
可以发现删除后数据还剩96146条。
我们又惊奇的发现性别变量还出现了其他(共计18个),这明显是异常数据,需要删除处理。
4.3探索性数据分析
4.3.1分析是否患病的比例
通过图发现,该数据集绝大部分都是没有患病的,说明该数据集显著不平衡,后续需要处理。
4.3.2分析血糖水平对糖尿病的影响
通过图形发现,性别对于是否患病没有显著性影响,但是血糖水平有显著性影响,患病的血糖水平显著高于没有患病的。
4.3.3分析年龄对糖尿病的影响
通过图形发现,患糖尿病的群体年龄主要集中在55-70岁之间,主要为老年群体。值得注意的是20岁以下患病的也存在一些。
4.3.4 分析不同性别和年龄在高血压上的差异
基于性别的高血压与年龄的箱线图与糖尿病与年龄的箱线图相似,这是意料之中的,因为通常大多数糖尿病患者的中位年龄较高,并且在年龄附近高血压的可能性也自然增加。在这里,年龄可以被称为一个混淆因素。
4.3.5分析不同性别和糖化血红蛋白水平在血糖蛋白水平上的差异
从图发现,性别似乎没有什么影响,均不存在显著性差异。
4.3.6分析不同性别和血糖蛋白水平在BIM上的差异
对于每一种血糖水平,女性的BMI似乎都比男性高。
4.3.7相关系数热力图
最后,从热图中我们可以看到,不存在共线性的证据。虽然可能存在多重共线性,但我们需要主题专家的帮助才能找到它,因为在我们可以找到共线性的给定数据集中没有高相关性(> 0.7)。总的来说,预测因子之间没有相关性,我们可以将数据用于各种模型。
4.4特征工程
前面在了解数据的时候发现性别和是否有吸烟史是非数值型数据类型,所以在这里要进行编码处理,使用sklearn中的LabelEncoder。
前面我们发现了数据是不平衡的,所以这里我们做个欠采样处理
接着准确建模等数据,拆分数据集
4.5模型构建
先定义存储模型准确率、运行时间、f1值的字典。
构建逻辑回归模型
构建随机森林模型
构建Adaboost模型
构建多项式朴素贝叶斯模型
构建支持向量机模型
4.6模型评估
前面我们构建了5个分类模型,接下来汇总一下模型的各指标
可以发现Adaboost模型的准确率和F1都是最高的,运行时间也是相对较高的,即是最理想的模型,所以我们最终使用其作为训练模型。
对Adaboost模型进行评估,打印其混淆矩阵和分类报告,最后绘制ROC曲线。
4.7特征重要性
打印出特征重要性评分并可视化
从结果可看出,血糖水平、年龄、bim对患糖尿病的影响程度最大。
4.8模型预测
这里我们随机抽取10个进行检查模型预测效果
从结果发现,模型预测10个中,正确了9个,错误1个,模型效果还不错。
5.实验总结
本次实验我们找出了影响糖尿病的重要特征,即血糖水平、年龄、bim,最后我们使用Adaboost算法构建了糖尿病预测模型,模型的准确率为0.91,模型效果不错。
心得与体会:
通过这次Python项目实战,我学到了许多新的知识,这是一个让我把书本上的理论知识运用于实践中的好机会。原先,学的时候感叹学的资料太难懂,此刻想来,有些其实并不难,关键在于理解。
在这次实战中还锻炼了我其他方面的潜力,提高了我的综合素质。首先,它锻炼了我做项目的潜力,提高了独立思考问题、自我动手操作的潜力,在工作的过程中,复习了以前学习过的知识,并掌握了一些应用知识的技巧等
在此次实战中,我还学会了下面几点工作学习心态:
1)继续学习,不断提升理论涵养。在信息时代,学习是不断地汲取新信息,获得事业进步的动力。作为一名青年学子更就应把学习作为持续工作用心性的重要途径。走上工作岗位后,我会用心响应单位号召,结合工作实际,不断学习理论、业务知识和社会知识,用先进的理论武装头脑,用精良的业务知识提升潜力,以广博的社会知识拓展视野。
2)努力实践,自觉进行主角转化。只有将理论付诸于实践才能实现理论自身的价值,也只有将理论付诸于实践才能使理论得以检验。同样,一个人的价值也是透过实践活动来实现的,也只有透过实践才能锻炼人的品质,彰显人的意志。
3)提高工作用心性和主动性。实习,是开端也是结束。展此刻自我面前的是一片任自我驰骋的沃土,也分明感受到了沉甸甸的职责。在今后的工作和生活中,我将继续学习,深入实践,不断提升自我,努力创造业绩,继续创造更多的价值。
这次Python实战不仅仅使我学到了知识,丰富了经验。也帮忙我缩小了实践和理论的差距。在未来的工作中我会把学到的理论知识和实践经验不断的应用到实际工作中,为实现理想而努力。
源代码
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(font='SimHei')
import warnings
warnings.filterwarnings('ignore')
data = pd.read_csv('diabetes_prediction_dataset.csv')
data.head()
data.shape
data.info()
data.describe()
data.describe(include='O')
data.isnull().sum()
any(data.duplicated())
data.drop_duplicates(inplace=True)
data.shape
data['gender'].value_counts()
data = data[data['gender']!='Other']
data['gender'].value_counts()
data['diabetes'].value_counts().plot(kind='bar')
plt.show()
# 分析不同性别和血糖水平对糖尿病的影响
sns.catplot(data = data, x = 'diabetes', y = 'blood_glucose_level', kind = 'box', hue = 'gender')
plt.show()
# 分析不同性别和年龄对糖尿病的影响
sns.catplot(data = data, x = 'diabetes', y = 'age', kind = 'box', hue = 'gender')
plt.show()
从上面的糖尿病与年龄的箱线图中我们可以看到,大多数糖尿病患者的中位年龄较高,而且通常年龄较高,只有少数20岁以下的人也患有糖尿病。
# 分析不同性别和年龄在高血压上的差异
sns.catplot(data = data, x = 'hypertension', y = 'age', kind = 'box', hue = 'gender')
plt.show()
# 分析不同性别和糖化血红蛋白水平在血糖蛋白水平上的差异
sns.relplot(data = data, x = 'HbA1c_level', y = 'blood_glucose_level', kind = 'line', hue = 'gender', ci = None, markers = True)
plt.show()
# 分析不同性别和血糖蛋白水平在BIM上的差异
sns.relplot(data = data, x = 'blood_glucose_level', y = 'bmi', kind = 'line', hue = 'gender', ci = None)
plt.show()
# 相关系数热力图
plt.figure(figsize=(10,8))
sns.heatmap(data.corr(), annot = True, cmap = 'coolwarm')
plt.show()
data.head()
# 特征工程-变量代换
from sklearn.preprocessing import LabelEncoder
data['gender'] = LabelEncoder().fit_transform(data['gender'])
data['smoking_history'] = LabelEncoder().fit_transform(data['smoking_history'])
data.head()
# 欠采样处理
new_data = pd.concat([data[data['diabetes']==0].sample(len(data[data['diabetes']==1])),data[data['diabetes']==1]])
new_data['diabetes'].value_counts()
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import time
from sklearn.metrics import f1_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.svm import LinearSVC
# 准备数据
X = new_data.drop('diabetes',axis=1)
y = new_data['diabetes']
# 拆分数据
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=42)
print(f'训练集大小:',X_train.shape[0])
print(f'测试集大小:',X_test.shape[0])
scores = dict()
time_models = dict()
f1 = dict()
# 构建逻辑回归模型
t0 = time.time()
lr_model = LogisticRegression().fit(X_train, y_train)
t1 = time.time()
print('Model Runnign Time',t1-t0)
lr_score = lr_model.score(X_test, y_test)
scores['Logistic Regression'] = lr_score
print(lr_score)
time_models['Logistic Regression'] = t1-t0
y_pred = lr_model.predict(X_test)
f1['Logistic Regression'] = f1_score(y_test,y_pred)
# 构建随机森林模型
t0 = time.time()
rf_model = RandomForestClassifier().fit(X_train, y_train)
t1 = time.time()
print('Model Runnign Time',t1-t0)
rf_score = rf_model.score(X_test, y_test)
print(rf_score)
time_models['Random Forest'] = t1-t0
scores['Random Forest'] = rf_score
f1['Random Forest'] = f1_score(y_test, rf_model.predict(X_test))
# 构建adaboost模型
t0 = time.time()
ada_model = AdaBoostClassifier().fit(X_train, y_train)
t1 = time.time()
print('Model Runnign Time',t1-t0)
time_models['Ada Boost'] = t1-t0
f1['Ada Boost'] = f1_score(y_test, ada_model.predict(X_test))
print('Score',ada_model.score(X_test, y_test))
scores['Ada Boost'] = ada_model.score(X_test, y_test)
# 构建朴素贝叶斯模型
from sklearn.naive_bayes import MultinomialNB
t0 = time.time()
naive_multimonial_model = MultinomialNB().fit(X_train, y_train)
t1 = time.time()
print('Model Runnign Time',t1-t0)
time_models['Multinomial Naive Bayes'] = t1-t0
print('Score',naive_multimonial_model.score(X_test, y_test))
scores['Multinomial Naive Bayes'] = naive_multimonial_model.score(X_test, y_test)
f1['Multinomial Naive Bayes'] = f1_score(y_test, naive_multimonial_model.predict(X_test))
# 构建支持向量机svc模型
t0 = time.time()
svm_model = LinearSVC(dual=False, random_state = 110).fit(X_train, y_train)
t1 = time.time()
print('Model Runnign Time',t1-t0)
time_models['Linear Support Vector Machine'] = t1-t0
print('Score',svm_model.score(X_test, y_test))
scores['Linear Support Vector Machine'] = svm_model.score(X_test, y_test)
f1['Linear Support Vector Machine'] = f1_score(y_test, svm_model.predict(X_test))
# 查看模型评估指标汇总的结果
result_df = pd.DataFrame({'Models': scores.keys(), 'Scores':scores.values(), 'Time':time_models.values(), 'F1':f1.values()})
result_df.sort_values('Scores', ascending = False)
from sklearn.metrics import confusion_matrix,classification_report,auc,roc_curve
# 模型评估
y_pred = ada_model.predict(X_test)
print('confusion_matrix:','
',confusion_matrix(y_test,y_pred))
print('classification_report:','
',classification_report(y_test,y_pred))
# 画出ROC曲线
y_prob = ada_model.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 = ada_model.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])
print(f + 1, feat_labels[j], importances[j])
plt.figure(figsize=(12,8))
plt.barh(index_list[::-1],value_list[::-1])
plt.yticks(fontsize=12)
plt.title('Feature Importance Sorted',fontsize=14)
plt.show()
# 模型预测
res = pd.DataFrame()
res['真实值'] = y_test
res['预测值'] = y_pred
res.sample(10) # 随机抽取10个