赞
踩
随着2018年飞逝而过,2019悄然到来,我并没有什么太大的起伏去迎接新年,从上一篇博文截止到今天,好像是有接近一礼拜没有更文了,主要是最近正在参加一个建模比赛,导致原计划这两天要写的年终总结一推再推,另外还顺便报了个集训营,那么年终总结。。。So,不如来更新一篇kaggle小项目吧,趁现在还有时间,建模那边已经快到结尾了,年终总结等博客真正搭好的时候作为第一篇好了。虽然最近也并不是很想处理博客,wordpress看花了眼。。。
作为当前机器学习最出名的几个入门kaggle项目,背景就无需多做介绍了。本次泰坦尼克号实验总结了实验楼以及相应的几个博客案例,主要侧重于对随机森林的描述,然后加上自己的一些理解,文底表明文章出处,数据出处如下:
https://www.kaggle.com/c/titanic/data
当下载好数据之后,因为数据集并不大,我便直接用excel打开然后观察数据特征以及背景了,数据标签含义如下:
特征label | 解释说明 |
---|---|
PassengerId | 整型变量,标识乘客的ID,递增变量,对预测无帮助 |
Survived | 整型变量,标识该乘客是否幸存。0表示遇难,1表示幸存。将其转换为factor变量比较方便处理 |
Pclass | 整型变量,标识乘客的社会-经济状态,1代表Upper,2代表Middle,3代表Lower |
Name | 字符型变量,除包含姓和名以外,还包含Mr. Mrs. Dr.这样的具有西方文化特点的信息 |
Sex | 字符型变量,标识乘客性别,适合转换为factor类型变量 |
Age | 整型变量,标识乘客年龄,有缺失值 |
SibSp | 整型变量,代表兄弟姐妹及配偶的个数。其中Sib代表Sibling也即兄弟姐妹,Sp代表Spouse也即配偶 |
Parch | 整型变量,代表父母或子女的个数。其中Par代表Parent也即父母,Ch代表Child也即子女 |
Ticket | 字符型变量,代表乘客的船票号 |
Fare | 数值型,代表乘客的船票价 |
Cabin | 字符型,代表乘客所在的舱位,有缺失值 |
Embarked | 字符型,代表乘客登船口岸,适合转换为factor型变量 |
从这里,我们大致了解了关于这份数据的存在形式,于是我们便可以进行python的使用与分析了,在此之前,导入基本我们需要使用的第三方库与数据:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
train = pd.read_csv(r"C:\Users\xuzhenggen\Desktop\files\train.csv")
test = pd.read_csv(r"C:\Users\xuzhenggen\Desktop\files\test.csv")
当我们导入数据后,往往并不是直接做数据建模,还有太多的数据处理方面的问题等着我们,只有对数据的认识越深,那么后面的特征工程的构建也就越轻松。那么问题就来了,这份数据到底应该怎么处理呢?
我们首先可以看一下在python中数据的表现形式是否和之前在excel中的形式一致,出于运行单元速度以及效率来考虑,考虑用head,代码如下:
train.head() # head参数默认是5个
test.head()
- | PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. OwenHarris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
- | PassengerId | Pclass | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 892 | 3 | 3 | Kelly, Mr. James | male | 34.5 | 0 | 0 | 330911 | 7.8292 | NaN | Q |
由于篇幅考虑,显示一行。我们可以看到大体和我们想的一样,那么我们再来检查一下变量类型:
train.info()
test.info()
看到了数据的变量类型,和上述表格中预想的一致,那么我们便可以针对每个特征的数据结构给它们归一归类了,这也同样有益于我们加深理解数据,除了使后面的计算更方便,更能帮助我们选择合适的图形做可视化,我们可以进一步进行如下分析:
对于连续型和离散型特征具体区别,可以看如下链接:
然后我们就可以查看训练数据的具体分布情况:
#通过使用 percentile=[.1, .2, .3, .4, .5, .6, .7, .8, .9, .99] 来查看分布
train.describe(percentiles=[.1, .2, .3, .4, .5, .6, .7, .8, .9, .99])
我们可以从上表知道:
大概可以很明确的就如上几点,可能有人还会说Age数量为啥与其它的少?这个问题就是我们如下需要分析的了:
我们可以统计一下缺失值到底有多少:
data.isnull().sum() #查看 null 值,查看非空使用 notnull()
总共有 891 个游客的数据,177 个 Age 缺失,687 个 Cabin 缺失,2 个 Embarked 缺失。在后面我们需要用不同的方法补充这些数据。
然后,我们查看特征类别分布是否平衡。类别平衡指分类样例不同类别的训练样例数目差别不大。当差别很大时,为类别不平衡。当类别不平衡的时候,例如正反比为 9:1,学习器将所有样本判别为正例的正确率都能达到 0.9。这时候,我们就需要使用 “再缩放”、“欠采样”、“过采样”、“阈值移动” 等方法。我们可以对Survice做图验证:
sns.countplot(x='Survived',data=train) #对不同值的 'Survived' 进行计数并绘图
这个结果说明样本比例还算均衡,也同样应征了上表中说明的幸存者在30%~40%之间,而这组数据本身就少,差距变化不大,我们可以认为是属于类别平衡问题。
接下来,删除无用的特征 PassengerId, Name。
train.drop(['PassengerId','Name'],axis=1,inplace=True) #删除 train['PassengerId','Name'] 两列数据,axis=1 表示删除列,axis=0 表示删除行,inplace=True 原位删除
train.columns
"""
Index(['Survived', 'Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Ticket', 'Fare',
'Cabin', 'Embarked'],
dtype='object')
"""
名字在这里对我来讲并不是很想分析,看了一篇大佬对名字的分析,从分离出他们之间的姓氏,以及名字长度,去推测他们的社会地位,然后再看看是否与存活相关,虽然最后得出来的结果是有点相关性,但我感觉关联并不是很大,太复杂了,一般我是直接删除,删除不了,降维也会把它降掉。
g=sns.heatmap(train[['Survived','SibSp','Parch','Age','Fare','Pclass']].corr(),cmap='RdYlGn',annot=True) #corr() 计算相关系数,cmap 选择 color map,annot=True 显示相关系数
这里我们可以做一个相关系数矩阵图,从理论上来讲,相关系数越大,那么相关系数就越强,这里Fare的颜色较深,相关性较大,其它次之。
缺失值处理:
缺失值有很多种处理方式,从直接剔除,到取平均值、中位数、众数,到线性回归,拉格朗日插值、三次样条插值、极大似然估计、KNN等等,这些都需要视具体情况具体分析,想起上午刚打完的一个建模比赛,通过spss用了KNN和上下四个数取平均,spss自从集成了python环境还是挺好用的,有时间我也可以写一些自己的理解。
上述列举了这么多的方法,那么它们都是什么情况下使用的呢?
当然以上仅仅是一些我的理解,还是那句话,具体情况具体分析,另外本题没有采取什么缺失值的技巧,运用的是平均值方式去补充,我们首先观察年龄对存活率的变化情况:
Age0=train[(train['Survived']==0)&(train['Age'].notnull())]['Age'] #死亡乘客的 Age 数据
Age1=train[(train['Survived']==1)&(train['Age'].notnull())]['Age'] #生存乘客的 Age 数据
g=sns.kdeplot(Age0,legend=True,shade=True,color='r',label='NotSurvived') #死亡乘客年龄概率分布图, shade=True 设置阴影
g=sns.kdeplot(Age1,legend=True,shade=True,color='b',label='Survived') #生存乘客概率分布图
在前面,我们根据 heatmap构造的相关系数图中,Age 和 SibSp, Parch,Pclass 相关性高,我们再用箱型图直观感受下,以图形 Sex ~ Age,Pclass ~ Age 为例。
g=sns.factorplot(x='Sex',y='Age',data=train,kind='box')
g=sns.factorplot(x='Pclass',y='Age',data=train,kind='box')
上面两图说明男性和女性的年龄分布(指箱型图中的五条线,从上到下依次是最大值、四分位数、中位数、四分位数、最小值)基本一致,而购买不同等级票的人的年龄分布是不同的。所以,我们根据票的等级将数据分为不同的集合,再用缺失数据所在集合的平均值来进行填充,并检查填充后 Age ~ Survived 是否受到影响。
index = list(train[train['Age'].isnull()].index) #Age 缺失样例的 index
Age_mean = np.mean(train[train['Age'].notnull()]['Age']) #求平均值
copy_data = train.copy()
for i in index:
filling_age = np.mean(copy_data[(copy_data['Pclass'] == copy_data.iloc[i]['Pclass'])
& (copy_data['SibSp'] == copy_data.iloc[i]['SibSp'])
& (copy_data['Parch'] == copy_data.iloc[i]['Parch'])
]['Age'])
if not np.isnan(filling_age): # filling_age 非空为真
train['Age'].iloc[i] = filling_age #填充 null 值
else: # filling_age 空为真
train['Age'].iloc[i] = Age_mean
g = sns.kdeplot(Age0, legend=True, shade=True, color='r', label='NotSurvived')
g = sns.kdeplot(Age1, legend=True, shade=True, color='b', label='Survived')
结果是基本与原数据一致,那么初步来看,是可以这样做的。
然后我们可以来处理关于cabin这个缺失项,这个不同于age,cabin可以看做是离散的缺失值,我们可以分析一下这个样本:
train[train['Cabin'].notnull()]['Cabin'].head(10)
"""
1 C85
3 C123
6 E46
10 G6
11 C103
21 D56
23 A6
27 C23 C25 C27
31 B78
52 D33
Name: Cabin, dtype: object
"""
然后我们可以将缺失值取做新变量名,比如说“U”:
# fillna() 填充 null 值
train['Cabin'].fillna('U',inplace=True)
# 使用 lambda 表达式定义匿名函数对 i 执行 list(i)[0]。map() 指对指定序列 data ['Cabin'] 进行映射,对每个元素执行 lambda
train['Cabin']=train['Cabin'].map(lambda i: list(i)[0])
# kind='bar' 绘制条形图,ci=False 不绘制概率曲线,order 设置横坐标次序
g = sns.factorplot(x='Cabin',y='Survived',data=train,ci=False,kind='bar',order=['A','B','C','D','E','F','G','U'])
这样看上去就比较合理了。
另外关于Embarked特征主要有三个值,分别为S,Q,C,对应了三个登船港口。在训练集里,这个有2个缺失值,我们会使用频率最高的值来填充这个缺失值,填补为S,做法和上面的cabin类似。
异常值处理:
对于异常值的处理,方法也是多样的,可以设置一个初始阈值,超过那么就算做是异常,这也并没有什么问题,还有就是分布问题,同样会产生异常。在测绘里面,我记得有一种异常处理方式叫做sigma原则,即
3
σ
3\sigma
3σ原则,
σ
\sigma
σ为:
σ
=
∑
i
=
1
n
(
x
i
−
x
ˉ
)
2
n
−
1
\sigma = \sqrt{\frac{\sum_{i=1}^{n}(x_{i}-\bar{x})^{2}}{n-1}}
σ=n−1∑i=1n(xi−xˉ)2
缺失值为:
∣
x
i
−
x
ˉ
∣
>
3
σ
|x_{i}-\bar{x}|> 3\sigma
∣xi−xˉ∣>3σ
而另一种就是关于数据分布问题了,比如说这里的Fare,我们可以看到它的分布情况:
g=sns.kdeplot(train[train['Survived']==0]['Fare'],shade='True',label='NotSurvived',color='r') # 死亡乘客 'Fare' 分布
g=sns.kdeplot(train[train['Survived']==1]['Fare'],shade='True',label='Survived',color='b') # 生存乘客 'Fare' 分布
可以看到Fare存在明显的集中情况,但并不是标准正态分布,可以看做是偏态分布,或者说叫长尾分布,这里可以举一个很形象的例子:世界上人口这么多,但真正能站在巅峰的也就那么百分之几,而大部分人都是集中在一个很狭小的范围内波动起伏。
(需要翻墙)
Skewed Distribution and Log Transformation
Fare 属于右偏态分布,Python 提供了计算数据偏态系数的函数 skew(), 计算值越大,数据偏态越明显。使用 Log Transformation 后,我们看到计算值从 4.79 降到 0.44。
train['Fare']=train['Fare'].map(lambda i:np.log(i) if i>0 else 0) # 匿名函数为对非零数据进行 Log Transformation,否则保持零值
g=sns.distplot(train['Fare'])
print('Skew Coefficient:%.2f' %(train['Fare'].skew())) # skew() 计算偏态系数
对于性别,我们可以对其重新进行01编码,因为只有男性和女性:
train['Sex'].replace('male',0,inplace=True)#inplace=True 原位替换
train['Sex'].replace('female',1,inplace=True)
然后我们可以从上面的箱型图观察,其实还是有异常值的,可以考虑按照sigma原则排除,不过这种我只在spss里试过,这里还是按照箱型图的定义来,针对于 [‘Age’, ‘Parch’, ‘SibSp’, ‘Fare’] :
from collections import Counter def outlier_detect(n, df, features):#定义函数 outlier_detect 探测离群点,输入变量 n, df, features,返回 outlier outlier_index = [] for feature in features: Q1 = np.percentile(df[feature], 25)#计算上四分位数(1/4) Q3 = np.percentile(df[feature], 75)#计算下四分位数(3/4) IQR = Q3 - Q1 outlier_span = 1.5 * IQR col = ((train[train[feature] > Q3 + outlier_span]) | (train[train[feature] < Q1 - outlier_span])).index outlier_index.extend(col) print('%s: %f (Q3+1.5*IQR) , %f (Q1-1.5*QIR) )' % (feature, Q3 + outlier_span, Q1 - outlier_span)) outlier_index = Counter(outlier_index)#计数 outlier = list(i for i, j in outlier_index.items() if j >= n) print('number of outliers: %d' % len(outlier)) print(df[['Age', 'Parch', 'SibSp', 'Fare']].loc[outlier]) return outlier outlier = outlier_detect(3, train, ['Age', 'Parch', 'SibSp', 'Fare'])#调用函数 outlier_detect """ 异常值总共有四个 Age: 59.500000 (Q3+1.5*IQR) , -0.500000 (Q1-1.5*QIR) ) Parch: 0.000000 (Q3+1.5*IQR) , 0.000000 (Q1-1.5*QIR) ) SibSp: 2.500000 (Q3+1.5*IQR) , -1.500000 (Q1-1.5*QIR) ) Fare: 1.994305 (Q3+1.5*IQR) , -0.033916 (Q1-1.5*QIR) ) number of outliers: 0 Empty DataFrame Columns: [Age, Parch, SibSp, Fare] Index: [] """
然后删除上述四个值就行啦。
Ticket 特征值中的一串数字编号对我们没有意义,下面代码中,我们用正则表达式过滤掉这串数字,并使用 pandas的get_dummies 函数进行数值化(以 Ticket 特征值 作为新的特征,0,1 作为新的特征值),类似于onehot编码性质的方法。
Ticket=[]
import re
r=re.compile(r'\w*')#正则表达式,查找所有单词字符[a-z/A-Z/0-9]
for i in train['Ticket']:
sp=i.split(' ')#拆分空格前后字符串,返回列表
if len(sp)==1:
Ticket.append('U')#对于只有一串数字的 Ticket,Ticket 增加字符 'U'
else:
t=r.findall(sp[0])#查找所有单词字符,忽略符号,返回列表
Ticket.append(''.join(t))#将 t 中所有字符串合并
train['Ticket']=Ticket
train=pd.get_dummies(train,columns=['Ticket'],prefix='T')#get_dummies:如果DataFrame的某一列中含有k个不同的值,则可以派生出一个k列矩阵或DataFrame(其值全为1和0)
这里一定需要注意的是,Ticket样本可以直接删除,也可以这样分隔,但一定不能不处理,否则后面的模型构建时会有错误,比如这个:
Python: Cannot Convert String to Float
上面是kaggle上的一个讨论,可能中间还会有一些其它小错误,但基本都和数据清洗处理不当有关,比如说上面的错误就是因为ticket样本依然包括空格,但一般用get_dummies基本没有。那么到此为止,数据清洗的工作就做完啦。
关于随机森林的构建,如果运用sklearn包的话,其实很简单,重点其实是需要搞清楚评估方法,比如说交叉验证:
留出法和 k 折交叉验证法需要划分一部分样本作为测试集,就引入由于训练样本规模不同而产生的偏差。留一法改善了这一问题,但计算复杂度高。自助法也改善了这一个问题,但改变了数据集分布,同样会引入偏差,该方法适合数据集较小的情况。所以,留出法和 k 折交叉验证法是最常用的。这里选择 k 折交叉验证法进行模型评估。
Python sklearn.model_selection 提供了 Stratified k-fold。参考 Stratified k-fold
我推荐使用 sklearn cross_val_score。这个函数输入我们选择的算法、数据集 D,k 的值,输出训练精度(误差是错误率,精度是正确率)。对于分类问题,默认采用 stratified k-fold 方法。参考 sklearn cross_val_score
下面我们用 10 折交叉验证法(k=10)对两种常用的集成学习算法 AdaBoost 以及 Random Forest 进行评估。最后我们看到 Random Forest 比 Adaboost 效果更好。
from sklearn.ensemble import AdaBoostClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score y = train['Survived'] X = train.drop(['Survived'], axis=1).values classifiers = [AdaBoostClassifier( random_state=2), RandomForestClassifier(random_state=2)] for clf in classifiers: score = cross_val_score(clf, X, y, cv=10, scoring='accuracy')#cv=10:10 折交叉验证法,scoring='accuracy':返回测试精度 print([np.mean(score)])#显示测试精度平均值 """ [0.7353336738168198] [0.8047636477130858] """
过拟合是学习器性能过好,把样本的一些特性当做了数据的一般性质,从而导致训练误差低但泛化误差高。学习曲线是判断过拟合的一种方式,同时可以判断学习器的表现。学习曲线包括训练误差(或精度)随样例数目的变化曲线与测试误差(或精度)随样例数目的变化曲线。
下面将以训练样例数目为横坐标,训练精度和测试精度为纵坐标绘制学习曲线,并分析 Random Forest 算法的性能。
from sklearn.model_selection import learning_curve import matplotlib.pyplot as plt # 定义函数 plot_learning_curve 绘制学习曲线。train_sizes 初始化为 array([ 0.1 , 0.325, 0.55 , 0.775, 1\. ]),cv 初始化为 10,以后调用函数时不再输入这两个变量 def plot_learning_curve(estimator, title, X, y, cv=10, train_sizes=np.linspace(.1, 1.0, 5)): plt.figure() plt.title(title) # 设置图的 title plt.xlabel('Training examples') # 横坐标 plt.ylabel('Score') # 纵坐标 train_sizes, train_scores, test_scores = learning_curve(estimator, X, y, cv=cv, train_sizes=train_sizes) train_scores_mean = np.mean(train_scores, axis=1) # 计算平均值 train_scores_std = np.std(train_scores, axis=1) # 计算标准差 test_scores_mean = np.mean(test_scores, axis=1) test_scores_std = np.std(test_scores, axis=1) plt.grid() # 设置背景的网格 plt.fill_between(train_sizes, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std, alpha=0.1, color='g') # 设置颜色 plt.fill_between(train_sizes, test_scores_mean - test_scores_std, test_scores_mean + test_scores_std, alpha=0.1, color='r') plt.plot(train_sizes, train_scores_mean, 'o-', color='g', label='traning score') # 绘制训练精度曲线 plt.plot(train_sizes, test_scores_mean, 'o-', color='r', label='testing score') # 绘制测试精度曲线 plt.legend(loc='best') return plt g = plot_learning_curve(RandomForestClassifier(), 'RFC', X, y) # 调用函数 plot_learning_curve 绘制随机森林学习器学习曲线
Random Forest 的学习曲线我们得到了,训练误差始终接近 0,而测试误差始终偏高,说明存在过拟合的问题。这个问题的产生是因为 Random Forest 算法使用决策树作为基学习器,而决策树的一些特性将造成较严重的过拟合。所以我们接下来需要调整随机森林参数,改善这种问题。随机森林参数说明:
参数 | 说明 | 特点 |
---|---|---|
n_estimators | 基学习器数目(默认值 10) | 基本趋势是值越大精度越高 ,直到达到一个上限 |
criterion | 选择算法 gini 或者 entropy (默认 gini) | 视具体情况定 |
max_features | 2.2.3 节中子集的大小,即 k 值(默认 sqrt(n_features)) | |
max_depth | 决策树深度 | 过小基学习器欠拟合,过大基学习器过拟合。粗调节 |
max_leaf_nodes | 最大叶节点数(默认无限制) | 粗调节 |
min_samples_split | 分裂时最小样本数,默认 2 | 细调节, 越小模型越复杂 |
min_samples_leaf | 叶节点最小样本数,默认 2 | 细调节,越小模型越复杂 |
bootstrap | 是否采用自助法进行样本抽样(默认使用) | 决定基学习器样本是否一致 |
out-of-bag estimate | 包外估计:是否选用包外样本(即bootstrap采样剩下的36.8%的样本)作为验证集,对训练结果进行验证 | 默认不采用。 |
n_jobs | integer, optional (default=1) 并行使用的进程数 | 默认1个,如果设置为-1,该值为总核数。 |
random_state | 随机状态 | 默认由np.numpy生成 |
verbose | int, optional (default=0) | 显输出的一些参数,默认不输出。 |
根据反馈来的结果,我们便可以根据如上的参数进行参数调节,解决遇到的过拟合问题。
def para_tune(para,X,y): clf = RandomForestClassifier(n_estimators=para) # n_estimators 设置为parameter score = np.mean(cross_val_score(clf,X,y,scoring="accuracy")) return score def accurate_curve(para_range,X,y,title): score = [] for para in para_range: score.append(para_tune(para,X,y)) plt.figure() plt.title(title) plt.xlabel("Paramters") plt.ylabel("Score") plt.grid() plt.plot(para_range,score,"o-") return plt g = accurate_curve([2,5,80,100,150],X,y,"n_estimator tuning")
我们利用交叉验证的方式得到最优参数 n_estimators=80,同理:
def para_tune(para, X, y): clf = RandomForestClassifier(n_estimators=300, max_depth=para) score = np.mean(cross_val_score(clf, X, y, scoring='accuracy')) return score def accurate_curve(para_range, X, y, title): score = [] for para in para_range: score.append(para_tune(para, X, y)) plt.figure() plt.title(title) plt.xlabel('Paramters') plt.ylabel('Score') plt.grid() plt.plot(para_range, score, 'o-') return plt g = accurate_curve([2, 10, 20, 30, 40], X, y, 'max_depth tuning')
得到最优max_depth=10
from sklearn.model_selection import GridSearchCV def plot_learning_curve(estimator, title, X, y, cv=10, train_sizes=np.linspace(.1, 1.0, 5)): plt.figure() plt.title(title) # 设置图的 title plt.xlabel('Training examples') # 横坐标 plt.ylabel('Score') # 纵坐标 train_sizes, train_scores, test_scores = learning_curve(estimator, X, y, cv=cv, train_sizes=train_sizes) train_scores_mean = np.mean(train_scores, axis=1) # 计算平均值 train_scores_std = np.std(train_scores, axis=1) # 计算标准差 test_scores_mean = np.mean(test_scores, axis=1) test_scores_std = np.std(test_scores, axis=1) plt.grid() # 设置背景的网格 plt.fill_between(train_sizes, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std, alpha=0.1, color='g') # 设置颜色 plt.fill_between(train_sizes, test_scores_mean - test_scores_std, test_scores_mean + test_scores_std, alpha=0.1, color='r') plt.plot(train_sizes, train_scores_mean, 'o-', color='g', label='traning score') # 绘制训练精度曲线 plt.plot(train_sizes, test_scores_mean, 'o-', color='r', label='testing score') # 绘制测试精度曲线 plt.legend(loc='best') return plt clf = RandomForestClassifier() para_grid = {'max_depth': [10], 'n_estimators': [80], 'max_features': [1, 5, 10], 'criterion': ['gini', 'entropy'], 'min_samples_split': [2, 5, 10], 'min_samples_leaf': [1, 5, 10]}#对以上参数进行网格搜索 gs = GridSearchCV(clf, param_grid=para_grid, cv=3, scoring='accuracy') gs.fit(X, y) gs_best = gs.best_estimator_ #选择出最优的学习器 gs.best_score_ #最优学习器的精度 g = plot_learning_curve(gs_best, 'RFC', X, y)#调用实验2中定义的 plot_learning_curve 绘制学习曲线
我们发现,相比于上面,有效地缓解了过拟合。
没啥太大总结的,思路大概就这么多,前面写得挺顺的,后面调bug调了很久,因为有些代码并不是我写的,我从中午从零开始写,到晚上10点基本完成了雏形,数据之前就有关注过,毕竟最出名的题目之一,然后有些代码确实时间不多,还有就是有些博文已经总结得非常好了,有些大佬写得连我都看不懂,这里贴出一些好的链接。
[1].机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾
[2].Kaggle_Titanic生存预测 – 详细流程吐血梳理
[3].Kaggle泰坦尼克-Python(建模完整流程,小白学习用)
[4].Kaggle入门:泰坦尼克号乘客生死预测
[5].kaggle 泰坦尼克号生存预测——六种算法模型实现与比较
[6].分分钟带你杀入Kaggle Top 1%
第一篇是韩小阳写的,实力不用多说,内容很全面,语言很幽默,第二篇偏向于可视化,作图技巧叹为观止,第三篇对整个赛题的理解都非常清晰,还有整体的框架确实适合于小白,第四、五篇都还好,很全面代码量也多,第六篇偏向于科普。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。