(1) 决策树案例:泰坦尼克号幸存者的预测

1、导库

import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt

2、加载数据,探索数据

data = pd.read_csv('./data.csv')
data.head()
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
 #   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  
 0   PassengerId  891 non-null    int64  
 1   Survived     891 non-null    int64  
 2   Pclass       891 non-null    int64  
 3   Name         891 non-null    object 
 4   Sex          891 non-null    object 
 5   Age          714 non-null    float64
 6   SibSp        891 non-null    int64  
 7   Parch        891 non-null    int64  
 8   Ticket       891 non-null    object 
 9   Fare         891 non-null    float64
 10  Cabin        204 non-null    object 
 11  Embarked     889 non-null    object 
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB

3、数据预处理

#删除缺失值过多的列,和观察判断来说和预测的y没有关系的列
data.drop(["PassengerId", "Cabin", "Name", "Ticket"], inplace=True, axis=1)
#处理缺失值,对缺失值较多的列进行填补,有一些特征只确实一两个值,可以采取直接删除记录的方法
data["Age"] = data["Age"].fillna(data["Age"].mean())
data = data.dropna()
#将分类变量转换为数值型变量

#将二分类变量转换为数值型变量
#astype能够将一个pandas对象转换为某种类型,和apply(int(x))不同,astype可以将文本类转换为数字,用这个方式可以很便捷地将二分类特征转换为0~1
data["Sex"] = (data["Sex"] == "male").astype("int")
#将三分类变量转换为数值型变量 apply() 函数可以直接对 Series 或者 DataFrame 中元素进行逐元素遍历操作
labels = data["Embarked"].unique().tolist()
data["Embarked"] = data["Embarked"].apply(lambda x: labels.index(x))
# 查看处理后的数据集
data.head()
SurvivedPclassSexAgeSibSpParchFareEmbarked
003122.0107.25000
111038.01071.28331
213026.0007.92500
311035.01053.10000
403135.0008.05000

4、提取标签和特征矩阵,分测试集和训练集

y = data["Survived"]
X = data.drop("Survived", axis=1)
Xtrain, Xtest, Ytrain, Ytest = train_test_split(X, y, test_size=0.3)
Xtrain.head()  # 索引乱了
PclassSexAgeSibSpParchFareEmbarked
5512127.0000000026.00000
1681129.6991180025.92500
297102.00000012151.55000
5903135.000000007.12500
3321138.00000001153.46250
#修正测试集和训练集的索引
for i in [Xtrain, Xtest, Ytrain, Ytest]:
    i.index = range(i.shape[0])
Xtrain.head()
PclassSexAgeSibSpParchFareEmbarked
02127.0000000026.00000
11129.6991180025.92500
2102.00000012151.55000
33135.000000007.12500
41138.00000001153.46250

5、导入模型,粗略跑一下查看结果

clf = DecisionTreeClassifier(random_state=20)
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)
score
0.7752808988764045
# 使用交叉验证看下
clf = DecisionTreeClassifier(random_state=20)
score = cross_val_score(clf, X, y, cv=10).mean()
score
0.7784473953013279

6、在不同max_depth下观察模型的拟合状况

tr = []
te = []
for i in range(10):
    clf = DecisionTreeClassifier(random_state=20
                                 , 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))
plt.legend()
plt.show()
#这里为什么使用“entropy”?
#因为我们注意到,在最大深度=3的时候,模型拟合不足,在训练集和测试集上的表现接近,但却都不是非常理想,只能够达到82%左右,所以我们要使用entropy
#其实就两个参数,都试一下
0.8200331971399386

7、用网格搜索调整参数

# 网格搜索的一串参数
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=20)
GS = GridSearchCV(clf, parameters, cv=10)
GS.fit(Xtrain, Ytrain)
GS.best_params_  # 网格搜索后的最佳参数
{'criterion': 'gini',
 'max_depth': 7,
 'min_impurity_decrease': 0.0,
 'min_samples_leaf': 6,
 'splitter': 'best'}
GS.best_score_  # 结果还不如第六步,我晕
0.8167434715821813

文章参考于该up主:https://space.bilibili.com/2932207

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值