数据分析初探——以2020百度&西安交大大数据竞赛:传染病感染人数预测为例

    技术2023-05-20  85

    文章目录

    数据分析初探——以2020百度&西安交大大数据竞赛:传染病感染人数预测为例比赛的大致情况环境配置与相关包的配置anaconda和pytorch(顺带tensorflow)的配置GPU的配置写这个Notebook的配置 数据处理一些数据处理软件的选择这次比赛的数据处理比赛提供的数据格式数据处理的主要步骤stata,SPSS数据处理的一些方法python pandas包的使用numpy 包操作arraycsv文件读写有关问题python 程序编写中发现的问题和tricks简单可视化数据编码与转换(1)热编码(2)时间序列处理(3)空间编码 机器学习和神经网络的初步了解sklearn包KNN和SVM训练集划分和参数训练 XGBoostLSTM神经网络是怎样做预测的 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的安装都是很简单的而且一般下载完后会自动配置环境变量,上网查到的方法也一般都能用(不管安装什么,都比较建议在等网站找一篇比较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排(加表头) datehourgridinfectdensityw_tempw_humidw_towardw_speedw_forcew_wtrans_1trans_200000.0951.8167601138.27.810010.0987.21676011317.914.120020.0665.5167601138.78.930030.0818.0167601135.77.940040.01797.91676011312.615.6

    (2)选几排:

    a=data[['date','hour']] a.head() datehour000100200300400

    (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排 datehourgridinfectdensityw_tempw_speedw_wtrans_1trans_242335544233876.375000143.47110.50.8423356442338841.08333399.07110.80.9423357442338925.3750000.27110.00.0423358442339029.000000121.37111.01.842335944233914.125000157.77111.11.7

    (7)增加列:

    trans_1=list(range(423360)) data['trans_1']=trans_1#trans data.head() datehourgridinfectdensityw_tempw_speedw_wtrans_1trans_200000.0951.8161307.810010.0987.21613114.120020.0665.5161328.930030.0818.0161337.940040.01797.91613415.6

    (8)改变行/列名:

    #用字典的形式,不改变存储 data=data.rename(columns={'trans_1':1}) data.head() datehourgridinfectdensityw_tempw_speedw_w1trans_200000.0951.8161307.810010.0987.21613114.120020.0665.5161328.930030.0818.0161337.940040.01797.91613415.6

    (9)按条件索引:

    wa=data.loc[lambda x :x['grid']==0] wa.head()#注意新的dataframe每行的index保持原状 datehourgridinfectdensityw_tempw_speedw_w1trans_200000.0951.8161307.83920100.0951.815133928.47840200.0951.814127847.711760300.0951.8141211765.515680400.0951.81403156812.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 datehourgridinfectdensityw_tempw_humidw_towardw_speedw_forcew_wtrans_1trans_2200002000.000000252.1159671134.34.3592012000.000000252.1139671134.44.8984022000.000000252.1149771232.52.41376032000.000000252.1159251133.33.01768042000.000000252.1169051134.35.3..........................................4216004419200496.583333375.71671000126.524.64219924420200495.666667375.71371200117.016.94223844421200494.750000375.71371200112.117.24227764422200493.833333375.71171200111.711.34231684423200492.916667375.7137120015.95.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的时候需要格外注意,尽量避免这种情况)

    b=[[[1,5],[2,6]],[[3,7],[4,8]]] #b[:,:,0]#报错,无这种索引方式 b[:][1][0]#和array一样 #list没有shape,array不能append [3, 7] b*2#list外面的乘法表示copy [[[1, 5], [2, 6]], [[3, 7], [4, 8]], [[1, 5], [2, 6]], [[3, 7], [4, 8]]] a*2#array表示数乘 array([[[ 2, 10], [ 4, 12]], [[ 6, 18], [ 8, 16]]])

    (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((666), 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按字典形式读取)

    import csv points=[] with open(r"C:\Users\10539\Desktop\数据竞赛\train_data\density_filled.csv")as f: csv_reader=csv.reader(f) for line in csv_reader: temp=[float(x) for x in line] points.append(temp)#直接读都是str

    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 循环的内层循环是不支持循环读取文件等较复杂循环的。如果

    for i in range(5): for city in Cities: csv.DictReaderXXXX ...... #这样外面的for i 循环只会运行一次,但是可能不会报错

    (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方法:

    #(a)构成元组 a=[1,2,3,4] b=[5,6,7,8] c=zip(a,b)#c:[(1,5),(2,6),(3,7),(4,8)] for (x,y) in c:print(x+y) 6 8 10 12 #(b)构成字典 d=dict(zip(a,b)) d {1: 5, 2: 6, 3: 7, 4: 8}

    (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)箱形图: 对箱型图的理解看这里

    data[['density','trans_1']].boxplot()#数据情况属实不好 <matplotlib.axes._subplots.AxesSubplot at 0x20a70841cc8>

    数据编码与转换

    (1)热编码

    one-hot热编码:将分类变量变成多个0-1变量 关于连续函数离散化,分类指标哑元化详见

    pandas的get_dummies函数

    dataa=pd.get_dummies(data,columns=['w_w']) dataa.head() datehourgridinfectdensityw_tempw_speed1trans_2w_w_0w_w_1w_w_2w_w_3w_w_4w_w_5w_w_600000.0951.816107.8000100010010.0987.2161114.1000100020020.0665.516128.9000100030030.0818.016137.9000100040040.01797.9161415.60001000
    (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 xgboost model=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个时间的数据(包括感染人数,天气等8个数据)得到下一个时间点的8个数据的值(对下一个时间点的8个数据处于未知状态),也就是前80个预测后面一个 from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM from keras.layers import Flatten from keras.layers import Dropout model = Sequential() model.add(LSTM(64, input_shape=(80,8),return_sequences=True))#输入80组数据,每组数据8个特征 model.add(Dropout(0.5)) model.add(LSTM(64,return_sequences=True))#特征变为64个还是80组数据return_sequence这个参数很关键保证了网络output的格式,一般在全连接层前设置为True model.add(LSTM(32,return_sequences=False))#特征变成32个,数据组数减小 model.add(Dense(8))#全连接层得到下一组数据 model.compile(loss='mae', optimizer='adam')#误差mae,优化算法adam model.fit(train_x0, train_y0, epochs=10, batch_size=200) #validation_data=(test_x0, test_y0), verbose=2, shuffle=False)#测试集 predict_y0=model.predict(predict_x0)

    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])
    Processed: 0.015, SQL: 9