实验题目要求
数据描述
对胎儿健康进行分类,以防止儿童和产妇死亡。
降低儿童死亡率反映在联合国的若干可持续发展目标中,是人类进步的关键指标。联合国预计,到2030年,各国将结束可预防的5岁以下新生儿和儿童的死亡,所有国家都力争将5岁以下儿童的死亡率降低到至少每1000活产25人。
与儿童死亡率的概念平行的当然是孕产妇死亡率,其占妊娠和分娩期间和之后(截至2017年)的295 000例死亡。这些死亡中的绝大多数(94%)发生在资源贫乏的地区,大多数可以预防。
鉴于上述情况,心电图(CTG)是评估胎儿健康的一种简单且成本可承受的选择,允许医疗保健专业人员采取行动以预防儿童和孕产妇死亡。该设备本身通过发送超声波脉冲并读取其响应来工作,从而减轻了胎儿心率(FHR),胎儿运动,子宫收缩等方面的负担。
内容范围及评分要求
该数据集包含从心电图检查中提取的2126条特征记录,然后由三名产科专家将其分类为3类:
正常
疑似
病理性的
创建一个多类模型以将CTG功能分类为三种胎儿健康状态。
“train.csv”包含1767个数据,每个数据包含21个属性。最后一列“fetal_health”的值表示健康程度,为分类标签,其中“1”为正常,“2”为疑似,“3”为病例性的。
“test.csv”包含280个数据,你的目标是预测其结果。
“predict.csv”是需要将预测的结果放在此表中,然后上传。
要求:以报告(文档)的形式记录整个实验过程。
实验报告(文档)内应将过程分为以下几步:1.数据理解和清洗;2.特征提取和选择;3.构建模型进行训练;4.模型评估和预测。每步都要有详细过程。
在数据理解和清洗中,要求将按属性进行数据分析,统计信息缺失情况,且以图表的形式对数据进行展示。
在特征提取和选择中,要求对清洗后的数据进行特征提取,选择合适的特征或使用降维作为模型训练的输入。
在模型构建中,要求选择合适的机器学习方法构建模型(可选择多种方法进行对比),输出在训练集上的准确率,要有训练过程。在此部分,要对使用的方法进行方法介绍。(以SVM为例,要阐述SVM的基本原理、算法流程、目标函数等)。
在模型评估和预测中,要求使用预测数据集预测结果,将预测结果保存到predict.csv文件中。与真实标签对比,输出测试集上的准确率。
最终上传文件:报告(包含整个过程)、代码、csv文件(输出结果,形式如其真实标签类似,参考predict.csv).
具体过程可参考:kaggle泰坦尼克号数据集——数据分析全流程 - 知乎。
评分标准:以测试集上的分类准确率为这次考试的成绩。比如你的分类准确率为80%,你的代码成绩为80分。本次报告的最终成绩为:代码成绩*50%+报告*50%。
胎儿健康分类实验报告
-
数据的基本统计分析
-
数据分析的第一步便是了解数据集属性,查看数据的基本情况(数据量、缺失值、异常值等)。
我先检查了训练集和测试集的完整程度,即查看各列属性的数据量和缺失情况
-
训练集:
测试集:
两数据集均未产生数据缺失,
然后我们再看两组数据集的基本情况:
其中count为数量,mean为平均值,std为标准差
这里的数据并没有显示完全,故我采取了set_option函数来设置控制台输出的显示选项,通过pd.set_option函数,将display.max_columns设置为None可以显示所有列,将display.expand_frame_repr设置为False可以防止输出被省略号代替我们根据表格中的数据可知,一共有以下这些值:
number: 编号baseline value: 基线值
accelerations: 加速
fetal_movement: 胎动
uterine_contractions: 子宫收缩
light_decelerations: 轻度减速
severe_decelerations: 重度减速
prolongued_decelerations: 持续减速
abnormal_short_term_variability: 异常短期变异性
mean_value_of_short_term_variability: 短期变异性的平均值
percentage_of_time_with_abnormal_long_term_variability:异常长期变异性的时间百分比
mean_value_of_long_term_variability: 长期变异性的平均值
histogram_width: 直方图宽度
histogram_min: 直方图最小值
histogram_max: 直方图最大值
histogram_number_of_peaks: 直方图峰值数量
histogram_number_of_zeroes: 直方图零值数量
histogram_mode: 直方图模式
histogram_mean: 直方图均值
histogram_median: 直方图中位数
histogram_variance: 直方图方差
histogram_tendency: 直方图趋势
fetal_health: 胎儿健康状况
简单的分析一下,这些数据除了编号number以外,都与我们的胎儿健康分类相关,因此不能舍弃,需要都加入到后期的分析,此外我们发现在我们的测试集中没有fetal_health: 胎儿健康状况
-
数据的属性探查
数据的属性探测是针对单个的属性探测其分布情况,一般可以通过绘制单个属性的分布图进行探查。
首先我们探查一下胎儿健康情况的分布,它分为1,2,3这三种情况,
其中,前两行代码是用于配置matplotlib库的字体设置,以确保能够正确显示中文字符。通过这两行配置,可以确保在使用matplotlib库进行数据可视化时,能够正确显示中文字符和负号,提供更好的图表展示效果。
结果如下,我们能直观的发现从占比来讲,1>>2>3
然后我们再看一下其他的分布情况
采取plt方法绘图,建了一个2*4的网格布局,前八个标签的分布情况我们用其表达。
代码节选:
由于baseline value: 基线值,accelerations: 加速,fetal_movement: 胎动,uterine_contractions: 子宫收缩,light_decelerations: 轻度减速,severe_decelerations: 重度减速,prolongued_decelerations: 持续减速,abnormal_short_term_variability: 异常短期变异性这些类都是连续类别型的属性,故我们都采取直方图来查看
代码节选:
分析:对于胎动分布来说,最大为0.481,最小为0,但是平均值为0.007392,方差也只为0.041273.由此可知绝大多数的胎动值都在0-0.05之间,而我们胎儿的健康指数1:2:3=1376:245:146,该比值比胎动指数的比值大得多。所以暂且推测胎动基本对胎儿健康指数没有影响由此类推,重度减速和持续减速也基本对胎儿健康指数没有影响
这里由于我们的变量太多,都需要分析,所以我们剩下的除了直方图趋势这种类别型属性,还有12个标签,分成3*4的网格布局
histogram_tendency: 直方图趋势,这类属性是类别型属性,只是有3个类别,我们统计这3类的数量即可。 -
数据预处理
-
由于上述数据中我们并没有发现有缺失值和异常值,所以我选择不处理
-
数据的相关性分析
由于上述数据中我们并没有发现有缺失值和异常值,所以我选择不处理
数据的相关性分析可以探查属性间的相关性,查看属性是否存在冗余;另外通过探寻各属性和结果属性的关系,进而选择和结果相关性较大的属性,作为建模的重要特征,所以这一部分我们首先探测各属性间关系,然后再探测单个属性和结果之间的关系。
属性间相关性探测:
在得到上述的相关性热力图后,我们发现由于属性太多,他们之中相关性高的也多,并不好再进一步进行处理分析,所以我在接下来的特征工程中采取pca的方法进行降维 -
特征工程
-
首先介绍一下我采用的降维方法,主成分分析(PCA):对于大量特征的数据集,可以使用PCA进行降维。PCA可以将原始特征转换为一组线性无关的主成分,其中每个主成分都具有不同的重要性。您可以选择保留最重要的主成分,作为关键数据。我选择了key_data(也就是这21个属性的)作为关键数据,并使用PCA将其降维为2个主成分。然后,我们绘制了降维后的数据散点图,其中x轴和y轴分别代表了第一个和第二个主成分。我保留了2个主成分,并将其命名为"Principal Component 1"和"Principal Component 2"。这两个主成分是根据数据中的方差分布计算得到的,并且它们是原始特征的线性组合。
最终得到的散点图如下所示: -
数据模型构建
也首先介绍一下我采取的模型,支持向量机(Support Vector Machine,SVM)它是一种常用的监督学习算法,主要用于分类和回归问题。它在机器学习领域具有广泛的应用,并且在处理小样本、非线性和高维数据的情况下表现出色。
SVM的基本思想是构建一个最优的超平面,将不同类别的样本分开。在二分类问题中,它的目标是找到一个能够最大化类别间间隔(Margin)的超平面,同时限制训练样本的分类错误率。支持向量指的是距离超平面最近的样本点,它们对于确定超平面起到关键作用。
我们首先进行数据预处理,主要是划分训练集和测试集并且将数据处理为numpy矩阵,方便后续的处理:
接下来就是我们的svm分类器的参数配置首先是误差惩罚系数,默认值为1,这个数值越大表示容错能力越低
其次是核函数,选取了线性核函数,它在特征空间中采取核函数进行分类
最后是决策函数,选取的是one-vs-rest策略,目的是将多类别分类问题转化为多个二分类问题
然后是模型训练部分:
fit方法接受训练集的特征向量作为第一个参数(x_train),目标值作为第二个参数(y_train.ravel())。ravel()函数用于将目标值展平为一维数组,以符合fit方法的要求。
最后直接train(clf, x_train1, y_train1)即可
整个过程其实就是SVM分类器对象clf被配置为使用线性核函数,并采用OvR策略进行多类别分类。然后,使用train函数对模型进行训练,将训练集的特征向量和目标值传入。这样就完成了SVM模型的训练过程
但是此时,我们运行后出现了报错:
报错的意思是我在处理数据的时候的使用了np.matrix,但该类在最新的NumPy版本中已不推荐使用,并且在将来可能会被移除。相反,建议使用常规的NumPy数组。根据报错信息的建议,可以使用np.asarray将np.matrix对象转换为NumPy数组。
那我们就按照他给出的要求修改即可
此时再运行就没有报错了
准确率达到了90%以上,win! -
交叉检验
-
交叉验证是为了检验我们模型的好坏,我们利用sklearn中的模型交叉验证对训练数据进行检测,这里我们对模型分割5次,每次20%拿去检测,80%用于训练,输出每次的精度,和五次精度平均值。
我们进行了5次交叉验证之后的平均值也达到了0.9左右,说明我们的模型也挺好,没有更换模型的必要了 -
特征选择
-
特征选择是特征工程和模型优化的重要部分,选择的过程贯穿于数据的整个分析和建模的过程,是一个不断迭代的过程。这里SVM模型中我们就是相对简单的筛选出对我们的模型影响比较大的特征,使用coef_属性获取特征的权重,进而评估特征的重要性。较大的权重表示该特征对模型的贡献较大。实现的思路是:使用SelectFromModel类来进行特征选择。首先,我们使用训练好的SVM模型clf作为参数创建了一个SelectFromModel对象model。然后,通过调用model.transform(x_train1)方法,选择训练集中的重要特征。使用model.get_support(indices=True)方法可以获取所选特征的索引。最后,我们将选择的特征用于交叉验证。
可以看出,我们选取出的特征值索引分别是0,2,8,10,14,20这六项,但是这里有一个问题是:他把我们的第一项也算进来了,而我们的第一项是number序列,按理来说对我们的婴儿健康程度分析没有影响,但其它的也能直观的看出来确实还是比较准的 -
模型过拟合分析
衡量一个模型的好坏不至是看模型的精度高低,因为检验数据和训练数据出自一份数据集,在检验数据上取得了好的精度,不代表在测试数据集上依然可以得到好的预测结果,这种情况我们称之为过拟合,所以针对得到的模型,我们还要检测其是否存在过拟合情况,
其实本来想的是计算训练集和测试集的准确率。然后,通过将训练集的准确率与测试集的准确率进行比较,判断模型是否存在过拟合。但是这样做不够直观,就还是使用了泰坦尼克实验中的方法,具体思路是:使用training_sizes数组来定义不同训练集大小的范围。然后,通过循环迭代不同大小的训练集,计算训练集和测试集的准确率,并将它们存储在train_scores和test_scores数组中。最后,使用plt.plot()函数将训练集和测试集的准确率绘制成曲线图。
还是可以比较清晰直观的看到训练集和测试集的准确率也比较趋近于一致,因此我们判断没有出现过拟合或者欠拟合的情况
当然最后的最后,不要忘了将我们的预测结果保存到excel文件中
保存成功