数据分析初探——以2020百度西安交大大数据竞赛:传染病感染人数预测为例
文章目錄
- 數(shù)據(jù)分析初探——以2020百度&西安交大大數(shù)據(jù)競(jìng)賽:傳染病感染人數(shù)預(yù)測(cè)為例
- 比賽的大致情況
- 環(huán)境配置與相關(guān)包的配置
- anaconda和pytorch(順帶tensorflow)的配置
- GPU的配置
- 寫這個(gè)Notebook的配置
- 數(shù)據(jù)處理
- 一些數(shù)據(jù)處理軟件的選擇
- 這次比賽的數(shù)據(jù)處理
- 比賽提供的數(shù)據(jù)格式
- 數(shù)據(jù)處理的主要步驟
- stata,SPSS數(shù)據(jù)處理的一些方法
- python pandas包的使用
- numpy 包操作array
- csv文件讀寫有關(guān)問題
- python 程序編寫中發(fā)現(xiàn)的問題和tricks
- 簡(jiǎn)單可視化
- 數(shù)據(jù)編碼與轉(zhuǎn)換
- (1)熱編碼
- (2)時(shí)間序列處理
- (3)空間編碼
- 機(jī)器學(xué)習(xí)和神經(jīng)網(wǎng)絡(luò)的初步了解
- sklearn包
- KNN和SVM
- 訓(xùn)練集劃分和參數(shù)訓(xùn)練
- XGBoost
- LSTM
- 神經(jīng)網(wǎng)絡(luò)是怎樣做預(yù)測(cè)的
- CNN
數(shù)據(jù)分析初探——以2020百度&西安交大大數(shù)據(jù)競(jìng)賽:傳染病感染人數(shù)預(yù)測(cè)為例
?emm第一次參加這種比賽試水,雖然初賽的具體情況沒有公布,但是感覺已經(jīng)翻車了ORZ(端午節(jié)最后一天沖榜的都太猛了嚶)。已經(jīng)有將近一年沒怎么寫程序了,感覺在重新學(xué)習(xí)python,作為一只菜狗還在ctrlC ctrlZ之間游走,雖然如此本菜在大佬的幫助下還是學(xué)習(xí)到了很多的知識(shí)。想做一個(gè)總結(jié)&對(duì)學(xué)到的ML,數(shù)據(jù)分析,數(shù)據(jù)挖掘知識(shí)進(jìn)行梳理&練習(xí)markdown的書寫&整理之前收藏的亂糟糟的鏈接(這次的文本是用jupter notebook寫的,jupyter屬實(shí)好用:3 !)比賽相關(guān)程序是用python寫的,但是下面的內(nèi)容不僅限于此次比賽與python,但可能舉例多舉此次比賽的例子。python和juyter相關(guān)下載配置部署詳見后面有關(guān)部分。
比賽的大致情況
? 這次比賽比賽流程和一般的數(shù)據(jù)分析比賽的流程差不多,可能多了一個(gè)時(shí)間有點(diǎn)長(將近2個(gè)月)的初賽,復(fù)賽是一個(gè)月時(shí)間,決賽取復(fù)賽前一定名次做答辯。每天限制提交2次預(yù)測(cè)結(jié)果,計(jì)算誤差進(jìn)行排名,取排名靠前者。報(bào)名已經(jīng)截至了,具體的情況見官網(wǎng)
? 比賽的目標(biāo)是用給出前45天5個(gè)城市的相關(guān)數(shù)據(jù)(包括感染人數(shù),人流量密度,城市間人口流動(dòng)量,城市內(nèi)人口流動(dòng)量,溫度,濕度,風(fēng)力,風(fēng)向等)來預(yù)測(cè)往后30天5個(gè)城市,總計(jì)392個(gè)地區(qū)每日的的新增感染人數(shù)。
?官網(wǎng)給了baseline但是是用的paddel的架構(gòu),而且效果不太好…
環(huán)境配置與相關(guān)包的配置
本來這個(gè)比賽的目的之一是推廣百度自己的paddlepaddle的框架,但是這個(gè)不太常用,而且很多API不知道是啥,然后就沒用這個(gè)。
anaconda和pytorch(順帶tensorflow)的配置
Anaconda是Python的一個(gè)開源發(fā)行版本,pytorch/tensorflow是神經(jīng)網(wǎng)絡(luò)常用的框架,這個(gè)上面有安裝配置方式 我在安裝時(shí)沒按照這個(gè)來,但是一般來說anaconda的安裝都是很簡(jiǎn)單的而且一般下載完后會(huì)自動(dòng)配置環(huán)境變量,上網(wǎng)查到的方法也一般都能用(不管安裝什么,都比較建議在CSDN等網(wǎng)站找一篇比較detailed,贊比較多,評(píng)論大多數(shù)都是感謝貼主的安裝指南照著安裝),安裝完anaconda之后在anaconda navigator里或者prompt里安裝pytorch,tensorflow,sklearn,numpy,pandas包都很容易。
需要注意:
1.如果你在使用SSR或者VPN科學(xué)地上網(wǎng),可能會(huì)出現(xiàn)占用jupyter notebook打開的端口,把SSR關(guān)掉就能打開jupyter notebook了。
2.在安裝pytorch/tensorflow的時(shí)候建議不要在prompt里面使用conda install下載,這樣下載的是pytorch和tensorflow的CPU版本,對(duì)應(yīng)的GPU版本下載在后續(xù)進(jìn)行說明。
GPU的配置
配這個(gè)是真的麻煩啊啊啊啊,當(dāng)時(shí)搞了好多天。一般電腦里用NVIDIA的顯卡可以按照下面的步驟,(原來把詳細(xì)是步驟放在了收藏夾,后來發(fā)現(xiàn)在收藏夾里蒸發(fā)了???但是大致步驟如下,大家可以在網(wǎng)上找比較靠譜的教程(有的官方文檔提供的安裝教程不太好用)然后考慮下面的tips安裝)
1.cuda和cudnn的配置(參考網(wǎng)上的一些教程,官網(wǎng)上可以直接下載,但是要選擇對(duì)版本,而且要在nvidia官網(wǎng)里注冊(cè))
2.gpu版本pytorch和tensorflow的下載(參考網(wǎng)上的教程/在navigator里可以下gpu版本)
3.pycuda可以試著用gpu跑普通的程序(還沒有嘗試,似乎效率不太高)
tips:
1.安裝中最容易出問題的是版本不兼容,需要注意python的版本,cuda的版本,顯卡的版本,和下載的pytorch/tensorflow的版本,一般來說都是不同版本向下兼容,向上不兼容的,具體的情況可以參考網(wǎng)上的安裝說明/另一種方法是安裝后對(duì)版本升級(jí)(升級(jí)python &&升級(jí)顯卡 比如我的電腦用的GeForce的顯卡,就安裝了GeForce Experience自動(dòng)升級(jí))
2.tensorflow安裝后使用時(shí)如果有no module named "tensorflow"的報(bào)錯(cuò)可能是因?yàn)榘惭b路徑不對(duì),改這個(gè)很麻煩,建議卸載重下。
3.能使用tensorflow/pytorch之后可能會(huì)有報(bào)錯(cuò)“ailed to get convolution algorithm. This is probably because cuDNN failed to…”類似的報(bào)錯(cuò),可能是因?yàn)轱@存不夠,建議關(guān)閉之前的運(yùn)行的網(wǎng)絡(luò)/增加顯存/簡(jiǎn)化網(wǎng)絡(luò)…
寫這個(gè)Notebook的配置
這個(gè)文檔書寫用到的是jupyter notebook,編輯目錄等需要下載擴(kuò)展文件nbextension具體下載方法,目錄怎么搞
ps.jupyter notebook運(yùn)行完一個(gè)文件后,在首頁點(diǎn)前面的方塊shutdowm以免占內(nèi)存
數(shù)據(jù)處理
一些數(shù)據(jù)處理軟件的選擇
?數(shù)據(jù)處理方法和相關(guān)軟件有很多種,并不是越復(fù)雜越高端越好,需要根據(jù)實(shí)際情況進(jìn)行選擇。Excel一般情況下都是超好用的!
?在先前發(fā)的文章中有提到過SPSS,stata(雖然只是吐槽一下)在這個(gè)的最后面,還有SAS啥的對(duì)于一般的數(shù)據(jù)處理,簡(jiǎn)單的數(shù)據(jù)分析(計(jì)量上的面板數(shù)據(jù)多元logit,probit回歸)都可以handle,而且用stata,spss之類有數(shù)據(jù)顯示頁面,能直接看著整個(gè)數(shù)據(jù)操作,而且很好學(xué),而且很多都和excel一樣能直接按button操作,python和matlab需要寫和csv,excel的接口,暫時(shí)不能看到完整的數(shù)據(jù)狀態(tài),如果寫相關(guān)程序不熟練會(huì)耗費(fèi)更多的精力或者感覺很煩躁。
?R沒學(xué)過,但是聽說相關(guān)的時(shí)序處理的包比較多但是處理的數(shù)據(jù)量不如python,而且比python慢。And,SQL,去年暑假計(jì)劃好要學(xué)SQL的,但是最后竟然下了好多次沒有下下來就鴿了(可能現(xiàn)在科學(xué)上個(gè)網(wǎng)在官網(wǎng)下會(huì)比較快,或者找國內(nèi)的鏡像)。
?然后就是這次比賽主要使用的python的pandas包,開始還覺得pandas不好用。。。后來我就真香了!pandas真香!
這次比賽的數(shù)據(jù)處理
比賽提供的數(shù)據(jù)格式
?把比賽用的數(shù)據(jù)包下載之后整理了一下各個(gè)包里的數(shù)據(jù)格式,提供的數(shù)據(jù)沒有做train-data和test_data的劃分,數(shù)據(jù)的內(nèi)容主要是下面幾種:
density: 數(shù)據(jù)完整 時(shí)間(按小時(shí)) 地點(diǎn)(經(jīng)緯度) 人口流動(dòng)量
infection:數(shù)據(jù)完整 時(shí)間(按天) 地點(diǎn)(按區(qū)域(兩個(gè)變量:城市&區(qū)域)) 新增感染
weather: 有缺失 時(shí)間(按小時(shí)) 地點(diǎn)(按城市) 溫度、濕度(有百分比)、風(fēng)向:九個(gè)方向(加上無風(fēng))
???? 風(fēng)速(<12km/h,16-24km/h,24-34km/h,三檔&空白(包括無風(fēng)和缺失值))
???? 風(fēng)力(0,1,2,3,4,??,無缺失值)
???? 天氣(cloudy moderaterain rain overcast sunny fog lightrain) ????
p.s.風(fēng)力和天氣無缺失值
migration:數(shù)據(jù)完整 時(shí)間(按天) 地點(diǎn):出發(fā)——到達(dá)(城市) 城市間遷徙指數(shù)
transfer :數(shù)據(jù)完整 時(shí)間(日均小時(shí))地點(diǎn) :(城市內(nèi):出發(fā)經(jīng)緯度,到達(dá)經(jīng)緯度) 城市中遷移強(qiáng)度
grid_attr: 數(shù)據(jù)完整 地點(diǎn):經(jīng)緯度 屬于該城市的哪個(gè)區(qū)域
數(shù)據(jù)處理的主要步驟
下面主要是在這次比賽中用到的,更系統(tǒng)一點(diǎn)的方法看這里
1.觀察數(shù)據(jù)格式類型,了解數(shù)據(jù)內(nèi)涵。
2.可視化。
?(1)看基本走勢(shì),(這個(gè)很重要,我們第一次提交就是直接根據(jù)infection的走勢(shì)擬合了一個(gè)函數(shù)直接預(yù)測(cè),有人擬合的好就直接進(jìn)復(fù)賽遼)
?(2)數(shù)據(jù)之間的關(guān)系
?(3)數(shù)據(jù)情況(描述性統(tǒng)計(jì))(噪聲大的考慮分箱等方法降噪,噪聲特別大的舍棄這個(gè)特征)。
3.缺失值處理。
?(1)直接刪除一些具體的做法
?(2)pandas fillina函數(shù)的使用具體看這里
?(3)用KNN或者決策樹等方法填充
5.異常值處理。
?這次沒怎么用…主要數(shù)據(jù)實(shí)在(全是噪聲ORZ)
4.數(shù)據(jù)格式轉(zhuǎn)換。
?(1)數(shù)據(jù)的編碼與轉(zhuǎn)換,詳細(xì)見后面的部分。
?(2)數(shù)據(jù)格式轉(zhuǎn)換,主要做CNN等神經(jīng)網(wǎng)絡(luò)的時(shí)候的輸入格式的調(diào)整。
stata,SPSS數(shù)據(jù)處理的一些方法
這些功能都能在pandas中實(shí)現(xiàn)
?混著用軟件做數(shù)據(jù)處理屬實(shí)弟弟行為,但是當(dāng)時(shí)太菜了就沒想太多ORZ,還是應(yīng)該學(xué)好一樣來做處理(首推pandas!)
?因?yàn)殚_始的時(shí)候還不太會(huì)用pandas就想用其他的軟件。開始使用SPSS,但是SPSS沒有批量處理多個(gè)文件的能力,且無法提取符號(hào)和數(shù)字混合的變量(例如帶%¥)
于是又用了stata,stata在查看數(shù)據(jù)窗口可以完成字符型變量與數(shù)值變量的轉(zhuǎn)換,最妙的是
即使你不知道對(duì)應(yīng)程序怎么寫,在窗口上點(diǎn)按鈕操作后會(huì)自動(dòng)出現(xiàn)相應(yīng)的代碼,另外stata
支持正則表達(dá)式的提取,詳見
1.數(shù)據(jù)類型的轉(zhuǎn)換
聲明數(shù)值變量的方法:gen variable=.
字符到數(shù)值的轉(zhuǎn)換:
?? gen v5_change=.
?? replace v5_change=0 if v5==“Quiet”
?? replace v5_change=1if v5==“East”
在例如logit回歸(附一個(gè)logistic回歸結(jié)果回歸系數(shù)&OR值解讀and SPSS二項(xiàng)logistic回歸的方法和解釋)中需要將分類變量轉(zhuǎn)化為啞變量,避免將分類元的數(shù)值作為倍數(shù)關(guān)系處理。(例如在分類變量:性別中,將男變?yōu)?,女變?yōu)?)。在python 的pandas庫中有更好的處理方法在后面會(huì)提到。
2.缺失值處理
?關(guān)于缺失值,實(shí)際上SPSS提供了取總體平均值,中位數(shù),以及缺失值前后非缺失值平均數(shù),中位數(shù),線性估計(jì)。但是如果變量是int型,SPSS處理后會(huì)變成float。然后有人告訴我了一個(gè)神奇偏方(PS:此方法僅供娛樂):先按照上述方法補(bǔ)全缺失值再取整,SPSS中取整數(shù)參考(SPSS中:轉(zhuǎn)換->計(jì)算變量->函數(shù)組->字符串->Char.substr())(取整方法:或者調(diào)整SPSS總體數(shù)據(jù)格式)
python pandas包的使用
pandas包除了在數(shù)據(jù)處理上有很多好用的函數(shù)外,值得一提的還有Pandas的數(shù)據(jù)存儲(chǔ)方式 ,相較于使用列表\字典的嵌套更節(jié)省空間。
?一般來說pandas包和numpy包是配合使用的。官方文檔關(guān)于pandas包的學(xué)習(xí)強(qiáng)列推薦:這個(gè)里面有教程和習(xí)題,同樣也可以當(dāng)成工具書使用。
?下面是一些寫程序過程中常用的points,寫在這里方便以后copy:
(1)讀取csv文件加表頭(不要學(xué)我這樣的菜狗路徑帶中文):
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\數(shù)據(jù)競(jìng)賽\數(shù)據(jù)整理\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)取值(數(shù)據(jù)類型不發(fā)生改變):
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)變量變換,以標(biāo)準(zhǔn)化為例(注意其中l(wèi)ambda函數(shù)的使用):
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)改變行/列名:
#用字典的形式,不改變存儲(chǔ) 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)分類函數(shù)groupby
#這個(gè)函數(shù)是真的好用 grid_pre=data.groupby('grid') grid_pre#把data按照相同的grid進(jìn)行劃分 <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里面數(shù)據(jù)的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相互轉(zhuǎn)化:
a=[[[1,5],[2,6]],[[3,7],[4,8]]] a=np.array(a) #np.array(a)不改變a的內(nèi)存 a.shape (2, 2, 2) b=list(a)(4)索引:
a[:,:,0]#抽出的保持原格式 array([[1, 2],[3, 4]]) a[:][1][0][1]=9#冒號(hào)和上面的冒號(hào)意思不同,可以將[:]看作不存在 a[1][0][1] 9 a[:][1][1] array([4, 8])(5)和list對(duì)比
(因?yàn)閮烧咧g有區(qū)別在進(jìn)行數(shù)據(jù)處理的時(shí)候,特別是多維度可能出現(xiàn)list里面套array的時(shí)候需要格外注意,盡量避免這種情況)
(6)reshape&flatten函數(shù)(不改變內(nèi)存)
a.reshape(2,4)#高維到低維是順著排的,各維度之間的轉(zhuǎn)換需要有整除關(guān)系 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)表示一個(gè)置換,即原來的shape:(2,3,4)中0號(hào)位置('2')現(xiàn)在在2號(hào)位置,1號(hào)位置('3')在1號(hào)位置 b.shape (4, 3, 2)csv文件讀寫有關(guān)問題
#寫入list import csv with open(r'路徑','a+',newline='') as f:#a+表示接著在文件后面寫入writer=csv.writer(f)writer.writerows(data)下面是一個(gè)讀取csv存入list的例子,在讀取后成行放入列表。
需要注意的是假如沒有for line in csv_reader:后面的temp=float(x) for x in line,直接存入points時(shí)得到的是包含str的List,且其中的逗號(hào)分隔符(,)也算在str里面(當(dāng)然,也可以使用Dictreader按字典形式讀取)
python 程序編寫中發(fā)現(xiàn)的問題和tricks
(1)關(guān)于利用list&dict寫循環(huán)和函數(shù)(這段代碼沒頭沒尾的僅提供形式)
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里面嵌套一個(gè)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:關(guān)于Python中循環(huán)嵌套的問題:
在多層循環(huán)中建議簡(jiǎn)單的循環(huán)放在里面,復(fù)雜的循環(huán)放在外面。例如:讀取csv文件的循環(huán)放在外面,for i in range(5):這樣的循環(huán)放在里面。
因?yàn)閜ython 的for 循環(huán)的內(nèi)層循環(huán)是不支持循環(huán)讀取文件等較復(fù)雜循環(huán)的。如果
(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不方便用的時(shí)候還可以利用range(len(list_a))和zip構(gòu)成字典進(jìn)行循環(huán)
在組成字典和元組中都很方便更多zip方法:
(5)lambda 用法
y=lambda x:2*x+1 y(2) 5簡(jiǎn)單可視化
import matplotlib.pyplot as plt#借助 matplotlib包(1)畫dataframe里的總圖
data.plot() #一般來說都沒有標(biāo)準(zhǔn)化畫出來的總圖亂糟糟作用不大 plt.show()(2)分開畫
data['infect'].plot()#默認(rèn)x軸是index #加標(biāo)題,圖例,坐標(biāo)軸: 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都呈現(xiàn)在同一張圖里 <matplotlib.axes._subplots.AxesSubplot at 0x18c05fb3908> plt.plot(data['grid'].values,data['infect'].values)#plot(x,y) [<matplotlib.lines.Line2D at 0x2eb218a88c8>](3)散點(diǎn)圖:
data.plot.scatter('density','trans_1') <matplotlib.axes._subplots.AxesSubplot at 0x18c05593f48>(4)箱形圖:
對(duì)箱型圖的理解看這里
數(shù)據(jù)編碼與轉(zhuǎn)換
(1)熱編碼
one-hot熱編碼:將分類變量變成多個(gè)0-1變量
關(guān)于連續(xù)函數(shù)離散化,分類指標(biāo)啞元化詳見
pandas的get_dummies函數(shù)
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)時(shí)間序列處理
pandas里有看這里的后面幾個(gè)cap,在脈沖神經(jīng)網(wǎng)絡(luò)中會(huì)對(duì)時(shí)間有其他的編碼方式。
(3)空間編碼
因?yàn)檫@次數(shù)據(jù)中有很多point to point 的數(shù)據(jù),但是我們?cè)诓僮鞯倪^程中處理的不太好(本來想到過用連接矩陣,但是與其它的數(shù)據(jù)格式不太兼容)。
具體的一些空間編碼的方向可以參考這里
機(jī)器學(xué)習(xí)和神經(jīng)網(wǎng)絡(luò)的初步了解
?開始的時(shí)候用了sklearn做天氣這些外源變量的回歸,還嘗試使用了XGBoost做了感染人數(shù)的回歸,但是總體的回歸效果不太好,就沒搞sklearn了。
?后來用了LSTM長短期記憶做回歸,但是效果也不好,最后用了CNN卷積神經(jīng)網(wǎng)絡(luò)效果才好一點(diǎn)。
sklearn包
?sklearn包可以直接在anaconda prompt里直接下載,里面有線性回歸到隨機(jī)森林的一系列可以直接調(diào)用的相關(guān)函數(shù)。一般單核單線程,關(guān)于這個(gè)包的學(xué)習(xí)首推中文文檔
KNN和SVM
?KNN和SVM原本是兩種分類算法。SVM通過超平面和核做分類劃分,KNN則直接計(jì)算距離,根據(jù)距離遠(yuǎn)近做劃分,具體的內(nèi)容看上面的文檔,網(wǎng)上的大多數(shù)博客也寫的很清楚。
?還可以借助KNN對(duì)分類變量做回歸:
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)?因?yàn)镵NN是根據(jù)距離做的劃分,但是不同維度的距離可能內(nèi)涵不同,或者單位不統(tǒng)一,從而容易導(dǎo)致分類不準(zhǔn)確,可以通過改變各維度的比重進(jìn)行優(yōu)化具體看這里
?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)訓(xùn)練集劃分和參數(shù)訓(xùn)練
主要是下面兩個(gè)函數(shù),具體看上面的sklearn文檔,下面兩個(gè)函數(shù)還可以用在XGBoost上具體的看下面做房?jī)r(jià)預(yù)測(cè)的完整代碼例子
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) #參數(shù)集寫成字典形式 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) #看結(jié)果 print(model.best_params_) print('rmse:', (-grid_model.best_score_) ** 0.5)XGBoost
?XGBoost在一般的分類中超好用,主要原理是多個(gè)決策樹的拼接和權(quán)重分配。具體原理看這里
還有做房?jī)r(jià)預(yù)測(cè)的完整代碼例子
?在回歸中使用XGBoost中的XGBregressor函數(shù)參數(shù)含義看這里:
#這里用的是xgboost做回歸預(yù)測(cè)的函數(shù)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外的調(diào)參策略
LSTM
關(guān)于LSTM和CNN之類原理的強(qiáng)烈建議看這個(gè)建議從頭開始看
LSTM源自RNN,RNN具體看上面,結(jié)構(gòu)上還是seq2seq結(jié)構(gòu)
LSTM和CNN具體網(wǎng)絡(luò)結(jié)構(gòu)看這里
網(wǎng)絡(luò)是用keras搭的,怎么搭看這里強(qiáng)烈推薦keras文檔
keras文檔是真的良心文檔!
神經(jīng)網(wǎng)絡(luò)是怎樣做預(yù)測(cè)的
在上面的介紹中我們看到網(wǎng)絡(luò)有隱藏層(比如CNN的卷積核)里面的參數(shù)通過訓(xùn)練集的輸入與結(jié)果的對(duì)比不斷優(yōu)化隱藏層的參數(shù),從而得到較好的隱藏層,這時(shí)候輸入數(shù)據(jù)通過現(xiàn)有的隱藏層就能得到較好的結(jié)果。
ps.看最下面CNN下面的表最后一列param是每層參數(shù)的個(gè)數(shù),可見網(wǎng)絡(luò)的參數(shù)很多,如果要擬合的很好,需要大量的訓(xùn)練數(shù)據(jù)!
LSTM同樣能做多步多變量預(yù)測(cè)(具體的網(wǎng)上有),上面的就是前80組數(shù)據(jù)預(yù)測(cè)后面一組數(shù)據(jù),要實(shí)現(xiàn)對(duì)后面10組數(shù)據(jù)的預(yù)測(cè)可以通過循環(huán)的方式完成,每次把預(yù)測(cè)到的數(shù)據(jù)加入之前的80個(gè)輸入中,把之前80個(gè)輸入數(shù)據(jù)組的最開始的數(shù)據(jù)刪除。類似于數(shù)據(jù)結(jié)構(gòu)隊(duì)列的亞子。
除此之外如果知道下一組數(shù)據(jù)的8個(gè)特征中的兩個(gè),要預(yù)測(cè)另外6個(gè)特征,則可以把model.add(Dense(8))變?yōu)閙odel.add(Dense(6)),testX不變,testY從8個(gè)數(shù)去掉兩個(gè)已知的變成6個(gè)數(shù)。如果要預(yù)測(cè)后面10組數(shù)據(jù),則在上面的循環(huán)中每次要把預(yù)測(cè)結(jié)果加上兩個(gè)已知數(shù)據(jù),再放入下一次輸入的80組數(shù)據(jù)中。
CNN
(先看這個(gè)!)CNN的具體原理網(wǎng)上有,指路B站3Blue1Brown 的CNN視頻(…B站真的是學(xué)習(xí)站…要不是因?yàn)榭傁矚g打開B站看別的…我是不會(huì)卸載的!)
原理、結(jié)構(gòu)、怎么搭參考上面的LSTM給的網(wǎng)站,里面都有CNN的內(nèi)容。和LSTM有相似之處。但是數(shù)據(jù)維度發(fā)生了改變,下面的網(wǎng)絡(luò)也是用keras搭的,具體的看上面LSTM給的keras中文文檔網(wǎng)址中搜Conv2D等
#先放個(gè)網(wǎng)絡(luò) 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])總結(jié)
以上是生活随笔為你收集整理的数据分析初探——以2020百度西安交大大数据竞赛:传染病感染人数预测为例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何打开华为鸿蒙系统HarmonyOS虚
- 下一篇: 火狐浏览器安装Vue.js devtoo