【sklearn】2.分类决策树实践——Titanic数据集

2022-06-14 11:53:36 浏览数 (1)

在上一篇【sklearn】1.分类决策树学习了sklearn决策树的一些接口后,现在利用kaggle上泰坦尼克号的数据集进行实践。

数据集获取

在Kaggle上下载Tictanic数据集 下载地址:https://www.kaggle.com/c/titanic/data

数据集中有三个文件,一个是训练集,一个是测试集,还有一个是提交的答案范例。 本次仅使用训练集。

sklearn实战

导入库

代码语言:javascript复制
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import train_test_split, cross_val_score
import numpy as np

读取数据

代码语言:javascript复制
data = pd.read_csv("titanic/train.csv")
# print(data.info())  # 查看大致信息
# print(data.head(5))  # 查看前5条数据

数据预处理

代码语言:javascript复制
# 筛选特征
data.drop(['Cabin', 'Name', 'Ticket'], inplace=True, axis=1)  # inplace覆盖原表,axis=1删除列,axis=0删除行
# 填补缺失值
data['Age'] = data['Age'].fillna(data['Age'].mean())
# 删掉含有缺失值的行
data = data.dropna()  # 默认axis=0
# 将[Embarked]的文字部分替换成0,1,2(有三类)
labels = data["Embarked"].unique().tolist()
data["Embarked"] = data["Embarked"].apply(lambda x: labels.index(x))
# 性别转换将male和female转换成1和0
data["Sex"] = (data['Sex'] == 'male').astype('int')  # 小技巧:通过条件判断强制转换为int

通过预处理,将不重要的特征进行删除,对年龄的缺失行以平均年龄进行填补,对文字数据集进行了数字转换。

样本选取

代码语言:javascript复制
# 取出 x 和 y 因变量为Survived
x = data.iloc[:, data.columns != "Survived"]
y = data.iloc[:, data.columns == "Survived"]

Xtrain, Xtest, Ytrain, Ytest = train_test_split(x, y, test_size=0.3)

# 随机取出数据,索引会变化,下面重新纠正索引
for i in [Xtrain, Xtest, Ytrain, Ytest]:
    i.index = range(i.shape[0])

决策树构建

代码语言:javascript复制
# 使用决策分类树
clf = DecisionTreeClassifier(random_state=25)
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)

print(score)

打印出准确率,发现只有76%,下面进行调参。

对最大深度调参

代码语言:javascript复制
# 准确率只有76%,对最大深度调参
tr = []
te = []
for i in range(10):
    clf = DecisionTreeClassifier(random_state=25
                                 , max_depth=i   1
                                 , criterion="entropy"
                                 )
    clf = clf.fit(Xtrain, Ytrain)
    score_tr = clf.score(Xtrain, Ytrain)
    score_te = cross_val_score(clf, x, y, cv=10).mean()  # 交叉验证取均值作测试
    tr.append(score_tr)
    te.append(score_te)
print(max(te))
plt.plot(range(1, 11), tr, color="red", label="train")
plt.plot(range(1, 11), te, color="blue", label="test")
plt.xticks(range(1, 11))  # 限制x轴显示范围
plt.legend()  # 显示图例
plt.show()

上面的图说明,最大深度很大时,用于交叉验证的test准确率低,train准确率高,产生过拟合现象。 为了减小过拟合,在图中可以发现,最大深度取3最合适。

网格调参

上面仅仅是对最大深度进行了调参,还有很多参数需要进行调节,一个个去调节显然是困难的。 因此,这里采用了一种网格调参的方法。 通俗理解,所有的参数枚举出来,形成了一个个网格,每个网格试过去,直到找到最好的。

代码语言:javascript复制
# 最好的max的准确度也仅为81.6%,下面使用网格搜索调参
gini_thresholds = np.linspace(0, 0.5, 20)  # 20个0到0.5的等差数列
# 设定参数范围
parameters = {"criterion": ("gini", "entropy")
            , "splitter": ("best", "random")
            , "max_depth": [*range(1, 10)]
            , "min_samples_leaf": [*range(1, 50, 5)]
            , "min_impurity_decrease": [*np.linspace(0, 0.5, 20)]
              }
clf = DecisionTreeClassifier(random_state=25)
GS = GridSearchCV(clf, parameters, cv=10)
GS = GS.fit(Xtrain, Ytrain)

#返回最佳组合
print(GS.best_params_)
#返回最佳准确率
print(GS.best_score_)

注:网格调参非常耗时,这段代码跑了10分钟。

最佳组合: {‘criterion’: ‘entropy’, ‘max_depth’: 3, ‘min_impurity_decrease’: 0.0, ‘min_samples_leaf’: 1, ‘splitter’: ‘best’}

最佳准确率:82.3%

总结

即使经过调参,准确率依旧提升不多,说明决策树对该数据集的效果并不理想。 若要准确进行预测,需要更换其它模型。

参考资料

【2020机器学习全集】菜菜的sklearn完整版

0 人点赞