数据分析初探——以2020百度西安交大大数据竞赛:传染病感染人数预测为例
文章目录
- 数据分析初探——以2020百度&西安交大大数据竞赛:传染病感染人数预测为例
- 比赛的大致情况
- 环境配置与相关包的配置
- anaconda和pytorch(顺带tensorflow)的配置
- GPU的配置
- 写这个Notebook的配置
- 数据处理
- 一些数据处理软件的选择
- 这次比赛的数据处理
- 比赛提供的数据格式
- 数据处理的主要步骤
- stata,SPSS数据处理的一些方法
- python pandas包的使用
- numpy 包操作array
- csv文件读写有关问题
- python 程序编写中发现的问题和tricks
- 简单可视化
- 数据编码与转换
- (1)热编码
- (2)时间序列处理
- (3)空间编码
- 机器学习和神经网络的初步了解
- sklearn包
- KNN和SVM
- 训练集划分和参数训练
- XGBoost
- LSTM
- 神经网络是怎样做预测的
- CNN
数据分析初探——以2020百度&西安交大大数据竞赛:传染病感染人数预测为例
emm第一次参加这种比赛试水,虽然初赛的具体情况没有公布,但是感觉已经翻车了ORZ(端午节最后一天冲榜的都太猛了嘤)。已经有将近一年没怎么写程序了,感觉在重新学习python,作为一只菜狗还在ctrlC ctrlZ之间游走,虽然如此本菜在大佬的帮助下还是学习到了很多的知识。想做一个总结&对学到的ML,数据分析,数据挖掘知识进行梳理&练习markdown的书写&整理之前收藏的乱糟糟的链接(这次的文本是用jupter notebook写的,jupyter属实好用:3 !)比赛相关程序是用python写的,但是下面的内容不仅限于此次比赛与python,但可能举例多举此次比赛的例子。python和juyter相关下载配置部署详见后面有关部分。
比赛的大致情况
这次比赛比赛流程和一般的数据分析比赛的流程差不多,可能多了一个时间有点长(将近2个月)的初赛,复赛是一个月时间,决赛取复赛前一定名次做答辩。每天限制提交2次预测结果,计算误差进行排名,取排名靠前者。报名已经截至了,具体的情况见官网
比赛的目标是用给出前45天5个城市的相关数据(包括感染人数,人流量密度,城市间人口流动量,城市内人口流动量,温度,湿度,风力,风向等)来预测往后30天5个城市,总计392个地区每日的的新增感染人数。
官网给了baseline但是是用的paddel的架构,而且效果不太好…
环境配置与相关包的配置
本来这个比赛的目的之一是推广百度自己的paddlepaddle的框架,但是这个不太常用,而且很多API不知道是啥,然后就没用这个。
anaconda和pytorch(顺带tensorflow)的配置
Anaconda是Python的一个开源发行版本,pytorch/tensorflow是神经网络常用的框架,这个上面有安装配置方式 我在安装时没按照这个来,但是一般来说anaconda的安装都是很简单的而且一般下载完后会自动配置环境变量,上网查到的方法也一般都能用(不管安装什么,都比较建议在CSDN等网站找一篇比较detailed,赞比较多,评论大多数都是感谢贴主的安装指南照着安装),安装完anaconda之后在anaconda navigator里或者prompt里安装pytorch,tensorflow,sklearn,numpy,pandas包都很容易。
需要注意:
1.如果你在使用SSR或者VPN科学地上网,可能会出现占用jupyter notebook打开的端口,把SSR关掉就能打开jupyter notebook了。
2.在安装pytorch/tensorflow的时候建议不要在prompt里面使用conda install下载,这样下载的是pytorch和tensorflow的CPU版本,对应的GPU版本下载在后续进行说明。
GPU的配置
配这个是真的麻烦啊啊啊啊,当时搞了好多天。一般电脑里用NVIDIA的显卡可以按照下面的步骤,(原来把详细是步骤放在了收藏夹,后来发现在收藏夹里蒸发了???但是大致步骤如下,大家可以在网上找比较靠谱的教程(有的官方文档提供的安装教程不太好用)然后考虑下面的tips安装)
1.cuda和cudnn的配置(参考网上的一些教程,官网上可以直接下载,但是要选择对版本,而且要在nvidia官网里注册)
2.gpu版本pytorch和tensorflow的下载(参考网上的教程/在navigator里可以下gpu版本)
3.pycuda可以试着用gpu跑普通的程序(还没有尝试,似乎效率不太高)
tips:
1.安装中最容易出问题的是版本不兼容,需要注意python的版本,cuda的版本,显卡的版本,和下载的pytorch/tensorflow的版本,一般来说都是不同版本向下兼容,向上不兼容的,具体的情况可以参考网上的安装说明/另一种方法是安装后对版本升级(升级python &&升级显卡 比如我的电脑用的GeForce的显卡,就安装了GeForce Experience自动升级)
2.tensorflow安装后使用时如果有no module named "tensorflow"的报错可能是因为安装路径不对,改这个很麻烦,建议卸载重下。
3.能使用tensorflow/pytorch之后可能会有报错“ailed to get convolution algorithm. This is probably because cuDNN failed to…”类似的报错,可能是因为显存不够,建议关闭之前的运行的网络/增加显存/简化网络…
写这个Notebook的配置
这个文档书写用到的是jupyter notebook,编辑目录等需要下载扩展文件nbextension具体下载方法,目录怎么搞
ps.jupyter notebook运行完一个文件后,在首页点前面的方块shutdowm以免占内存
数据处理
一些数据处理软件的选择
数据处理方法和相关软件有很多种,并不是越复杂越高端越好,需要根据实际情况进行选择。Excel一般情况下都是超好用的!
在先前发的文章中有提到过SPSS,stata(虽然只是吐槽一下)在这个的最后面,还有SAS啥的对于一般的数据处理,简单的数据分析(计量上的面板数据多元logit,probit回归)都可以handle,而且用stata,spss之类有数据显示页面,能直接看着整个数据操作,而且很好学,而且很多都和excel一样能直接按button操作,python和matlab需要写和csv,excel的接口,暂时不能看到完整的数据状态,如果写相关程序不熟练会耗费更多的精力或者感觉很烦躁。
R没学过,但是听说相关的时序处理的包比较多但是处理的数据量不如python,而且比python慢。And,SQL,去年暑假计划好要学SQL的,但是最后竟然下了好多次没有下下来就鸽了(可能现在科学上个网在官网下会比较快,或者找国内的镜像)。
然后就是这次比赛主要使用的python的pandas包,开始还觉得pandas不好用。。。后来我就真香了!pandas真香!
这次比赛的数据处理
比赛提供的数据格式
把比赛用的数据包下载之后整理了一下各个包里的数据格式,提供的数据没有做train-data和test_data的划分,数据的内容主要是下面几种:
density: 数据完整 时间(按小时) 地点(经纬度) 人口流动量
infection:数据完整 时间(按天) 地点(按区域(两个变量:城市&区域)) 新增感染
weather: 有缺失 时间(按小时) 地点(按城市) 温度、湿度(有百分比)、风向:九个方向(加上无风)
风速(<12km/h,16-24km/h,24-34km/h,三档&空白(包括无风和缺失值))
风力(0,1,2,3,4,❤️,无缺失值)
天气(cloudy moderaterain rain overcast sunny fog lightrain)
p.s.风力和天气无缺失值
migration:数据完整 时间(按天) 地点:出发——到达(城市) 城市间迁徙指数
transfer :数据完整 时间(日均小时)地点 :(城市内:出发经纬度,到达经纬度) 城市中迁移强度
grid_attr: 数据完整 地点:经纬度 属于该城市的哪个区域
数据处理的主要步骤
下面主要是在这次比赛中用到的,更系统一点的方法看这里
1.观察数据格式类型,了解数据内涵。
2.可视化。
(1)看基本走势,(这个很重要,我们第一次提交就是直接根据infection的走势拟合了一个函数直接预测,有人拟合的好就直接进复赛辽)
(2)数据之间的关系
(3)数据情况(描述性统计)(噪声大的考虑分箱等方法降噪,噪声特别大的舍弃这个特征)。
3.缺失值处理。
(1)直接删除一些具体的做法
(2)pandas fillina函数的使用具体看这里
(3)用KNN或者决策树等方法填充
5.异常值处理。
这次没怎么用…主要数据实在(全是噪声ORZ)
4.数据格式转换。
(1)数据的编码与转换,详细见后面的部分。
(2)数据格式转换,主要做CNN等神经网络的时候的输入格式的调整。
stata,SPSS数据处理的一些方法
这些功能都能在pandas中实现
混着用软件做数据处理属实弟弟行为,但是当时太菜了就没想太多ORZ,还是应该学好一样来做处理(首推pandas!)
因为开始的时候还不太会用pandas就想用其他的软件。开始使用SPSS,但是SPSS没有批量处理多个文件的能力,且无法提取符号和数字混合的变量(例如带%¥)
于是又用了stata,stata在查看数据窗口可以完成字符型变量与数值变量的转换,最妙的是
即使你不知道对应程序怎么写,在窗口上点按钮操作后会自动出现相应的代码,另外stata
支持正则表达式的提取,详见
1.数据类型的转换
声明数值变量的方法:gen variable=.
字符到数值的转换:
gen v5_change=.
replace v5_change=0 if v5==“Quiet”
replace v5_change=1if v5==“East”
在例如logit回归(附一个logistic回归结果回归系数&OR值解读and SPSS二项logistic回归的方法和解释)中需要将分类变量转化为哑变量,避免将分类元的数值作为倍数关系处理。(例如在分类变量:性别中,将男变为0,女变为1)。在python 的pandas库中有更好的处理方法在后面会提到。
2.缺失值处理
关于缺失值,实际上SPSS提供了取总体平均值,中位数,以及缺失值前后非缺失值平均数,中位数,线性估计。但是如果变量是int型,SPSS处理后会变成float。然后有人告诉我了一个神奇偏方(PS:此方法仅供娱乐):先按照上述方法补全缺失值再取整,SPSS中取整数参考(SPSS中:转换->计算变量->函数组->字符串->Char.substr())(取整方法:或者调整SPSS总体数据格式)
python pandas包的使用
pandas包除了在数据处理上有很多好用的函数外,值得一提的还有Pandas的数据存储方式 ,相较于使用列表\字典的嵌套更节省空间。
一般来说pandas包和numpy包是配合使用的。官方文档关于pandas包的学习强列推荐:这个里面有教程和习题,同样也可以当成工具书使用。
下面是一些写程序过程中常用的points,写在这里方便以后copy:
(1)读取csv文件加表头(不要学我这样的菜狗路径带中文):
import pandas as pd name=['date','hour','grid','infect','density','w_temp','w_humid','w_toward','w_speed','w_force','w_w','trans_1','trans_2'] data=pd.read_csv(r"C:\Users\10539\Desktop\数据竞赛\数据整理\except_migration.csv",header=None,names=name)#none表示原文件没有表头,header=i表示从第i+1行开始 data.head()#看前5排(加表头)| 0 | 0 | 0 | 0.0 | 951.8 | 16 | 76 | 0 | 1 | 1 | 3 | 8.2 | 7.8 |
| 0 | 0 | 1 | 0.0 | 987.2 | 16 | 76 | 0 | 1 | 1 | 3 | 17.9 | 14.1 |
| 0 | 0 | 2 | 0.0 | 665.5 | 16 | 76 | 0 | 1 | 1 | 3 | 8.7 | 8.9 |
| 0 | 0 | 3 | 0.0 | 818.0 | 16 | 76 | 0 | 1 | 1 | 3 | 5.7 | 7.9 |
| 0 | 0 | 4 | 0.0 | 1797.9 | 16 | 76 | 0 | 1 | 1 | 3 | 12.6 | 15.6 |
(2)选几排:
a=data[['date','hour']] a.head()| 0 | 0 |
| 0 | 0 |
| 0 | 0 |
| 0 | 0 |
| 0 | 0 |
(3)索引:
#方法1:loc 得到series或者dataframe b=data.loc[3,['date']] b date 0.0 Name: 3, dtype: float64 #方法2:[] 两种方法最后得到的值的形式不同 data['hour'][400]#先列后行 1(4)取值(数据类型不发生改变):
a=data[['date','hour']].values a array([[ 0, 0],[ 0, 0],[ 0, 0],...,[44, 23],[44, 23],[44, 23]], dtype=int64) a=data.loc[:,['date','hour']].values a array([[ 0, 0],[ 0, 0],[ 0, 0],...,[44, 23],[44, 23],[44, 23]], dtype=int64) a=data.loc[:,'date'].values#注意pandas中[]作为索引和表示列表的双重作用 a array([ 0, 0, 0, ..., 44, 44, 44], dtype=int64)(5)变量变换,以标准化为例(注意其中lambda函数的使用):
data[['density','w_temp','w_humid','trans_1','trans_2']]=data[['density','w_temp','w_humid','trans_1','trans_2']].transform(lambda x:(x-x.mean())/x.std())(6)去掉行/列
data=data.drop(['w_humid','w_toward','w_force'],axis=1) data.tail()#看后5排| 44 | 23 | 387 | 6.375000 | 143.4 | 7 | 1 | 1 | 0.5 | 0.8 |
| 44 | 23 | 388 | 41.083333 | 99.0 | 7 | 1 | 1 | 0.8 | 0.9 |
| 44 | 23 | 389 | 25.375000 | 0.2 | 7 | 1 | 1 | 0.0 | 0.0 |
| 44 | 23 | 390 | 29.000000 | 121.3 | 7 | 1 | 1 | 1.0 | 1.8 |
| 44 | 23 | 391 | 4.125000 | 157.7 | 7 | 1 | 1 | 1.1 | 1.7 |
(7)增加列:
trans_1=list(range(423360)) data['trans_1']=trans_1#trans data.head()| 0 | 0 | 0 | 0.0 | 951.8 | 16 | 1 | 3 | 0 | 7.8 |
| 0 | 0 | 1 | 0.0 | 987.2 | 16 | 1 | 3 | 1 | 14.1 |
| 0 | 0 | 2 | 0.0 | 665.5 | 16 | 1 | 3 | 2 | 8.9 |
| 0 | 0 | 3 | 0.0 | 818.0 | 16 | 1 | 3 | 3 | 7.9 |
| 0 | 0 | 4 | 0.0 | 1797.9 | 16 | 1 | 3 | 4 | 15.6 |
(8)改变行/列名:
#用字典的形式,不改变存储 data=data.rename(columns={'trans_1':1}) data.head()| 0 | 0 | 0 | 0.0 | 951.8 | 16 | 1 | 3 | 0 | 7.8 |
| 0 | 0 | 1 | 0.0 | 987.2 | 16 | 1 | 3 | 1 | 14.1 |
| 0 | 0 | 2 | 0.0 | 665.5 | 16 | 1 | 3 | 2 | 8.9 |
| 0 | 0 | 3 | 0.0 | 818.0 | 16 | 1 | 3 | 3 | 7.9 |
| 0 | 0 | 4 | 0.0 | 1797.9 | 16 | 1 | 3 | 4 | 15.6 |
(9)按条件索引:
wa=data.loc[lambda x :x['grid']==0] wa.head()#注意新的dataframe每行的index保持原状| 0 | 0 | 0 | 0.0 | 951.8 | 16 | 1 | 3 | 0 | 7.8 |
| 0 | 1 | 0 | 0.0 | 951.8 | 15 | 1 | 3 | 392 | 8.4 |
| 0 | 2 | 0 | 0.0 | 951.8 | 14 | 1 | 2 | 784 | 7.7 |
| 0 | 3 | 0 | 0.0 | 951.8 | 14 | 1 | 2 | 1176 | 5.5 |
| 0 | 4 | 0 | 0.0 | 951.8 | 14 | 0 | 3 | 1568 | 12.2 |
(10)按行、列遍历:详见
(11)分类函数groupby
#这个函数是真的好用 grid_pre=data.groupby('grid') grid_pre#把data按照相同的grid进行划分 <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000020A6F9DC608> x=grid_pre.get_group(200)#取grid=200的分组 x| 0 | 0 | 200 | 0.000000 | 252.1 | 15 | 96 | 7 | 1 | 1 | 3 | 4.3 | 4.3 |
| 0 | 1 | 200 | 0.000000 | 252.1 | 13 | 96 | 7 | 1 | 1 | 3 | 4.4 | 4.8 |
| 0 | 2 | 200 | 0.000000 | 252.1 | 14 | 97 | 7 | 1 | 2 | 3 | 2.5 | 2.4 |
| 0 | 3 | 200 | 0.000000 | 252.1 | 15 | 92 | 5 | 1 | 1 | 3 | 3.3 | 3.0 |
| 0 | 4 | 200 | 0.000000 | 252.1 | 16 | 90 | 5 | 1 | 1 | 3 | 4.3 | 5.3 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 44 | 19 | 200 | 496.583333 | 375.7 | 16 | 71 | 0 | 0 | 0 | 1 | 26.5 | 24.6 |
| 44 | 20 | 200 | 495.666667 | 375.7 | 13 | 71 | 2 | 0 | 0 | 1 | 17.0 | 16.9 |
| 44 | 21 | 200 | 494.750000 | 375.7 | 13 | 71 | 2 | 0 | 0 | 1 | 12.1 | 17.2 |
| 44 | 22 | 200 | 493.833333 | 375.7 | 11 | 71 | 2 | 0 | 0 | 1 | 11.7 | 11.3 |
| 44 | 23 | 200 | 492.916667 | 375.7 | 13 | 71 | 2 | 0 | 0 | 1 | 5.9 | 5.4 |
1080 rows × 13 columns
需要注意的是groupby后的get_group得到的新dataframe里面数据的Index还是原来的index(200,592,984…)没有重新排
numpy 包操作array
(1)写入读出:
import numpy as np trans=np.load(r'XXXX'); np.save(r'XXXX',trans)(2)看形状:
trans.shape(3)list,array相互转化:
a=[[[1,5],[2,6]],[[3,7],[4,8]]] a=np.array(a) #np.array(a)不改变a的内存 a.shape (2, 2, 2) b=list(a)(4)索引:
a[:,:,0]#抽出的保持原格式 array([[1, 2],[3, 4]]) a[:][1][0][1]=9#冒号和上面的冒号意思不同,可以将[:]看作不存在 a[1][0][1] 9 a[:][1][1] array([4, 8])(5)和list对比
(因为两者之间有区别在进行数据处理的时候,特别是多维度可能出现list里面套array的时候需要格外注意,尽量避免这种情况)
(6)reshape&flatten函数(不改变内存)
a.reshape(2,4)#高维到低维是顺着排的,各维度之间的转换需要有整除关系 array([[1, 5, 2, 6],[3, 9, 4, 8]]) a.flatten()#flatten可以排成一维 array([1, 5, 2, 6, 3, 9, 4, 8])(7)合并:
a=[[1,2],[3,4]] b=[[5,6],[7,8]] x=np.concatenate((a,b),axis=0)#按维度 x array([[1, 2],[3, 4],[5, 6],[7, 8]]) x=np.concatenate((a,b),axis=1) x array([[1, 2, 5, 6],[3, 4, 7, 8]]) y=np.c_[a,b]#按列 y array([[1, 2, 5, 6],[3, 4, 7, 8]])(7)初始化
migration_data = np.zeros((6,6,6), dtype='float')(8)不同维度互换(eg:(2,3,4)矩阵换成(4,3,2))
a=np.array([[[1,2,3,4],[5,6,7,8],[9,10,11,12]],[[13,14,15,16],[17,18,19,20],[21,22,23,24]]]) a.shape (2, 3, 4) b= np.transpose(a,(2,1,0))#后面的(2,1,0)表示一个置换,即原来的shape:(2,3,4)中0号位置('2')现在在2号位置,1号位置('3')在1号位置 b.shape (4, 3, 2)csv文件读写有关问题
#写入list import csv with open(r'路径','a+',newline='') as f:#a+表示接着在文件后面写入writer=csv.writer(f)writer.writerows(data)下面是一个读取csv存入list的例子,在读取后成行放入列表。
需要注意的是假如没有for line in csv_reader:后面的temp=float(x) for x in line,直接存入points时得到的是包含str的List,且其中的逗号分隔符(,)也算在str里面(当然,也可以使用Dictreader按字典形式读取)
python 程序编写中发现的问题和tricks
(1)关于利用list&dict写循环和函数(这段代码没头没尾的仅提供形式)
Cities = ["city_A", "city_B", "city_C", "city_D", "city_E"] CitiesIndex ={'A':0,'B':1,'C':2,'D':3,'E':4}#索引方式: dict[key]def find_place(direction:int) -> int:start = CitiesIndex[direction[0][-1]]#direction是list里面嵌套一个list end = CitiesIndex[direction[1][-1]]return start * 4 + (end if start > end else end-1)count = 0 for city in Cities:with open("train_data/"+city+"/migration.csv") as f:#利用list批量录入csv文件csv_reader = csv.reader(f,delimiter=',')for line in csv_reader:date = calcu_days(int(line[0]))index = find_place(line[1:3])for i in range(24):for j in range(grid_num[count]):migration_data[date * 24 + i, sum(grid_num[:count]) + j, index] += float(line[-1])print(sum(grid_num[:count]))count+=1(2)attention:关于Python中循环嵌套的问题:
在多层循环中建议简单的循环放在里面,复杂的循环放在外面。例如:读取csv文件的循环放在外面,for i in range(5):这样的循环放在里面。
因为python 的for 循环的内层循环是不支持循环读取文件等较复杂循环的。如果
(3)list的enumerate遍历
point=[13,56,12,44] for index,row in enumerate(point):print(index,row) 0 13 1 56 2 12 3 44(4)zip的用法
zip的用法多样,在上面的enumerate不方便用的时候还可以利用range(len(list_a))和zip构成字典进行循环
在组成字典和元组中都很方便更多zip方法:
(5)lambda 用法
y=lambda x:2*x+1 y(2) 5简单可视化
import matplotlib.pyplot as plt#借助 matplotlib包(1)画dataframe里的总图
data.plot() #一般来说都没有标准化画出来的总图乱糟糟作用不大 plt.show()(2)分开画
data['infect'].plot()#默认x轴是index #加标题,图例,坐标轴: plt.plot(lista) plt.plot(listb) plt.title('XXX')#一般不支持有中文 plt.xlable('XX') plt.ylable('XXX') plt.legend(['a','b']) plt.show() #plt画图顺序排legend,一般plt画图a,b最后plt.show都呈现在同一张图里 <matplotlib.axes._subplots.AxesSubplot at 0x18c05fb3908> plt.plot(data['grid'].values,data['infect'].values)#plot(x,y) [<matplotlib.lines.Line2D at 0x2eb218a88c8>](3)散点图:
data.plot.scatter('density','trans_1') <matplotlib.axes._subplots.AxesSubplot at 0x18c05593f48>(4)箱形图:
对箱型图的理解看这里
数据编码与转换
(1)热编码
one-hot热编码:将分类变量变成多个0-1变量
关于连续函数离散化,分类指标哑元化详见
pandas的get_dummies函数
dataa=pd.get_dummies(data,columns=['w_w']) dataa.head()| 0 | 0 | 0 | 0.0 | 951.8 | 16 | 1 | 0 | 7.8 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| 0 | 0 | 1 | 0.0 | 987.2 | 16 | 1 | 1 | 14.1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| 0 | 0 | 2 | 0.0 | 665.5 | 16 | 1 | 2 | 8.9 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| 0 | 0 | 3 | 0.0 | 818.0 | 16 | 1 | 3 | 7.9 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| 0 | 0 | 4 | 0.0 | 1797.9 | 16 | 1 | 4 | 15.6 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
(2)时间序列处理
pandas里有看这里的后面几个cap,在脉冲神经网络中会对时间有其他的编码方式。
(3)空间编码
因为这次数据中有很多point to point 的数据,但是我们在操作的过程中处理的不太好(本来想到过用连接矩阵,但是与其它的数据格式不太兼容)。
具体的一些空间编码的方向可以参考这里
机器学习和神经网络的初步了解
开始的时候用了sklearn做天气这些外源变量的回归,还尝试使用了XGBoost做了感染人数的回归,但是总体的回归效果不太好,就没搞sklearn了。
后来用了LSTM长短期记忆做回归,但是效果也不好,最后用了CNN卷积神经网络效果才好一点。
sklearn包
sklearn包可以直接在anaconda prompt里直接下载,里面有线性回归到随机森林的一系列可以直接调用的相关函数。一般单核单线程,关于这个包的学习首推中文文档
KNN和SVM
KNN和SVM原本是两种分类算法。SVM通过超平面和核做分类划分,KNN则直接计算距离,根据距离远近做划分,具体的内容看上面的文档,网上的大多数博客也写的很清楚。
还可以借助KNN对分类变量做回归:
from sklearn.neighbors import KNeighborsClassifier X=data[['date','hour']] X=X.values y=data['w_speed'] y=y.values #y=y.astype(np.int16) neigh =KNeighborsClassifier(n_neighbors=2) neigh.fit(X,y) predict_y= neigh.predict(predict_X)因为KNN是根据距离做的划分,但是不同维度的距离可能内涵不同,或者单位不统一,从而容易导致分类不准确,可以通过改变各维度的比重进行优化具体看这里
SVM里面的SVR可以用来做回归
from sklearn.svm import SVR X=data[['date','hour']] X=X.values y=data['w_temp'] y=y.values model = SVR() model.fit(X,y) predict_y = model.predict(predict_X)训练集划分和参数训练
主要是下面两个函数,具体看上面的sklearn文档,下面两个函数还可以用在XGBoost上具体的看下面做房价预测的完整代码例子
from sklearn.model_selection import GridSearchCV from sklearn.model_selection import ShuffleSplit cv_split = ShuffleSplit(n_splits=6, train_size=0.7, test_size=0.2) #参数集写成字典形式 grid_params = dict(max_depth = [4, 5, 6, 7],learning_rate = np.linspace(0.03, 0.3, 10),n_estimators = [100, 200] ) grid = GridSearchCV(model, grid_params, cv=cv_split, scoring='neg_mean_squared_error') grid.fit(X, y) #看结果 print(model.best_params_) print('rmse:', (-grid_model.best_score_) ** 0.5)XGBoost
XGBoost在一般的分类中超好用,主要原理是多个决策树的拼接和权重分配。具体原理看这里
还有做房价预测的完整代码例子
在回归中使用XGBoost中的XGBregressor函数参数含义看这里:
#这里用的是xgboost做回归预测的函数XGBRegressor,方法和一般的回归模型一样 import xgboostmodel=xgboost.XGBRegressor(objective ='reg:squarederror') X=data[['date','hour']] X=X.values y=data['w_temp'] y=y.values model=model.fit(X,y) pre=model.predict(predict_X)XGBoost还能做特征选取:
from xgboost import plot_importance print(model.feature_importances_)#选择得到的比重大的除了searchCV外的调参策略
LSTM
关于LSTM和CNN之类原理的强烈建议看这个建议从头开始看
LSTM源自RNN,RNN具体看上面,结构上还是seq2seq结构
LSTM和CNN具体网络结构看这里
网络是用keras搭的,怎么搭看这里强烈推荐keras文档
keras文档是真的良心文档!
神经网络是怎样做预测的
在上面的介绍中我们看到网络有隐藏层(比如CNN的卷积核)里面的参数通过训练集的输入与结果的对比不断优化隐藏层的参数,从而得到较好的隐藏层,这时候输入数据通过现有的隐藏层就能得到较好的结果。
ps.看最下面CNN下面的表最后一列param是每层参数的个数,可见网络的参数很多,如果要拟合的很好,需要大量的训练数据!
LSTM同样能做多步多变量预测(具体的网上有),上面的就是前80组数据预测后面一组数据,要实现对后面10组数据的预测可以通过循环的方式完成,每次把预测到的数据加入之前的80个输入中,把之前80个输入数据组的最开始的数据删除。类似于数据结构队列的亚子。
除此之外如果知道下一组数据的8个特征中的两个,要预测另外6个特征,则可以把model.add(Dense(8))变为model.add(Dense(6)),testX不变,testY从8个数去掉两个已知的变成6个数。如果要预测后面10组数据,则在上面的循环中每次要把预测结果加上两个已知数据,再放入下一次输入的80组数据中。
CNN
(先看这个!)CNN的具体原理网上有,指路B站3Blue1Brown 的CNN视频(…B站真的是学习站…要不是因为总喜欢打开B站看别的…我是不会卸载的!)
原理、结构、怎么搭参考上面的LSTM给的网站,里面都有CNN的内容。和LSTM有相似之处。但是数据维度发生了改变,下面的网络也是用keras搭的,具体的看上面LSTM给的keras中文文档网址中搜Conv2D等
#先放个网络 import tensorflow as tf input_shape = (48, 392, 7) model = tf.keras.models.Sequential([tf.keras.layers.Conv2D(64, (24,1),activation='relu', input_shape=input_shape),#tf.keras.layers.Conv2D(64, (2,2), padding='same',activation='relu'),tf.keras.layers.Conv2D(64, (3,1),strides=(2,1), activation='relu'),tf.keras.layers.Dropout(.5),tf.keras.layers.Conv2D(32, (3,3),padding='same', activation='relu'),tf.keras.layers.Dropout(.5),tf.keras.layers.Conv2D(32, (12,1), activation='relu'),tf.keras.layers.Reshape((392,32)),tf.keras.layers.Dropout(.1),tf.keras.layers.Dense(21),tf.keras.layers.Dropout(.1),tf.keras.layers.Dense(14),tf.keras.layers.Dropout(.1),tf.keras.layers.Dense(7)#tf.keras.layers.Reshape((392,7)) ]) model.compile(optimizer='adam',loss='mean_squared_error',metrics=[tf.keras.metrics.RootMeanSquaredError()]) model.summary() Model: "sequential_1" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_5 (Conv2D) (None, 25, 392, 64) 10816 _________________________________________________________________ conv2d_6 (Conv2D) (None, 25, 392, 64) 16448 _________________________________________________________________ conv2d_7 (Conv2D) (None, 12, 392, 64) 12352 _________________________________________________________________ dropout_5 (Dropout) (None, 12, 392, 64) 0 _________________________________________________________________ conv2d_8 (Conv2D) (None, 12, 392, 32) 18464 _________________________________________________________________ dropout_6 (Dropout) (None, 12, 392, 32) 0 _________________________________________________________________ conv2d_9 (Conv2D) (None, 1, 392, 32) 12320 _________________________________________________________________ reshape_1 (Reshape) (None, 392, 32) 0 _________________________________________________________________ dropout_7 (Dropout) (None, 392, 32) 0 _________________________________________________________________ dense_3 (Dense) (None, 392, 21) 693 _________________________________________________________________ dropout_8 (Dropout) (None, 392, 21) 0 _________________________________________________________________ dense_4 (Dense) (None, 392, 14) 308 _________________________________________________________________ dropout_9 (Dropout) (None, 392, 14) 0 _________________________________________________________________ dense_5 (Dense) (None, 392, 7) 105 ================================================================= Total params: 71,506 Trainable params: 71,506 Non-trainable params: 0 _________________________________________________________________ model.fit(X,Y,batch_size=64,epochs=135) test = model.predict([temp])总结
以上是生活随笔为你收集整理的数据分析初探——以2020百度西安交大大数据竞赛:传染病感染人数预测为例的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 如何打开华为鸿蒙系统HarmonyOS虚
- 下一篇: input 搜索 实时搜索