印象盐城·数创未来大数据竞赛 - 盐城汽车上牌量预测

从本次经历来看这份成绩我还是满意的。

毕竟我并没有像那些大佬们从数据的行列之间进行关联性分析,独立性检验之类的专业技术流操作。我只是个机器学习的小浪花。

通过这次比赛,我明白了要更多的联系社会实际生活的话,还是需要时间序列这块的理论知识和技能手段作支撑才能走的更远。

接下来分享一下大佬做比赛的思路流程,我只是复现。

寒武纪の盐城车牌预测数据初探 之 三

麻婆豆腐

第一步 导入数据

#调包侠

importpandas as pd

importmatplotlib.pyplot as plt

 

#第一步导入数据

dir ='data/'

train =pd.read_table(dir + 'train_20171215.txt',engine='python')

test_A =pd.read_table(dir + 'test_A_20171225.txt',engine='python')

sample_A =pd.read_table(dir + 'sample_A_20171225.txt',engine='python',header=None)

 

先查看数据train和test_A的数据样式

print("train.info():")

print(train.info())

print("test_A.info():")

print(test_A.info())

train.info():

<class'pandas.core.frame.DataFrame'>

RangeIndex: 4773entries, 0 to 4772

Data columns (total 4columns):

date           4773 non-null int64

day_of_week    4773 non-null int64

brand          4773 non-null int64

cnt            4773 non-null int64

dtypes: int64(4)

memory usage: 149.2KB

None

test_A.info():

<class'pandas.core.frame.DataFrame'>

RangeIndex: 276entries, 0 to 275

Data columns (total 2columns):

date           276 non-null int64

day_of_week    276 non-null int64

dtypes: int64(2)

memory usage: 4.4 KB

None

这里呈现给我们的train和test中字段形式并不一样,test中缺少了品牌即brand和需要预测的数量cnt(这个是合理的,因为需要预测)

通过对题目的阅读,第一赛季只需要预测量而不需要预测具体品牌的量,这样可以理解为,无论白猫还是黑猫,在一起就是两只猫。之后,数据类型是int64,即这个题目给我们的都是数值型的数据。

其中date根据题目,为脱敏数据,brand和cnt也是脱敏,但是dayofweek的值是真是反应星期的数值,首先观察一下这个唯一一个相对而言是真实值的值的形式

print(train['day_of_week'].unique())

print(test_A['day_of_week'].unique())

[3 4 5 6 7 1 2]

[4 5 6 1 2 3 7]

dow(dayofweek)的范围是1-7,可以理解为对应的周一到周日,也就是monday到sunday。

第二步:找出目标值(即需要我们预测的值)

这里,我们需要去观察目标值的范围变化,看一下目标值的大体趋势如何,首先以箱型图去观察一下目标值的变化。

箱形图有5个参数: 
下边缘(Q1),表示最小值; 
下四分位数(Q2),又称“第一四分位数”,等于该样本中所有数值由小到大排列后第25%的数字; 
中位数(Q3),又称“第二四分位数”等于该样本中所有数值由小到大排列后第50%的数字; 
上四分位数(Q4),又称“第三四分位数”等于该样本中所有数值由小到大排列后第75%的数字; 
上边缘(Q5),表述最大值。 
第三四分位数与第一四分位数的差距又称四分位间距。

功能:

1.为了反映原始数据的分布情况,比如数据的聚散情况和偏态。看看《统计学》这本书的插图

2..箱型图有个功能就是可以检测这组数据是否存在异常值。.箱型图有个功能就是可以检测这组数据是否存在异常值。

plt.boxplot(train['cnt'])

plt.show()

根据这个图,结合1所示的例子,大概可以估计出数据是右偏分布,以正态分布的角度观察,异常值存在于大于1000的地方,之后,绘制一个分布图,观察一下数据的分布。

importseaborn as sns

color =sns.color_palette()

sns.set_style('darkgrid')

from scipyimport stats

fromscipy.stats import norm, skew

 

sns.distplot(train['cnt'],fit=norm)

源代码,但是自己就是得不到结果(下图是大佬原图)

通过绘制分布图,可以看出来数据分布确实符合右偏分布,这里大概初步了解数据的分布尺度在 0 到 2000 左右,且在0-500/1000的数量最密集。

第三步:找出与目标最相关的变量X(即非目标值中找到与目标最相关的值)

因为数据本身与时间相关,所以我们可以绘制一下随脱敏时间和星期的变化

plt.plot(train['date'],train['cnt'])

plt.show()

结合箱图和分布图,可以确定,密集区域集中中500,之后我们以具体的数字反应意思刚才的图的信息。

print(train['cnt'].describe())

 

count   4773.000000

mean     380.567358

std      252.720918

min       12.000000

25%      221.000000

50%      351.000000

75%      496.000000

max     2102.000000

Name: cnt, dtype: float64

2)预测结果以mean square error作为评判标准,具体公式如下:

这里,可以以统计数据去确定一下,这些统计数据,在评测函数的指标。

fromsklearn.metrics import mean_squared_error

train['25%']= 221

train['50%']= 351

train['75%']= 496

train['median']= train['cnt'].median()

train['mean']= train['cnt'].mean()

print(mean_squared_error(train['cnt'],train['25%']))

print(mean_squared_error(train['cnt'],train['50%']))

print(mean_squared_error(train['cnt'],train['75%']))

print(mean_squared_error(train['cnt'],train['median']))

print(mean_squared_error(train['cnt'],train['mean']))

 

89316.2231301

64728.7100356

77179.1761995

64728.7100356

63854.4813732

可以大概看出来,由于存在异常点较多,导致统计量在时间轴上的表现并不是那么理想。现在还可以用的信息,只剩下了星期了,救命稻草之星期信息。

开始对星期信息统计,分别分析周一周五的分布情况

monday =train[train['day_of_week']==1]

plt.plot(range(len(monday)),monday['cnt'])

plt.show()

很明显了,可以把1-5和6,7分为两组去分析

简单分析一下按照星期的评测分数

res =train.groupby(['day_of_week'],as_index=False).cnt.mean()

xx =train.merge(res,on=['day_of_week'])

print(xx.head())

print('mse:',mean_squared_error(xx['cnt_x'],xx['cnt_y']))

mse明显小于之前的结果,所以这里暂时可以估计,以星期去统计分布。

 

# 因为第一赛季只是预测与时间相关的cnt的数量

# 所以可以对数据以dat和dow进行数据合并

train =train.groupby(['date','day_of_week'],as_index=False).cnt.sum()

plt.plot(train['day_of_week'],train['cnt'],'*')

plt.show()

这样很明显,看到在合并品牌之后,观察星期的分布情况,这样的观察,是观察周1-7的cnt的分布情况,可以初步认为距离密集区域较远的为异常数据。

for i inrange(7):

    tmp = train[train['day_of_week']==i+1]

    plt.subplot(7, 1, i+1)

    plt.plot(tmp['date'],tmp['cnt'],'*')

plt.show()

从上往下分别是1,2,3,4,5,6,7这样就很清楚的看见了。

训练集和测试集的分布

这样,我们首先要做的就是线下的验证机,模拟线上的数据。

此时的数据就是按星期聚类之后的数据集。

xx_train =train[train['date']<=756]

xx_test =train[train['date']>756]

print('testshape',xx_test.shape)

print('trainshape',xx_train.shape)

方案零:均值大法(原始数据验证)

# 线下统计每周的均值数据,不加权

xx_train =xx_train.groupby(['day_of_week'],as_index=False).cnt.mean()

xx_result =pd.merge(xx_test,xx_train,on=['day_of_week'],how='left')

print('xx_resultshape',xx_result.shape)

print(xx_result)

print(mean_squared_error(xx_result['cnt_x'],xx_result['cnt_y']))

查看周一到周日的情况,其mse得分如下所示

for i inrange(7):

    tmp =xx_result[xx_result['day_of_week']==i+1]

print('周%d'%(i+1),mean_squared_error(tmp['cnt_x'],tmp['cnt_y']))

感觉好差,所以要进一步优化结果

查看一下我们划分的线下数据的方差情况,说明数据的波动很明显,又是是周日的数据,根据前面的图,可以看出,数据中的异常点分布,看起来规律并不明显。而且,周日的数据本身就存在缺失,这种情况下。根据图分布可以看出来。

方案一:加权平均大法

这个方案主要是采取历史纪录*一个权值(可选函数为反比例函数,指数函数和简单的递减函数)

最后以之前分析的星期为周期,进行权重融合,求得最后结果。

def xx(df):

  df['w_cnt'] = (df['cnt'] * df['weight']).sum() / sum(df['weight'])

  return df

 

xx_train =train[train['date']<=756]

xx_train['weight'] =((xx_train['date'] + 1) / len(xx_train)) ** 6

xx_train =xx_train.groupby(['day_of_week'],as_index=False).apply(xx).reset_index()

xx_test =train[train['date']>756]

print('test shape',xx_test.shape)

print('trainshape',xx_train.shape)

# #

from sklearn.metrics importmean_squared_error

# # 这里是加权的方案

xx_train =xx_train.groupby(['day_of_week'],as_index=False).w_cnt.mean()

 

xx_result =pd.merge(xx_test,xx_train,on=['day_of_week'],how='left')

print('xx_resultshape',xx_result.shape)

print(xx_result)

print(mean_squared_error(xx_result['cnt'],xx_result['w_cnt']))

test shape (276, 3)

train shape (756, 6)

xx_result shape (276,4)

date day_of_week   cnt        w_cnt

0     757            6  314   419.121951

1     758            1 3309  2593.503011

2     759            2 1948  2615.940149

3     760            3 1722  2285.466506

4     761            4 1520  1839.909973

5     762            5 2232  1928.241036

6     763            6  497   419.121951

7     764            1 2037  2593.503011

8     765            2 2246  2615.940149

9     766            3 1447  2285.466506

10    767            4 1478  1839.909973

11    768            5 1631  1928.241036

12    769            6  128   419.121951

13    770            1 2102  2593.503011

14    771           2  2114  2615.940149

15    772            3 1964  2285.466506

16    773            4 1427  1839.909973

17    774            5 1416  1928.241036

18    775            6  319   419.121951

19    776            1 2147  2593.503011

20    777            2 1925  2615.940149

21    778            3 1668  2285.466506

22    779            4 1692  1839.909973

23    780            5 1517  1928.241036

24    781            6  381   419.121951

25    782            1 2327  2593.503011

26    783           2  1926 2615.940149

27    784            3 1387  2285.466506

28    785            4 1533  1839.909973

29    786            5 1946  1928.241036

..    ...         ...   ...          ...

246  1003            4 1618  1839.909973

247  1004           5  2259 1928.241036

248  1005            6  426   419.121951

249  1006            1 2203  2593.503011

250  1007            2 2344  2615.940149

251  1008            3 2392  2285.466506

252  1009            4 1870  1839.909973

253  1010            5 1772  1928.241036

254  1011            6  610   419.121951

255  1012            1 2437  2593.503011

256  1013            2 2326  2615.940149

257  1014            3 1954  2285.466506

258  1015            4 1569  1839.909973

259  1016           5  1777 1928.241036

260  1017            6  442   419.121951

261  1018            1 2476  2593.503011

262  1019            2 1934  2615.940149

263  1020            3 2048  2285.466506

264  1021            4 1586  1839.909973

265  1022           5  2268 1928.241036

266  1023            6  506   419.121951

267  1024            1 3439  2593.503011

268  1025            2 3208  2615.940149

269  1026            3 2277  2285.466506

270  1027            4 2144  1839.909973

271  1028            5 2519  1928.241036

272  1029            6  195   419.121951

273  1030            2 4003  2615.940149

274  1031            3 2513  2285.466506

275  1032            4 1306  1839.909973

[276 rows x 4columns]

828419.30779

可以发现,加权后的结果好于直接均值的效果,其思想考虑了近期影响大于远期影响。其实这个线下分数,只能算是一个开始,只要是模型的线下,理论应该会好于这个结果。

根据预测结果估计,可以预测到,每条数据的偏差应该在1000左右,其实这样而言,明显是差别很大。(⊙﹏⊙)接下来,要采取一些方案处理一下原始数据。

暂时这样吧,大概的两个过程是这样,应该还可以优化,如果有问题和意见可以留言,一起改善。 现在看起来,需要补充一下数据,对周日的数据补充一下。暂时思路吧。80多万的mse,说明每条数据平均和真实值的差距在1000左右。

在大佬的思路支撑下,我就按照大佬的数据处理思路,对data和day_of_week,在日期上按照星期进行训练数据的聚类。

XGBT线下测试成绩是最好的,但是能力有限并没有解决模型不能测试的问题。

最后采用了lgm+gbdt的方法进行优化,从结果上有了不小的提升。

这次比赛自己收获了一些心得,期待以后能走的更远。

为了方便大家 数据集百度网盘的链接

链接: https://pan.baidu.com/s/14clDc4O71L76rduwIeEZQA 提取码: gm1y 

2018天池比赛首战落幕相关推荐

  1. 2018 KubeCon + CloudNativeCon完美落幕,行云献力

    2018年11月13-15日,由云原生计算基金会(CNCF)组织的KubeCon+CloudNativeCon首次登陆中国.经过了三天的技术交流和展示,大会随着15日下午最后一个议程的结束而完美落幕. ...

  2. 阿里天池比赛——街景字符编码识别

    文章目录 前言 一.街景字符编码识别 1. 目标 2. 数据集 3. 指标 总结 前言 之前参加阿里天池比赛,好久了,一直没有时间整理,现在临近毕业,趁论文外审期间,赶紧把东西整理了,5月底学校就要让 ...

  3. 阿里天池比赛——地表建筑物识别

    阿里天池比赛--地表建筑物识别 记录一下之前参加的阿里天池比赛,方便以后查看. 策略: 1.多模型训练 2.多模型测试 3.数据增强 4.预训练/冻结训练 5.迁移学习 6.TTA 7.后处理 8.f ...

  4. 阿里天池比赛——食物声音识别

    阿里天池比赛--食物声音识别 最近写毕业论文无聊之余,再次参加阿里天池比赛,之前一直做CV,第一次尝试做语音识别,记录一下过程. 策略: 1.梅尔频谱和梅尔倒谱以及混合 2.多模型测试 想玩这个项目的 ...

  5. Docker提交天池比赛流程

    一.安装docker 天池大赛入门与docker实践课程: https://tianchi.aliyun.com/course/351 Ubuntu20.04安装docker: https://blo ...

  6. 天池比赛notebook

    天池比赛的链接文档说明 https://tianchi.aliyun.com/notebook/index.htm?spm=5176.9876270.5610778.14.31d1e44axRaA3f ...

  7. 天池比赛——用户情感可视化分析

    天池比赛--用户情感可视化分析 目录 天池比赛--用户情感可视化分析 前言 一.读取数据,查看基本情况并做数据预处理 引入相关库 读取数据,基础分析数据 空值处理,数据映射 对评论进行分词分析 二.词 ...

  8. 天池比赛——Docker基础镜像搭建,容器导出镜像

    天池Docker 文章目录 天池Docker 一. 通过基础的Dockerfile,只有python的镜像 二. 然后build构建镜像,再运行镜像进容器 三. 进入容器,安装环境 四. 退出容器, ...

  9. Docker提交天池比赛代码流程(windows10环境下)

    一.Docker环境配置(以windows10为例) Docker Desktop 下载地址:https://docs.docker.com/docker-for-windows/install/ 1 ...

最新文章

  1. 程序架构探讨—007 应用服务器集群的伸缩性之链路负载均衡
  2. asp 去除最后一个逗号为空字符串的代码
  3. 【Linux】35. python脚本重命名各子目录下的图片
  4. PHP学习笔记4:字符串与正则
  5. java复合数据类型_复合数据类型
  6. 定点c程序之五:定点数的字长效应
  7. ssl提高组周三备考赛【2018.10.24】
  8. lisp6 暖通cad_(完整版)暖通CAD设计技巧1
  9. 面试官系统精讲Java源码及大厂真题 - 03 Java 常用关键字理解
  10. 一文带你了解数仓智能运维框架
  11. python sqlalchemy core
  12. 堆排序算法讲解视频java版_堆排序算法的讲解及Java版实现
  13. 理解Java的几张图
  14. TreeMap按照key排序
  15. 由DOOM启示录想到微软的发展。
  16. 基于网易云API的音乐网站的登录注册(持续更新)
  17. 时间 java 时间段_Java 如何判断当前时间是否在指定时间段内
  18. 使用JBE修改.class字节码文件
  19. Linux命令行窗口无法输入密码
  20. MAX31865模块PT100两线制测温

热门文章

  1. 宽带和网线有什么区别?
  2. 【算法上车③】华为摄像头rpm签名校验并安装调试
  3. 仿微博、微信、qq 点击缩略图, 查看高清图 UI 组件
  4. 网页设计经典案例(Web)
  5. 小熊派折叠开发板(一)- 开发板介绍
  6. 微信小程序模板消息群发、无限制推送相关讲解
  7. 利用Javascript生成txt文本文件
  8. 计算机相关会议排名(二)
  9. 程序员的国庆大阅兵,太好好好好好好看了吧 ……
  10. 入门级选手浅写一下关于前端的知识点