目录

引言

背景

说明

How Do it?

看数据的容颜

了解性格

恋爱之baseline

恋爱之调优

结婚

总结

关于数据和代码


作者:徐国功

2018.9.7

转载请注明出处:https://blog.csdn.net/u010606321/article/details/82501341

引言

白天忙成狗,下班后就颓废到没有下降空间,突然良心发现抽晚上的时间做点有意义的事(鹅厂的游戏真的很不错喔),磨叽了很长时间才写完这篇博客,好久没有写过大段的文字了(写毕业论文的功底都没有了),找一个自己曾经熟悉的数据集回忆一下过去,希望能给小伙伴们带来一丢丢的收获,献给毕业一周年的自己。

好了,好了,煽情果然不是我的强项,不叨叨了,赶紧进入正题吧!!!不要怕,本文不会涉及数学公式,具体的算法原理会在下一篇里统一的介绍。

背景

翻箱倒柜找到了曾经天池【公交线路客流预测】的一份比赛数据,这里就借这份数据给还没有基础的小伙伴们表演一下。如果你看到这里脑子里直接出现【Random Forest,GBDT】,可以绕行了。

相信你从师兄师姐那里获悉,天池大数据比赛是个不错的练手的地方,这里附上链接:https://tianchi.aliyun.com/index.htm,这不是广告哦,我个人感觉这个对于还没有去过工地的小挖掘机们还是挺不错的。当然类似的数据挖掘比赛的平台还有很多,比如Kaggle,KDD-CUP啥的,这些平台把一些商业上的或者研究中产生的数据公开出来让全世界的数据挖掘爱好者和学者去折腾,用算法去解决实际问题。

好像又扯远了,还是正经的说说这个比赛的事吧!

说明

竞赛题目:

本次大赛要求选手根据广州市内及广佛同城公交线路的历史公交刷卡数据,挖掘固定人群在公共交通中的行为模式。建立公交线路乘车人次预测模型,并用模型预测未来一周(20150101-20150107)每日06时至21时每小时段各个线路的乘车人次。

大赛开放20140801至20141231五个月广东部分公交线路岭南通用户刷卡数据,共涉及近200万用户2条线路约800多万条数据记录。同时大赛提供20140801至20150131期间广州市的天气状况信息。

数据说明

乘车刷卡交易数据表(gd_train_data)

列名

类型

说明

示例

Use_city

String

使用地

广州

Line_name

String

线路名称

线路1

Terminal_id

String

刷卡终端ID

4589bb610f9be53a43a7bc26bb40e44d

Card_id

String

卡片ID

8ce79e0b647053f191d20c5552eb49f0

Create_city

String

发卡地

佛山

Deal_time

String

交易时间(yyyymmddhh)

2014091008

Card_type

String

卡类型

学生卡

公交线路信息表(gd_line_desc)

列名

类型

说明

示例

Line_name

String

线路名称

线路1

Stop_cnt

String

线路站点数量

24

Line_type

String

线路类型

广州市内/广州佛山跨区域

广州市天气状况信息(gd_weather_report)

列名

类型

说明

示例

Date_time

String

日期

2014/8/1

Weather

String

天气状况(白天/夜间)

小雨

Temperature

String

气温(最高/最低)

36℃/26℃

Wind_direction_force

String

风向风力(白天/夜间)

无持续风向≤3级/无持续风向≤3级

预测数据集为这些公交线路在20150101-20150107每个线路每日06时至21时各个小时段的乘车人次总和。(注:21时指的是21:00-21:59这个时间段)

选手需要提交结果表(gd_predict.txt)

列名

类型

说明

示例

Line_name

string

线路名称

线路1

Deal _date

string

日期

20150101

Deal_hour

string

小时段

08

Passenger_count

bigint

乘车人次

1234

提交文件示例

文件需用UTF-8字符编码;提交的文件内容格式如下,或参见文件sample_for_offline.txt。

 评估指标:

评估指标的设计主要期望选手对未来一周(20150101-20150107)每天06时至21时每个小时段各个线路乘车人次的总量数据预测的越准越好,积分公式的计算方法:计算每天每个小时段各个线路预测值的相对误差,然后根据用户预测乘车人次的相对误差,通过得分函数映射得到每个预测记录的得分,最后将所有预测记录得分求和除以理想状况的满分,得到最终评分。

How Do it?

由于比赛已经结束了,咱们没法知道20150101-20150107的真实数据,所以这里咱们就把20141225-20141231的客流作为预测对象,其余的数据作为训练数据,将就一下吧,木有办法。敲黑板……开始表演。

其实做数据挖掘的步骤和相亲是一样一样滴。

  1. 看妹子的容颜(看看是啥数据)
  2. 了解性格(特征工程)
  3. 恋爱(baseline+调优)
  4. 结婚(模型融合)

看数据的容颜

先看看数据卸妆后的真实面目,这里我使用pandas这个神器来探索数据,相信做数据挖掘的小伙伴都在使用吧。

import pandas as pdtrain_data = pd.read_csv('./data/gd_train_data.txt',header=None,names=['use_city', 'line_name', 'terminal_id', 'card_id', 'create_city', 'deal_time', 'card_type'])line_desc = pd.read_csv('./data/gd_line_desc.txt',header=None,names=['line_name','stop_cnt','line_type'])weather_report = pd.read_csv('./data/gd_weather_report.txt',header=None,names=['date','weather','temperature','wind_direction_force'])

下面的三个dataFrame(这是个啥,它是pandas中的一种数据结构,现在不用管它,就认为它是个excel表格)就是题目中给的原始数据,原始数据是没有表头的列名称的,这里我给数据加上了列字段名称。

这么看数据也看不出什么呀,尤其是gd_train_data.txt,数据文件1G多,这么多数据总不能一条条的看吧,万一中间有缺失值怎么办?pandas耍一耍

这一下就清楚了,这个文件中有11596035条数据,有7个字段,没有缺失值,各个字段都很完整。这里没有给我机会进行一下数据预处理,这里简要说一下数据预处理的几种方式。

1.空值:

如果某个属性缺失值比较多,对于构造特征没有什么帮助就直接去掉即可。如果缺失的不是特别多,属性是连续的数值型,可以根据已有的特征训练一个模型拟合一下把缺失补充上或者把连续值分段离散化后把空值作为一个属性值;如果是离散型可以尝试直接把空值作为一个属性值。

2.重复值:

去重复值的时候要考虑具体的业务,如果数据某个属性是代表了数据的ID值,这个属性出现重复是不符合实际的,那就直接留下一条。

公交线路信息数据和天气信息数据很容易理解,那么来看一下交易数据每个字段里都有什么。其中有四个字段我们比较好奇,分别是使用地(在哪用的呢?)、线路名称(赛题中说提供了两条数据,是哪两条线路的?)、发卡地(捎带着瞅一眼)、卡类型(都有什么类型)。

现在清楚这四个字段中都有什么了,前面的数字只是索引值而已,忽略即可,到此为止看颜值的阶段已经结束,进入下一个阶段。

了解性格

这个阶段就要根据给的数据了解一下性格了,不能总是这么肤浅,只看颜值,那就根据给的数据先猜测一下有哪些因素可能影响最后结婚呢?先进行一下头脑风暴,猜测会影响客流的因素,然后对数据进行实际的分析,但是要注意的是分析的影响因素要在未来的一周知道这些因素或者可以估计,否则在预测的时候无法给模型提供相应的特征,直观的感觉影响因素有:星期几、是否节假日、天气(人家既然给了天气数据不折腾一下多不好意思呀)、线路的站数、线路类型、发卡地、各种类型的卡在不同时间段出现概率。有了这几点咱们就探索一下这些因素是不是真的对客流有影响。

题目要求预测未来一周每天06时至21时每个小时段各个线路乘车人次,那就看看数据中给的两条线路的人次吧。先把数据按照线路6和线路11分开,以下就以线路6的数据为研究对象,线路11方法相同。咱们就按照时间顺序统计每个小时线路6的人次。

每小时的人次计算出来了,看这些数字是不是没感觉,好的,画个图吧,这时候引出了第二个神器matplotlib,咱们下面就用这个神器从整体到部分了解数据性格。

import matplotlib.pyplot as plt% matplotlib inlinefig = plt.figure()train_data_6_sort_time.groupby('deal_time').count()['card_id'].plot(figsize=(200, 10))plt.show()

这样就绘制出了5个月每天的人次变化曲线图,由于图太长了,我就截取其中比较特殊的一段图像。

为啥特殊呢,因为里面包含了十一长假7天(一提到放假就特别兴奋),猜一下哪七天是假期?很有意思就是中间比其他人次都少的7天就对应着十一长假,再仔细看看不只是这7天的人次比较少,每周的周末两天竟然也比其他天少,真相只有一个,就是大多数人们在节假日的时候不去挤公交了,这个信息通过画图反映了出来,所以画图去分析数据是很有料的。【在预测的时候要注意预测日是否为节假日】,预测目标日期是2014年12月25日到2014年12月31日, 27号、28号是周末,其余都是工作日,有的同学说25号是圣诞节呀,but在领导那里不管用,老老实实上班吧。其实比赛题目中让预测的日期还是挺特殊的,1号到3号是元旦假期,4号虽然是周日但是是工作日,5号到7号是正常的工作日(竟然选择了这么特殊的日期去预测,阿里是故意让人不好过呀!)。

再以周为单位看看数据

每一行就是一周的客流曲线,变化还是很有规律的,但是强迫症的我发现了一点瑕疵,第二行是什么鬼,别的周都挺好的,就这个特殊,可能是异常数据,待会找他算账。

接下来随便拿出正常的一周来看看一周内的人次变化情况。周一到周五的图像大致是一样的,每天早高峰和晚高峰比较明显,到周六日人次有所下降,而且早晚高峰不是那么明显了,这再次验证了刚才的想法。

抽出一天的数据看看

这一天的数据挺规矩的,竟让我无言以对。

再看看天气是否会对客流影响呢,为了后面分析数据方便以及算法中使用天气特征,我先把天气、风力风向这样的文字映射为数值标记,温度也只留下数值忽略掉摄氏度的符号,在映射之前要先知道数据里天气、风力风向都有哪些属性值,获取方法和看颜值阶段相同,下面是我映射的字典:

windmap={'无持续风向≤3级':0,'无持续风向微风转3-4级':1,'北风微风转3-4级':1,'东北风3-4级':2,'北风3-4级':2,'东南风3-4级':2,'东风4-5级':3,'北风4-5级':3}

个人感觉风向对客流应该没有太大影响,所有这里只考虑风力,风力相同则映射为同一数字。

weathermap={'晴':0,'多云':1,'阴':2,'小雨':3,'小到中雨':4,'中雨':5,'中到大雨':6,'大雨':7,'大到暴雨':8,'霾':9,'阵雨':10,'雷阵雨':11}

下面上图了!!

lineX_passenger_hour_path = "../data/line6 _passenger_hour.csv"lineX_passenger_hour = pd.read_csv(lineX_passenger_hour_path)lineX_passenger_day=DataFrame(lineX_passenger_hour.groupby('date').sum()['card_id']).reset_index()passenger_weather = pd.merge(lineX_passenger_day, weather_report_data, on='date', how='left')feature_daycount=DataFrame(passenger_weather.groupby('temperature_average').count()['date']).reset_index()feature_person=DataFrame(passenger_weather.groupby('temperature_average').sum()['card_id']).reset_index()feature_daycount_person=pd.merge(feature_daycount,feature_person,on='temperature_average')feature_daycount_person['personOneday']=feature_daycount_person['card_id']/feature_daycount_person['date']feature_daycount_person=feature_daycount_person.set_index('temperature_average')['personOneday']feature_daycount_person.plot(kind='bar', figsize=(8, 5))plt.show()

这是各个温度下温度相同的日平均人次,从图中的总体趋势看貌似可以感觉温度和人次存在负相关的关系,作为一个严谨的计算机科学工作者(以下简称程序猿)要把那这种貌似的感觉量化,这里就计算一些温度和人次的Pearson相关系数,就是【温度和人次的协方差】和【温度的标准差与人次标准差的积】的商,这个商是一个-1到1之间的数,绝对值越大说明越相关,负数表示负相关,正数表示正相关。

feature_average_person=pd.DataFrame(feature_daycount_person,columns=['temperature_average', 'personOneday'])print(feature_average_person.corr())

这个的Pearson相关系数计算后为-0.459826,果然和感觉是一样的,负相关。看来是人们在气温比较低的时候喜欢挤公交(挤公交暖和,嘿嘿)。

相同的方法再看看平均风力,

Pearson相关系数计算后为0.513215,是个正相关。

那降雨呢

结合刚才的映射字典看看,这个根据常识有点说不通,人们并没有因为降雨而选择公交出行,不过还有个原因就是这个图是根据全天的客流绘制的,而且没有考虑是否节假日,以及出行的人群类型,或许考虑这些因素后就会看出降雨对客流的影响,先不管它了。而对头脑风暴的时候提到的线路的站数、线路类型两个特征这里没法使用,why???因为同一个线路所有样本的站数和线路类型都一样,所以在训练的时候没有价值。

好了到这里咱们挖掘特征就暂时这样,马克思主义哲学告诉我们要抓主要矛盾,性格不是一天两天就能了解全面的,经过这段时间的相处感觉人还不错,进入恋爱阶段,根据现有的feature训练个模型看看效果吧。

恋爱之baseline

经过各种折腾,终于进入了建模阶段,是不是特别激动,引入又一神器scikit-learn,这个工具包中包含了机器学习的一系列工具,包括特征处理,模型选择,分类算法,回归算法,聚类算法,这里就不全面的说了,咱们用到什么说什么,其他的可以去官网看看文档。且慢,在进入主题之前,还要整理一下数据,把咱们前面分析的一系列feature和lable加上,肯定不能随便弄一份数据就能训练,那怎么【整理】呢?,先把之前发现的异常数据干掉。接下来对特征进行一些处理:

1.对于离散型的特征可以做one-hot encoding

什么是one-hot encoding?

举个栗子,某个特征是性别,用0表示男,1表示女,这个时候这个特征中就存在0和1两个值,而one-hot encoding的表示方法是把这个特征拆成两个特征即【是否男】和【是否女】。如果是男的话,【是否男】为1,【是否女】为0。如果是女的话,【是否男】为0,【是否女】为1。总结一下就是男用[1,0]表示,女用[0,1]表示。

怎么做one-hot encoding?

data={'gender':['male','female','female','male']}dataDf=DataFrame(data)dataOneHot=pd.get_dummies(dataDf['gender'], prefix= 'gender')

效果如下:

为什么要做one-hot encoding?

浅显的说就是使离散特征的每个取值都对应函数中的一个变量,装B的说就是使离散特征的每个取值都对应欧式空间的一个点,使特征之间的距离计算更加合理。

2.对于连续型的特征可以做标准化

什么是标准化?

标准化是将数据变化为标准正态分布,常用的方法是z-score标准化,

怎么做?

from sklearn import preprocessing

z-score标准化:

scaler = preprocessing.StandardScaler().fit(X)

为什么做?

如果特征之间数值变化范围相差较大的话,会导致在进行梯度下降的时候比较曲折,成功的道路上会走很多弯路,归一化后可以加快梯度下降的收敛速度。盗两张Andrew Ng课程里的图体会一下(我就是这么懒),左边是未进行特征标准化,右边是经过标准化处理的。

说了这几种整理的方法,那就用到自己的数据呗!

下面是未经过one-hot encoding和标准化的特征数据(特征有点多,截一部分体会一下)

one-hot encoding如下:

time_dum=pd.get_dummies(train_data_weather_passenger_holiday['time'], prefix= 'time')wind_d_map_dum=pd.get_dummies(train_data_weather_passenger_holiday['wind_d_map'], prefix= 'wind_d_map')wind_n_map_dum=pd.get_dummies(train_data_weather_passenger_holiday['wind_n_map'], prefix= 'wind_n_map')weather_d_map_dum=pd.get_dummies(train_data_weather_passenger_holiday['weather_d_map'], prefix= 'weather_d_map')weather_n_map_dum=pd.get_dummies(train_data_weather_passenger_holiday['weather_n_map'], prefix= 'weather_n_map')isholiday_dum=pd.get_dummies(train_data_weather_passenger_holiday['isholiday'], prefix= 'isholiday')dayofweek_dum=pd.get_dummies(train_data_weather_passenger_holiday['dayofweek'], prefix= 'dayofweek')train_data_dum = pd.concat([train_data_weather_passenger_holiday, time_dum, wind_d_map_dum, wind_n_map_dum, weather_d_map_dum,weather_n_map_dum,isholiday_dum,dayofweek_dum], axis=1)train_data_dum.drop(['time', 'wind_d_map', 'wind_n_map', 'weather_d_map', 'weather_n_map', 'isholiday','dayofweek'], axis=1, inplace=True)train_data_dum

我们再对温度和降雨这两个变化范围比较大的特征标准化:

import sklearn.preprocessing as preprocessingscaler = preprocessing.StandardScaler()temperature_h_scale = scaler.fit(train_data_dum[['temperature_h','temperature_l','temperature_average','temperature_abs','weather_average','weather_abs']].values)scaleDf=DataFrame(temperature_h_scale.transform(train_data_dum[['temperature_h','temperature_l','temperature_average','temperature_abs','weather_average','weather_abs']].values),columns=['temperature_h_scale','temperature_l_scale','temperature_average_scale','temperature_abs_scale','weather_average_scale','weather_abs_scale'])train_data_dum_scale=pd.concat([train_data_dum,scaleDf],axis=1)train_data_dum_scale.drop(['temperature_h', 'temperature_l', 'temperature_average', 'temperature_abs', 'weather_average', 'weather_abs'], axis=1, inplace=True)train_data_dum_scale

到现在为止终于把数据整理好了,直接上算法训练,先来个最基本的线性回归。

train_data_X_path = '../data/line6_train_data_dum_scale.csv'train_data_X = pd.read_csv(train_data_X_path)lables = train_data_X['card_id']features = train_data_X.drop(['date', 'card_id'], axis=1)linreg = LinearRegression()linreg.fit(features, lables)model_path = "../model/linreg_6.model"joblib.dump(linreg, model_path)

上面辛辛苦苦才准备好数据,不到10行的代码就完成了模型的训练过程,现在小伙伴儿们知道做这个工作都干啥了吧,就是一个光鲜的外表下藏着一颗low爆了的心,要保持微笑,吐槽完毕……

模型训练好了那先看看模型里训练出来的是什么吧,

print(model.coef_)
print(model.intercept_)

这就是咱们想要的东西,每个feature对应的就是最终学出的函数中的自变量,前面的list中就是每个自变量前面的系数,最后一个就是这个函数的偏置。

接下来就要看看这个模型的效果了,这里的评价指标就是最开始赛题里的评价指标,由于官方没有提供偏差和得分之间关系的公式,这里咱们就算平均绝对误差。

def error(true_labels, predict_labels):deviation = abs(true_labels - predict_labels) / true_labelsreturn deviation.mean()

这个时候有个主意的点,在进行特征工程阶段one-hot encoding和标准化的时候要把test set和train set放到一起处理,也就是train set做了什么处理test set也要做相同的处理。

for i in ['6', '11']:test_data_path = "../data/test_%s_data_dum_scale.csv" % itest_data = pd.read_csv(test_data_path)lineX_passenger_hour_test_path = "../data/line%s_passenger_hour_test.csv" % iline_passenger_hour_test = pd.read_csv(lineX_passenger_hour_test_path)test_labels = line_passenger_hour_test['card_id']model_path = "../model/linreg_%s.model" % imodel = joblib.load(model_path)features = test_data.drop('date', axis=1)predict_labels = model.predict(features)err = error(predict_labels, test_labels)print(err)

分别加载刚才训练好的模型,对测试集进行预测,接下来就是见证奇迹的时刻。

线路6:0.14914744085671014

线路11:0.1239384391911595

这是两个模型预测的平均绝对误差,虽然效果不是特别好,但是总算看到了第一个成果。

恋爱之调优

第一个最基本的线性回归模型训练好了,说明真正的苦日子开始了(是不是很惊喜),刚才构造了这么多特征对模型的影响大小不一,目前模型的状态咋样呢,所谓模型的状态就是模型是过拟合还是欠拟合。

过拟合:学的太僵硬了,课本里教什么就会什么,不知道举一反三,比如知道1加1等于2,但是2加2就不知道了。在模型中就叫“泛化能力差”,又叫“高方差”。

欠拟合:课本里教的知识还没会,比如连1加1还不知道等于几,2加2就更不知道了。在模型中叫做“高偏差”。

如果知道模型的状态了,下面是增加特征还是进行特征选择心里就有数了,怎么评估模型状态呢?这就引出了交叉验证和Learning Curves。

交叉验证:比较常用的交叉验证是K-fold交叉验证,就是把原始的训练集平均分成K份,每一份就叫1折,把这K折轮流做验证集,其余的K-1折作为训练集训练模型,这样就会得到K个得分,对K个得分求平均,这样可以更加客观的对模型做出评价,防止由于样本分布造成的评估不准确。

Learning Curves:还是盗张Andrew Ng的图吧,

左边是高偏差的图像,横轴是样本数量,纵轴是误差,随着样本量的增多,验证集error逐渐降低,训练集error逐渐升高,最终到达一个比较接近的error上,说明训练集上的误差和测试集上的误差基本相同,但是这个error高于期望的error,所以是欠拟合。右边是高方差的图像,训练集的误差远低于验证集上的误差,图像表现就是中间的gap比较大,所以是过拟合。

那咱们就画Learning Curves评估一下模型状态。

#画图函数(来自Sklearn)def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,n_jobs=1, train_sizes=np.linspace(.1, 1.0, 5)):plt.figure()plt.title(title)if ylim is not None:plt.ylim(*ylim)plt.xlabel("Training examples")plt.ylabel("Error")train_sizes, train_scores, test_scores = learning_curve(estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes, scoring=score)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="r")plt.fill_between(train_sizes, test_scores_mean - test_scores_std,test_scores_mean + test_scores_std, alpha=0.1, color="g")plt.plot(train_sizes, train_scores_mean, 'o-', color="r",label="Training error")plt.plot(train_sizes, test_scores_mean, 'o-', color="g",label="Cross-validation error")plt.legend(loc="best")return plt
#用题目定义的error方法score = make_scorer(error, greater_is_better=True)cv = ShuffleSplit(n_splits=20, test_size=7 * 16, random_state=1)plot_learning_curve(linreg, Lineartitle, features, lables, ylim=(0.0, 1.01), cv=cv)plt.show()

图像虽然和理论形状不一样,但是依据刚才说的也可以看出现在的模型是欠拟合,欠拟合的解决方法有:

  1. 再次回到特征工程阶段,根据实际问题挖掘有用的特征
  2. 增加模型的复杂度,比如用高次的函数去拟合数据

这里选择第二种方法尝试一下,使用二次的函数去拟合数据(其实就是特征本身以及特征之间相乘,构造出了很多二次的特征,特征数量增多了)。

quadratic_featurizer = PolynomialFeatures(degree=2)X_train_quadratic = quadratic_featurizer.fit_transform(features)Quadratictitle = "Learning Curves (Quadratic Linear Regression)"plot_learning_curve(linreg, Quadratictitle, X_train_quadratic, lables, ylim=(0.0, 1.01), cv=cv)

看到这个结果,只能感叹一下人生,CV集的error都飞到天上去了,1次拟合就欠拟合,2次拟合就过拟合,好吧,那就解决一下过拟合的问题,过拟合在机器学习中还是比较普遍的。

过拟合的解决方法有:

  1. 减少特征(特征筛选,降维)
  2. 增加样本数量(这里就这些数据了)
  3. 正则化

这里咱们用正则化的方法尝试,L1正则化由于可以稀疏权值矩阵,所以可以起到特征筛选的作用,L2正则化的作用是让权值尽可能的小,使模型简单,根据奥卡姆剃刀定律,模型越简单泛化能力越强,这样也就防止了过拟合。

我们尝试使用L1正则化,Lasso回归使用的就是L1范数,Lasso回归中有个比较重要的超参alpha,这里用GridSearch来确定alpha的最优取值。

lassoreg = linear_model.Lasso()
parameters = {'alpha': [1 * (i + 1) for i in range(10)]}
clf = GridSearchCV(lassoreg, parameters)
clf.fit(features, lables)
best_parameters = clf.best_params_
print(best_parameters['alpha'])
lassoreg.set_params(alpha=best_parameters['alpha'])
Lassotitle = "Learning Curves (Lasso Regression)"
plot_learning_curve(lassoreg, Lassotitle, X_train_quadratic, lables, ylim=(0.0, 1.01), cv=cv)

这次终于把CV集的error从天上拉了下来,然后看看在测试集的预测效果把,

线路6:0.12653625014283182

线路11:0.11308786725590539

误差分别比baseline降低了一两个百分点,还是有点效果的。

结婚

恋爱阶段的起起落落很多,经过层层考验进入了谈婚论嫁的阶段。

尝试了几个算法,就会产生一个想法,能不能集众人之所长来完成这个工作呢,答案肯定是有滴,不然就不说了。这就引出了集成学习,集成学习有两个思想,一个是bagging一个是boosting。这两种算法都是用弱学习器组合成强学习器,区别是bagging中的弱学习器是并列独立的,而boosting中的弱学习器是链式的,就像冰糖葫芦,上一个学习器和下一个学习器是有联系的。实现bagging思想的常见算法就是Random Forest,随机森林的思想就是随机的抽取部分样本,然后随机的选择部分特征参与决策树的构建,最终训练出多棵决策树,对同一问题做出预测,最终投票或求平均值确定最终答案。Boosting的思想就是先根据样本训练出一个基学习器,然后基于这个学习器的决策结果对样本权重进行调整,增大判断错误的样本权重,减小判断正确的样本权重,训练下一个学习器,最终达到事先设定的学习器的数目为止,把这些学习器加权结合,实现boosting思想的常见算法就是AdaBoost算法。

点到为止,直接上算法,这里咱们用基于boosting思想的GBDT算法来训练模型,GBDT中用的基学习器是CART树,这里有一点要说一下,基于树的算法可以不对特征进行one-hot encoding和标准化,因为树按照特征进行划分就类似与对特征进行编码,而且树模型不用求特征之间的距离。

gbdt = ensemble.GradientBoostingRegressor()title = "Learning Curves (GBDT)"plot_learning_curve(gbdt, title, no_dum_features, no_dum_lables, (0.0, 1.01), cv=cv)

没有进行调参,直接用默认参数训练的结果还不错,从图像上的误差看比Lasso回归有所下降,在测试集上在试一下。

线路6:0.10196657504740832

线路11:0.09444447023369977

误差再次下降两个百分点,是不是很开心,既然这么开心就结婚吧,如果还不开心可以尝试调参,这里就不展开说调参这事儿了,怕调参调头晕了,破坏了这桩婚事,hiahiahia。

总结

终于写到结尾了,感谢小伙伴们能坚持到最后,不知道能否有点收获,这篇文章没有涉及具体的算法原理,只是从工程角度以这份数据为例子走了一遍解决问题的流程,具体的算法原理打算在后期再补上。

再回顾一下这来之不易的爱情吧。

  1. 看妹子的容颜(看看是啥数据)
  2. 了解性格(特征工程)
  3. 恋爱(baseline+调优)
  4. 结婚(模型融合)

第一步看看数据里都有什么信息,对缺失值,重复值,异常值进行处理

第二步根据任务目标探索影响目标的特征,构造特征

第三步先跑个基本的模型,在此基础上慢慢调优,可以再回到第二步

第四部模型融合加调参。

关于数据和代码

数据和代码请去我的github中获取。

公交线路客流预测——手把手教你玩数据(一)相关推荐

  1. echarts formatter_手把手教你玩转echarts(二)折线图

    茫茫人海中与你相遇 相信未来的你不会很差 作者:婷酱Yaaa 来源:https://juejin.im/post/5f0292d35188252e5a5dbed0 前言 哈喽,everybody,我又 ...

  2. 手把手教你玩转SOCKET模型之重叠I/O篇(下)

    http://blog.csdn.net/PiggyXP/archive/2004/09/23/114908.aspx 四.     实现重叠模型的步骤 作了这么多的准备工作,费了这么多的笔墨,我们终 ...

  3. 手把手教你玩转SOCKET模型:完成例程(Completion Routine)篇

    本文假设你已经对重叠I/O的机制已有了解,否则请先参考本系列的前一篇<手把手教你玩转SOCKET模型之重叠I/O篇>: 目录: 1.完成例程的优点 2.完成例程的基本原理 3.关于完成例程 ...

  4. 手把手教你玩转SOCKET模型:完成端口(Completion Port)详解

    这篇文档我非常详细并且图文并茂的介绍了关于网络编程模型中完成端口的方方面面的信息,从API的用法到使用的步骤,从完成端口的实现机理到实际使用的注意事项,都有所涉及,并且为了让朋友们更直观的体会完成端口 ...

  5. 手把手教你玩转网络编程模型之完成例程(Completion Routine)

    前  言 记得写这个系列的上一篇文章的时候已经是四年前了,准确的说是四年半以前了,翻开我尘封已久的IO模型里面的"完成例程"的实现方式及示例代码. 本文凝聚着笔者心血,如要转载,请 ...

  6. 手把手教你玩转ARP包(一)

    原文地址:http://blog.csdn.net/piggyxp/article/details/19606 前   言 首先要感谢网络安全资深专家卢湖川博士以及VC网络版的limin朋友提供的资料 ...

  7. vscode angular智能提示_【线下活动】手把手教你玩转 VS Code 插件开发

    感谢 Google Developer Group 的邀请,3 月 30 号下午,韩老师将手把手带你玩转 VS Code 插件开发. Angular 使用了 TypeScript,VS Code 使用 ...

  8. 手把手教你玩转网络编程模型之完成例程(Completion Routine)篇(下)-转

    续 手把手教你玩转网络编程模型之完成例程(Completion Routine)篇(上) 四.         完成例程的实现步骤 基础知识方面需要知道的就是这么多,下面我们配合代码,来一步步的讲解如 ...

  9. 手把手教你玩转网络编程模型之完成例程(Completion Routine)篇(上)-转

    手把手教你玩转网络编程模型之完成例程(Completion Routine)篇 前  言 记得写这个系列的上一篇文章的时候已经是四年前了,准确的说是四年半以前了,翻开我尘封已久的IO模型里面的&quo ...

最新文章

  1. luvit 被忽视的lua 高性能框架(仿nodejs)
  2. 关于nginx配置的不完全总结
  3. CentOS忘记root密码解决办法
  4. 笨办法学习@ConditionalOnProperty 烧脑配置记录
  5. 新的编程语言研发契机思考
  6. 找高清壁纸,没有那么麻烦,高图网帮你搞定!
  7. 什么是网络爬虫python_什么的什可以组什么词语
  8. Django 基础,创建一个Django,并成功在网页中运行
  9. 两个摄像头合成一路_64个高空抛物摄像头安装到位 同德社区居民双手点赞
  10. LVDS屏的俩种接口:JEIDAVESA
  11. json转为tfrecord格式文件怎么转_JPG图片怎么转换成PDF?图片转PDF的免费软件有这些...
  12. 数商云制药医药供应链erp管理系统解决方案
  13. SD和SDHC和SDXC卡的区别, class与u1/u3关系
  14. 武汉科技大学计算机课程设置,武汉科技大学课程建设管理办法
  15. k8s部署mysql
  16. oracle revoke 列_oracle受权与回收权限grant和revoke
  17. vrp系统和linux区别,华为VRP-文件系统基础
  18. 了解阿克曼转向原理的作用
  19. NAS中的文件共享协议
  20. 多线程之线程的百米赛跑

热门文章

  1. 我的勇者服务器维护3月5日,时空猎人3月5日更新维护时间和更新活动内容
  2. 传统蒙文字体_蒙古文
  3. Win7蓝屏代码0X0000007B可能是SATA mode问题
  4. cookie、session与token之间的关系
  5. watchdog linux 进程,watchdog
  6. 【深度学习-吴恩达】L1-4 深层神经网络 作业
  7. 冬瓜哥对时间和空间的理解方式—时空参悟(下)
  8. 微信小程序图片上传oss
  9. android界面布局
  10. Vue2+Openlayer使用modify修改要素