泰坦尼克号数据集是一个公开可获取的数据集,源自1912年沉没的RMS泰坦尼克号事件。这个数据集被广泛用于教育和研究,特别是作为机器学习和数据分析的经典案例。数据集记录了船上乘客的一些信息,以及他们是否在灾难中幸存下来。以下是数据集中主要指标的详细介绍:
数据集来源:
数据集最初由Andrew Gelman等人收集整理,用于统计建模的教学。现在,它通常可以从Kaggle等平台获取。
数据集结构:
数据集分为两个文件:train.csv(训练集)和test.csv(测试集),其中训练集包含了一些已知乘客的生存结果,用于模型训练;测试集则没有生存结果,用户需预测这些乘客的生存情况并提交结果以评估模型性能。
主要特征(Columns):
- PassengerId:乘客的唯一标识符。
- Survived:这是目标变量,表示乘客是否在灾难中幸存下来(0 = 未生还,1 = 生还)。
- Pclass:乘客的船票等级(1 = 一等舱,2 = 二等舱,3 = 三等舱)。这反映了乘客的社会经济状况。
- Name:乘客姓名。虽然直接用于模型预测的价值不大,但可以通过姓名提取如称呼(Mr., Mrs.,
Miss.等)作为社会地位的一个代理指标。 - Sex:乘客性别(male/female)。
- Age:乘客的年龄。注意,数据集中存在一些缺失值。
- SibSp:同乘的兄弟姐妹/配偶人数。
- Parch:同乘的父母/子女人数。
- Ticket:船票号码。这个特征一般不直接用于模型,但有时会用来探索某些票种的生存率差异。
- Fare:乘客的船票价。反映了乘客的支付能力,与社会经济状况有关。
- Cabin:乘客的客舱号。数据缺失严重,但完整的客舱号可能指示了船上的位置,从而影响逃生机会。
- Embarked:乘客的登船港口(C = Cherbourg, Q = Queenstown, S =
Southampton)。反映了乘客的出发地,可能与社会经济背景相关联。 数据分析与机器学习应用
在使用这个数据集进行机器学习时,数据清洗、特征工程(如处理缺失值、进行特征转换)是至关重要的前期工作。之后,选择合适的模型进行训练,并通过交叉验证等技术评估模型的泛化能力。由于数据集相对较小且问题定义清晰,它非常适合初学者入门机器学习,同时也能够引入更多高级主题,如特征选择、模型调优、集成学习等。
泰坦尼克号数据集不仅提供了丰富的数据探索和分析的机会,也让学习者能够深刻理解机器学习项目从数据准备到模型部署的整个流程。
分析目的:
泰坦尼克号是数据科学机器学习领域很经典的数据集,在统计学里面也有很多案例,比如拟合优度检验,方差分析等等。其背景就是当年泰坦尼克号在灾难发生后,有人生存有人死亡,而且每个人都有很多不同的特征,比如性别,年龄,船仓等级,登船地点等等…根据这些特征,我们可以预测乘客是否存活下来。
响应变量为两种取值,存活是1,死亡是0,所以这是一个分类问题。
数据收集和读取:
kaggle是国际很有名的数据科学竞赛平台,上面有很多比赛,也有很多数据集,本文数据集便来源于此。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
data = pd.read_csv('/Users/c/jupyter lab/CSDN/人工智能-机器学习/train.csv')
data2 = pd.read_csv('/Users/c/jupyter lab/CSDN/人工智能-机器学习/test.csv')
训练集和测试集前五行数据:
数据清洗和整理:
可以看到训练集有891行数据,测试集418行数据。有多列存在缺失值。
可视化查看数据缺失值:
# 可视化查看缺失值
import missingno as msno
%matplotlib inline
msno.matrix(data)
测试集可视化方法一样,这里就不展示了。
上图黑色位置表示有数据,白色表示数据缺失,可以看到cabin(乘客客舱号)列缺失值很多,age(年龄)列缺失值也较多。
数据清洗:
- 特征选择:删除一些不需要的变量,比如乘客编号、名字、船票编号等。
y=data['Survived']
data.drop ('Survived',axis=1, inplace=True)
data.drop ('PassengerId',axis=1, inplace=True)
data.drop ('Name',axis=1, inplace=True)
data.drop ('Ticket',axis=1, inplace=True)
data.drop ('Cabin',axis=1, inplace=True)
ID=data2['PassengerId']
data2.drop ('PassengerId',axis=1, inplace=True)
data2.drop ('Name',axis=1, inplace=True)
data2.drop ('Ticket',axis=1, inplace=True)
data2.drop ('Cabin',axis=1, inplace=True)
- 缺失值填充:对年龄等缺失值采取中位数填充。
data['Age'].fillna(data.Age.median(), inplace=True)
data['Embarked'].fillna(method='pad',axis=0,inplace=True)
data2['Age'].fillna(data2.Age.median(), inplace=True)
data2['Fare'].fillna(method='pad',axis=0,inplace=True)
- 分类型数据转化:将文本型的分类数据映射为数值型数据,例如男:0,女:1.
d1={'male':0,'female':1}
d2={'S':1,'C':2,'Q':3}
data['Sex']=data['Sex'].map(d1)
data['Embarked']=data['Embarked'].map(d2)
data2['Sex']=data2['Sex'].map(d1)
data2['Embarked']=data2['Embarked'].map(d2)
特征工程:
查看清洗好的数据信息:
X=data.copy()
test=data2.copy()
X.info()
test.info()
可以看到,缺失值数据全部处理干净了。
画图查看训练集和测试集的变量分布情况:
# 设置子图的列数
dist_cols = 4
# 设置子图的行数,这里假设data2是一个pandas DataFrame,并且使用其列数作为行数
dist_rows = len(data2.columns)
# 创建一个图形窗口,并设置其大小,这里的大小根据子图的行列数进行调整
plt.figure(figsize=(4 * dist_cols, 4 * dist_rows))
# 初始化计数器,用于追踪当前正在处理的子图
i = 1
# 遍历data2的每一列
for col in data2.columns:
# 创建一个子图,并返回该子图的Axes对象
ax = plt.subplot(dist_rows, dist_cols, i)
# 在子图上绘制data DataFrame中对应列的核密度估计图(KDE),颜色为红色,并且填充阴影
ax = sns.kdeplot(data[col], color="Red", shade=True)
# 在相同的子图上再绘制data2 DataFrame中对应列的核密度估计图(KDE),颜色为蓝色,并且填充阴影
ax = sns.kdeplot(data2[col], color="Blue", shade=True)
# 设置x轴的标签为当前处理的列名
ax.set_xlabel(col)
# 设置y轴的标签为"Frequency"(频率)
ax.set_ylabel("Frequency")
# 为子图添加图例,标识为["train", "test"],但这里有一个小问题,因为kdeplot本身不直接支持图例,所以通常我们会使用plt.legend或者手动添加图例
# 这里使用ax.legend可能不会正确显示图例,通常需要使用其他的方法,比如使用lines或patches手动添加
ax = ax.legend(["train", "test"]) # 注意:这里可能不会正常工作,需要额外的处理
# 更新计数器,准备处理下一个子图
i += 1
# 显示图形
plt.show()
从上图可以看出训练集和测试集的数据分布还是很一致的,可能大家看不懂,下面还是给大家解读一下吧。
核密度图 Kernel Density Estimation, KDE是一种非参数统计方法,用于估计一个变量的概率密度函数。在数据可视化中,KDE图经常用于展示数据的分布形态,特别是当数据不满足正态分布时。
以下是核密度图的一些关键特点和如何解读它们:
- 峰值(Peaks):KDE图中的峰值表示数据集中出现频率最高的区域。如果KDE图有一个明显的峰值,那么这可能意味着数据集中在某个值附近非常集中。
- 多峰(Multiple
Peaks):如果KDE图中有多个峰值,那么这可能表示数据来自多个不同的分布或者类别。例如,在分类问题中,不同类别的数据可能有不同的KDE图峰值。 - 偏态(Skewness):KDE图的形状可以帮助判断数据分布的偏态性。如果KDE图的一侧比另一侧更长或更陡峭,那么这可能意味着数据分布是偏态的。
- 尾部(Tails):KDE图的尾部展示了数据分布的极端值情况。如果尾部很长,那么这可能意味着数据集中有一些极端的值。
- 重叠(Overlap):当比较两个或多个KDE图时(如你提供的代码所示),重叠区域表示这些数据分布有相似的值范围。没有重叠的区域则展示了数据分布之间的差异。
- 颜色填充(Shade):在KDE图中,颜色填充通常用于表示概率密度的高低。颜色越深,表示该区域的概率密度越高。
- 图例(Legend):虽然sns.kdeplot本身可能不直接支持图例,但你可以通过其他方式(如plt.legend或手动添加)来区分不同的KDE线。
- X轴和Y轴:X轴通常表示数据的值,而Y轴表示概率密度或频率。注意,KDE图通常不会显示真实的频率值,而是概率密度值,因此Y轴的单位是相对的。
可视化相关性矩阵:
corr = plt.subplots(figsize = (8,6))
corr= sns.heatmap(data.corr(method='spearman'),annot=True,square=True)
变量之间的相关性还是不太高,只有船舱等级和船费是负相关,且相关系数负值较大,因为船票越贵就能坐更好的船舱,测试集也差不多就不展示了,继续跟大家科谱。
**相关性矩阵(也称为相关系数矩阵)**是一个用于描述多个变量之间相关程度的矩阵。以下是关于如何清晰地解读相关性矩阵的一些要点:
- 矩阵结构: 相关性矩阵是一个方阵,其行和列都代表相同的变量。 矩阵中的每个元素表示两个变量之间的相关系数。
- 相关系数的取值范围: 相关系数的取值范围在-1到1之间。
接近1表示两个变量之间存在强正相关关系,即当一个变量增加时,另一个变量也倾向于增加。
接近-1表示两个变量之间存在强负相关关系,即当一个变量增加时,另一个变量倾向于减少。 接近0表示两个变量之间的线性关系较弱或无相关。 - 矩阵的对角线元素: 相关性矩阵的对角线元素都是1,因为任何变量与其自身的相关系数都是1。 矩阵的对称性:
相关性矩阵是对称的,即矩阵的上三角和下三角是对称的。这是因为相关系数是双向的,A与B的相关系数和B与A的相关系数是相同的。 - 解读元素:
观察矩阵中的元素,可以了解不同变量之间的关联性。例如,如果两个变量之间的相关系数接近1或-1,那么这两个变量之间存在较强的线性关系。
如果多个变量之间都存在较高的相关性,可能表明这些变量之间存在共线性问题,这在进行多元回归分析时需要注意。 - 结合专业知识:
在分析相关性矩阵时,还需要结合专业知识来判断相关系数的合理性。例如,在某些情况下,即使相关系数较低,也可能因为实际背景知识而认为两个变量之间存在重要关系。 - 可视化:
可以使用热力图(heatmap)等可视化工具来展示相关性矩阵,使得不同变量之间的相关性更加直观和易于理解。在热力图中,颜色深浅通常表示相关性的强弱,例如深红色可能表示强正相关,深蓝色可能表示强负相关。
建模与优化
开始机器学习了,数据也是可以训练的噢!
划分训练集和验证集:
from sklearn.model_selection import train_test_split
X_train,X_val,y_train,y_val=train_test_split(X,y,test_size=0.2,stratify=y,random_state=0)
将80%数据用于训练,20%数据进行验证,这也是机器学习的标准流程。
数据标准化:
# 导入StandardScaler类,该类用于特征缩放(将数据转换为均值为0,标准差为1的分布)
from sklearn.preprocessing import StandardScaler
# 创建一个StandardScaler对象,名为scaler
scaler = StandardScaler()
# 使用X_train数据集来“学习”数据的均值和标准差,这一步是为了后续对数据进行标准化
# fit方法会计算训练数据X_train的均值和标准差,并保存在scaler对象中
scaler.fit(X_train)
# 使用scaler对象中的均值和标准差来转换(标准化)X_train数据集
# transform方法会根据之前fit方法学习到的均值和标准差,将X_train中的数据转换为均值为0,标准差为1的数据
X_train_s = scaler.transform(X_train)
# 使用scaler对象(已经通过X_train的fit方法学习到了均值和标准差)来转换(标准化)X_val数据集
# 这意味着X_val将使用与X_train相同的均值和标准差进行标准化
X_val_s = scaler.transform(X_val)
# 使用scaler对象(已经通过X_train的fit方法学习到了均值和标准差)来转换(标准化)test数据集
# 通常,在实际应用中,我们可能没有test数据集的真实标签,但仍然需要对其进行与训练数据相同的预处理
# 这样可以确保模型在训练和测试时看到的数据具有相同的分布
test_s = scaler.transform(test)
构建自适应提升模型:先用一个简单的集成模型来验证一下精度。
# 自适应提升(Adaptive Boosting)
# AdaBoost 是一种集成学习方法,它通过组合多个弱分类器(通常是决策树桩)来创建一个强分类器。
# 它根据每个弱分类器的性能来分配权重,并在后续迭代中增加对之前错误分类样本的关注。
# 从 sklearn.ensemble 模块中导入 AdaBoostClassifier 类
from sklearn.ensemble import AdaBoostClassifier
# 创建一个 AdaBoostClassifier 对象,设置弱分类器的数量为 100,并指定一个随机种子(random_state)以确保结果的可复现性
model0 = AdaBoostClassifier(n_estimators=100, random_state=77)
# 使用训练数据(已经过标准化的 X_train_s)和对应的标签 y_train 来训练 AdaBoostClassifier 模型
model0.fit(X_train_s, y_train)
# 使用验证数据(已经过标准化的 X_val_s)和对应的标签 y_val 来评估模型的性能
# score 方法返回的是模型在验证集上的准确率
model0.score(X_val_s, y_val)
额外说明:
- n_estimators:这是 AdaBoostClassifier
中的一个重要参数,它指定了将要构建的弱分类器的数量。通常,增加这个值可以提高模型的性能,但也会增加计算成本。 - random_state:设置随机种子是为了确保结果的可复现性。当你多次运行相同的代码时,如果设置了随机种子,那么结果应该是相同的(除非其他部分的代码或数据发生了更改)。
- score 方法:对于分类任务,score
方法默认返回的是模型的准确率(accuracy)。然而,在某些情况下,准确率可能不是评估模型性能的最佳指标(例如,当类别不平衡时)。在这种情况下,你可能需要考虑使用其他指标,如精确度(precision)、召回率(recall)、F1
分数(F1-score)或 ROC AUC 分数等。 - 验证集:在上面的代码中,你使用了验证集(X_val_s,
y_val)来评估模型的性能。这是一个很好的做法,因为它可以帮助你了解模型在未见过的数据上的表现。然而,请注意,你最终可能还希望在一个独立的测试集上评估模型的性能,以确保你的模型对新数据的泛化能力。
运行的结果就是上图下面的一长串数字,用统计人的话来说预测准确率达到了79.9%。
模型运用——预测:
存储预测结果:准备存储预测结果表格。
df = pd.DataFrame(columns=['PassengerId','Survived'])
df['PassengerId']=ID
df.head()
上面表格第一列为乘客的唯一标识符,第二列为目标变量,暂时为空,用以存储预测结果,表示乘客是否在灾难中幸存下来(0 = 未生还,1 = 生还)。
# 使用已经训练好的 AdaBoost 模型(model0)对测试数据集(test_s)进行预测
# predict 方法会返回每个测试样本的预测类别(例如,在二分类问题中,通常是 0 或 1)
pred = model0.predict(test_s)
# 假设 df 是一个 pandas DataFrame,它包含了测试数据集中的原始特征和其他可能的列
# 我们现在想要将模型的预测结果(pred)添加到这个 DataFrame 中的一个新列 'Survived'
# 这通常是在数据预处理和特征工程阶段就已经准备好的 DataFrame,现在只是用于保存预测结果
df['Survived'] = pred
# 使用 pandas 的 to_csv 方法将修改后的 DataFrame(包含预测结果)保存为一个 CSV 文件
# 'predict_result__AdaBoost.csv' 是 CSV 文件的名称
# index=False 参数表示在保存文件时不包含 DataFrame 的索引
df.to_csv('predict_result__AdaBoost.csv', index=False)
几点额外的说明:
- pred:这个变量现在包含了 test_s 数据集中每个样本的预测结果。
- df:这个 DataFrame
应该是在数据预处理阶段就已经准备好的,它可能包含了测试数据的原始特征和其他信息。在这里,我们只是简单地将预测结果添加到这个
DataFrame 的一个新列 ‘Survived’ 中。 - ‘Survived’:这个列名通常用于表示二分类问题中的目标变量(尤其是当问题背景是生存分析时,如泰坦尼克号乘客生存预测)。但请注意,这里我们只是在 DataFrame 中添加了一个新列来保存预测结果,而不是说原始的 df 就一定有这个列。
- to_csv 方法:这个方法用于将 DataFrame 保存为 CSV 文件。index=False 参数确保在保存的文件中不包含
DataFrame 的索引列。 文件名 ‘predict_result__AdaBoost.csv’:这是你保存的 CSV
文件的名称,其中包含了 AdaBoost 模型的预测结果。你可以根据需要更改这个文件名。
对测试集上的数据预测,然后保存为csv文件,这里就不展示了,精彩在后面。
模型选择和优化:
模型选择:引入十种模型,测试验证集泛化精度最高的模型。
# 导入逻辑回归模型类。逻辑回归是一种用于分类问题的统计方法,它使用逻辑函数(sigmoid函数)将线性回归的输出转换为概率。
from sklearn.linear_model import LogisticRegression
# 导入线性判别分析模型类。线性判别分析(LDA)是一种经典的分类算法,它试图找到一个投影方向,使得类内差异最小而类间差异最大。
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
# 导入K近邻分类器。K近邻(KNN)是一种基本的分类和回归方法,其中输入由k个最接近的训练样本的多数投票决定。
from sklearn.neighbors import KNeighborsClassifier
# 导入决策树分类器。决策树是一种监督学习算法,用于分类和回归。它通过一系列的问题(决策节点)将数据集划分为更小的子集,直到每个子集只包含一个类别的实例。
from sklearn.tree import DecisionTreeClassifier
# 导入随机森林分类器。随机森林是一种集成学习方法,它构建多个决策树,并输出这些树分类结果的众数(对于分类任务)或平均值(对于回归任务)。
from sklearn.ensemble import RandomForestClassifier
# 导入梯度提升分类器。梯度提升是一种用于回归和分类问题的机器学习技术,它通过构建一系列的弱学习器(通常是决策树),并将它们组合成一个强学习器。
from sklearn.ensemble import GradientBoostingClassifier
# 导入XGBoost分类器。XGBoost是一种优化的分布式梯度提升库,旨在高效、灵活和便携。它实现了梯度提升框架,并支持多种目标函数,包括分类和回归。
from xgboost.sklearn import XGBClassifier
# 导入支持向量机分类器。支持向量机(SVM)是一种用于分类、回归和异常值检测的监督学习方法。它试图在特征空间中找到一个超平面,该超平面能够将实例划分为不同的类别。
from sklearn.svm import SVC
# 导入多层感知机分类器。多层感知机(MLP)是一种前馈人工神经网络模型,用于分类或回归。它由一个或多个全连接的层组成,每个层包含多个神经元。
from sklearn.neural_network import MLPClassifier
#逻辑回归
model1 = LogisticRegression(C=1e10)
#线性判别分析
model2 = LinearDiscriminantAnalysis()
#K近邻
model3 = KNeighborsClassifier(n_neighbors=10)
#决策树
model4 = DecisionTreeClassifier(random_state=77)
#随机森林
model5= RandomForestClassifier(n_estimators=1000, max_features='sqrt',random_state=10)
#梯度提升
model6 = GradientBoostingClassifier(random_state=123)
#极端梯度提升
model7 = XGBClassifier(eval_metric=['logloss','auc','error'],n_estimators=1000, colsample_bytree=0.8,learning_rate=0.1,random_state=77)
#支持向量机
model8 = SVC(kernel="rbf", random_state=77)
#神经网络
model9 = MLPClassifier(hidden_layer_sizes=(16,8), random_state=77, max_iter=10000)
model_list=[model1,model2,model3,model4,model5,model6,model7,model8,model9]
model_name=['逻辑回归','线性判别','K近邻','决策树','随机森林','梯度提升','极端梯度提升','支持向量机','神经网络']
打印每种模型的预测精度,并将预测结果存储至csv文件:
# 以下代码将遍历 model_list 中的每个模型,对其进行训练、评估,并对测试集进行预测
# 遍历从 0 到 8 的整数(总共 9 个),对应于 model_list 和 model_name 的索引
for i in range(9):
# 从 model_list 中取出当前索引 i 对应的模型对象
model_C = model_list[i]
# 从 model_name 中取出当前索引 i 对应的模型名称
name = model_name[i]
# 使用训练数据 X_train_s 和 y_train 来训练模型
model_C.fit(X_train_s, y_train)
# 使用验证数据 X_val_s 和 y_val 来评估模型的准确率
s = model_C.score(X_val_s, y_val)
# 打印出当前模型在验证集上的准确率
print(name + '方法在验证集的准确率为:' + str(s))
# 使用当前模型对测试集 test_s 进行预测
pred = model_C.predict(test_s)
# 假设 df 是一个 DataFrame,它用于存储预测结果,这里将当前模型的预测结果赋值给 'Survived' 列
# 注意:这里每次循环都会覆盖 'Survived' 列的值,可能这不是你想要的,如果你想保存每个模型的预测结果,需要调整这部分代码
df['Survived'] = pred
# 创建一个 CSV 文件名,包含模型名称和 "的预测结果.csv"
csv_name = name + '的预测结果.csv'
# 将包含预测结果的 DataFrame 保存到 CSV 文件中,不包括 DataFrame 的索引
df.to_csv(csv_name, index=False)
注意:
- 在上述代码中,df[‘Survived’] = pred 这行每次都会覆盖 df 中的 Survived 列,这意味着在循环结束时,df
中的 Survived
列将只包含最后一个模型的预测结果。如果你希望保存每个模型的预测结果,你需要考虑不同的策略,比如为每个模型创建一个新的 DataFrame
列或行,或者为每个模型保存一个独立的 DataFrame。 - model_list 和 model_name 需要在循环之前被定义并初始化,且它们的长度应该相同,均为 9。
- 变量 X_train_s, y_train, X_val_s, y_val, 和 test_s
也需要在循环之前被定义,它们分别是训练数据、训练标签、验证数据和验证标签,以及测试数据。 - 变量 df 需要在循环之前被定义为一个 pandas DataFrame,用于存储预测结果。如果 df 不包含除了 ‘Survived’
以外的其他列,那么在循环结束后,df 将只包含 ‘Survived’ 这一列,且值为最后一个模型的预测结果。如果 df
包含其他列,那么这些列将在每次循环中被保留,但 ‘Survived’ 列的值将被覆盖。
预测结果已经自动存入文件夹了,可以看到梯度提升模型泛化能力最强,预测精度达到了83.2%,这很强了吗?NO,机器学习数据越多预测越准,但永远不可能100%,具体为什么我也不清楚,只知道南京大学人工智能学院院长周志华老师讲过,如果预测精度达到100%,就会推翻概率的一个恒等式了。
模型优化:模型再继续优化就是调整超参数,这里利用K折交叉验证搜索最优超参数。
# 从 sklearn.model_selection 模块中导入 KFold 类
# KFold 是一种用于将数据集划分为 K 个(几乎)大小相等的互斥子集(或“折叠”)的交叉验证策略
# 这些子集是连续的,每个子集都作为一次独立的验证集,而剩余的 K-1 个子集则作为训练集
from sklearn.model_selection import KFold
# 从 sklearn.model_selection 模块中导入 StratifiedKFold 类
# StratifiedKFold 是 KFold 的一个变体,它确保在划分数据集时每个折叠中各类别的样本比例与原始数据集中的比例大致相同
# 这对于类别不平衡的数据集尤其有用,因为它有助于确保每个折叠都有代表性的样本分布
from sklearn.model_selection import StratifiedKFold
# 从 sklearn.model_selection 模块中导入 GridSearchCV 类
# GridSearchCV 是一个用于超参数优化的工具,它通过穷举搜索指定的参数值网格,来找出最优的参数组合
# 它使用交叉验证来评估每种参数组合的性能,并返回最佳参数和对应的评分
from sklearn.model_selection import GridSearchCV
# 定义一个参数分布字典,用于在GridSearchCV中进行随机搜索。这里我们设置了两个参数:
# 'max_depth':树的最大深度,其值在1到9之间(包含1和9)的整数范围内变化。
# 'learning_rate':学习率,其值在0.1到0.5之间平均分成5份,形成了一个浮点数序列。
param_distributions = {'max_depth': range(1, 10), 'learning_rate': np.linspace(0.1,0.5,5 )}
# 创建一个StratifiedKFold对象,用于在GridSearchCV中进行交叉验证。
# 'n_splits=10':将数据集分成10份进行交叉验证。
# 'shuffle=True':在划分数据前,先打乱数据集。
# 'random_state=1':设置随机种子,确保每次划分的结果都是相同的(可复现性)。
kfold = StratifiedKFold(n_splits=10, shuffle=True, random_state=1)
# 创建一个GridSearchCV对象,用于进行超参数搜索。
# 'estimator':使用的估计器或模型,这里是带有指定n_estimators和random_state的GradientBoostingClassifier。
# 'param_grid':这里应该使用'param_distributions'(对于RandomizedSearchCV),但这里用了'param_grid',
# 实际上应该改为'param_distributions'以进行随机搜索,而不是网格搜索。
# 'cv':交叉验证策略,这里使用了之前定义的StratifiedKFold对象。
# 注意:虽然变量名为'param_distributions',但在GridSearchCV中应使用'param_grid'(除非使用RandomizedSearchCV)。
model = GridSearchCV(estimator=GradientBoostingClassifier(n_estimators=300,random_state=123),
param_grid=param_distributions, cv=kfold)
# 使用训练集X_train_s和标签y_train来训练GridSearchCV对象,即进行超参数搜索和交叉验证。
model.fit(X_train_s, y_train)
model.best_params_
可以看到最优参数是0.1和3.
# 这行代码从GridSearchCV(或RandomizedSearchCV)对象中提取最佳估计器。
# GridSearchCV或RandomizedSearchCV在训练过程中会尝试多种参数组合,并找到在交叉验证中表现最好的那个。
# best_estimator_属性就是保存了那个最佳参数组合的估计器对象。
model = model.best_estimator_
# 这行代码使用上一步得到的最佳估计器对象(即最佳参数组合的模型)在验证集X_val_s上进行预测,
# 并计算预测的标签与真实的标签y_val之间的评分(通常是准确率,但取决于估计器对象所定义的score方法)。
# 这个评分给出了模型在未见过的数据(验证集)上的性能度量。
model.score(X_val_s, y_val)
通过调整超参数,模型精度达到了84.3%,比之前提升了1.1%。
# 使用之前从GridSearchCV或RandomizedSearchCV中提取的最佳估计器(模型)对测试集test_s进行预测。
# predict方法会返回测试集中每个样本的预测结果,这些结果通常是一个标签数组或概率数组(取决于模型是分类器还是回归器)。
pred = model.predict(test_s)
# 将预测结果pred赋值给DataFrame df的一个新列'Survived'。
# 假设df是已经存在的一个DataFrame,且它的行数应该与pred的长度相同,以便能够正确地将预测结果赋值给每一行。
df['Survived']=pred
# 将更新后的df DataFrame保存到CSV文件中,文件名为'调参后的梯度提升预测结果.csv'。
# index=False参数指定在保存时不包括DataFrame的索引列。
df.to_csv('调参后的梯度提升预测结果.csv',index=False)
上图就是最终调参后的预测结果,重要的事情说三遍!!!
Survived:这是目标变量,表示乘客是否在灾难中幸存下来(0 = 未生还,1 = 生还)。
Survived:这是目标变量,表示乘客是否在灾难中幸存下来(0 = 未生还,1 = 生还)。
Survived:这是目标变量,表示乘客是否在灾难中幸存下来(0 = 未生还,1 = 生还)。
模型评价:
我们可以进一步看看是哪个特征对于是否存活的预测起到的重要作用。
绘制特征变量的重要性排序图:
# 获取特征重要性的数组,并使用argsort()方法获取这些重要性值的索引,按照从小到大的顺序排列。
# 这样,sorted_index数组中的最小索引对应最不重要的特征,最大索引对应最重要的特征。
sorted_index = model.feature_importances_.argsort()
# 使用matplotlib的plt.barh()函数绘制水平条形图。
# range(X.shape[1])生成一个从0到特征数量减1的整数序列,作为y轴的位置(即每个特征的索引)。
# model.feature_importances_[sorted_index]是特征重要性值数组,但已经按照sorted_index重新排序。
plt.barh(range(X.shape[1]), model.feature_importances_[sorted_index])
# 设置y轴刻度标签。np.arange(X.shape[1])生成与特征数量相同的整数序列,
# X.columns[sorted_index]则是根据sorted_index重新排序的特征名称。
# 这意味着y轴上的每个刻度标签都对应一个特征名称,按照特征重要性从低到高排列。
plt.yticks(np.arange(X.shape[1]), X.columns[sorted_index])
# 设置x轴的标签,这里标签是'Feature Importance',表示特征的重要性。
plt.xlabel('Feature Importance')
# 设置y轴的标签,这里标签是'Feature',表示特征的名称。
plt.ylabel('Feature')
# 设置图表的标题为'Gradient Boosting',表示这是梯度提升模型的特征重要性图。
plt.title('Gradient Boosting')
从上图可以看出性别对于是否存活起到了重要的作用。
# 使用之前从GridSearchCV或RandomizedSearchCV中提取的最佳估计器(模型)对验证集X_val_s进行预测。
# predict方法会返回验证集中每个样本的预测结果,这些结果通常是一个标签数组或概率数组(取决于模型是分类器还是回归器)。
# 在这里,我们假设model是一个分类器,因此pred将包含预测的类别标签。
pred = model.predict(X_val_s)
# 使用pandas的crosstab函数创建一个交叉表(contingency table),该表显示了实际标签(y_val)与预测标签(pred)之间的关系。
# crosstab函数计算了两个或多个分类变量的频率表。
# rownames=['Actual']设置交叉表的行名为'Actual',表示实际的类别标签。
# colnames=['Predicted']设置交叉表的列名为'Predicted',表示预测的类别标签。
# 生成的交叉表table将显示每个实际类别中有多少样本被预测为各个类别。
table = pd.crosstab(y_val, pred, rownames=['Actual'], colnames=['Predicted'])
# 注释'table'本身并没有执行任何代码,但它是一个标记,表示接下来的内容是对变量table的解释或说明。
# 在这里,它可能表示“这是交叉表table的注释或说明”。
table
AUC画图:
# 从 sklearn.metrics 模块下的 plot 子模块中导入 plot_roc_curve 函数
# 这个函数用于绘制接收者操作特征曲线(ROC Curve)
from sklearn.metrics import plot_roc_curve
# 调用 plot_roc_curve 函数,绘制模型的 ROC 曲线
# model 是已经训练好的分类器模型
# X_val_s 是验证集的特征数据
# y_val 是验证集的标签数据
# plot_roc_curve 函数会返回一个 Display 对象,其中包含绘制的图形元素
plot_roc_curve(model, X_val_s, y_val)
# 使用 numpy 的 linspace 函数生成一个从 0 到 1 的等差数列,共 100 个点
# 这个数列将用于绘制对角线(表示随机猜测的 ROC 曲线)
x = np.linspace(0, 1, 100)
# 使用 matplotlib 的 pyplot 模块中的 plot 函数绘制对角线
# 'k--' 表示使用黑色虚线绘制
# linewidth=1 表示线宽为 1
# 这条线表示随机猜测的性能,即真正率(TPR)和假正率(FPR)相等的情况
plt.plot(x, x, 'k--', linewidth=1)
# 注意:这里并没有显示图形,通常需要添加 plt.show() 来显示图形
# 但如果这段代码是在 Jupyter Notebook 或其他交互式环境中运行的,图形可能会自动显示
模型为0.85,最高为1,及格了吧!
再给大家科谱一下怎样看AUC图吧。
AUC图,即ROC曲线下的面积图(Receiver Operating Characteristic curve and Area Under the Curve),是一种用于二分类模型性能评估的图形表示方法。AUC值衡量的是分类器在所有可能的阈值下,区分正例和负例的能力。下面是阅读和理解AUC图的关键点:
- ROC曲线的构成
横轴(False Positive Rate, FPR,假正率):表示模型预测为正例但实际上为负例的比例。FPR越高,意味着越多的负例被错误地分类为正例。
纵轴(True Positive Rate, TPR,真正率):表示模型预测为正例且实际上也是正例的比例。TPR越高,说明模型识别正例的能力越强。 - 曲线绘制
ROC曲线是通过改变分类器的决策阈值,绘制出TPR与FPR的一系列点,然后将这些点连接起来形成的。阈值从最严格(所有样本都被预测为负例)逐渐放松到最宽松(所有样本都被预测为正例)。 - 完美分类器的表现
理想情况下,完美的分类器会在左上角开始,直接上升至(0,1)点,这意味着在不产生任何假正例的情况下识别出所有正例,对应的AUC值为1。 - 随机分类器的表现
如果模型的预测完全是随机的,那么它的ROC曲线会贴近对角线(FPR = TPR),此时AUC值为0.5。 - AUC值解读
AUC接近1:表明模型在各种阈值下都能很好地区分正负例,分类性能优秀。
AUC约0.5:意味着模型的预测能力与随机猜测无异,没有区分力。
AUC介于0.5和1之间:AUC值越大,模型的区分能力越强。 - 实际应用
在AUC图上,通常还会看到一条斜率为1的对角线,作为随机分类的参考线。模型的ROC曲线位于这条线之上且越远离对角线,表示其性能越好。
通过观察ROC曲线的形状,还可以大致判断模型是否存在特定的偏置问题,比如曲线初期陡峭后期平缓可能意味着模型在高真正率区间表现较好,但随着FPR增加,提升真正率的效率降低。
总之,AUC图和AUC值是评价分类模型性能的重要工具,特别是在处理类别不平衡数据时,能够提供比单一准确率更全面的性能评估。
**创作不易,点赞、收藏、转发三连走起! **