99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何用Python和循環(huán)神經(jīng)網(wǎng)絡(luò)預(yù)測嚴(yán)重交通擁堵?

電子工程師 ? 來源:lq ? 2018-12-16 10:47 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本文為你介紹,如何從 Waze 交通事件開放數(shù)據(jù)中,利用序列模型找到規(guī)律,進行分類預(yù)測。以便相關(guān)部門可以未雨綢繆,提前有效干預(yù)可能發(fā)生的嚴(yán)重?fù)矶隆?/p>

尋找

之前在《文科生如何理解循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)?》一文中,我為你講解過循環(huán)神經(jīng)網(wǎng)絡(luò)的含義?!度绾斡?Python 和循環(huán)神經(jīng)網(wǎng)絡(luò)做中文文本分類?》一文,我又為你介紹了如何用循環(huán)神經(jīng)網(wǎng)絡(luò)對文本做分類。

我不希望給你一種錯誤的簡單關(guān)聯(lián),即“循環(huán)神經(jīng)網(wǎng)絡(luò)只能用來處理文本數(shù)據(jù)”。

事實上,只要是序列數(shù)據(jù),你都可以考慮一下循環(huán)神經(jīng)網(wǎng)絡(luò)。

我一直打算找個其他序列數(shù)據(jù)的樣例,給你展示循環(huán)神經(jīng)網(wǎng)絡(luò)的更多應(yīng)用場景。

但是這個數(shù)據(jù)不太好選擇。

目前一個熱門的應(yīng)用場景,就是金融產(chǎn)品的價格預(yù)測。

每時每秒,金融產(chǎn)品的價格都在變動。把它匯集起來,是個典型的序列數(shù)據(jù)。

但是我一直不看好這種應(yīng)用。因為金融產(chǎn)品的定價,應(yīng)該是面向未來的。基于歷史價格信息尋找波動規(guī)律,并對未來價格進行預(yù)測,實際上如同看著后視鏡開車一般危險。

但是,還有很多人依然樂此不疲地嘗試。很多時候,他們也能嘗到成功的甜頭。

這是為什么?

原因在于,金融市場的參與者,并非理性的機器,而是由人組成的群體。從行為金融學(xué)的角度來看,進化給人類思考與行為帶來了一些“快捷方式”,你可以利用它們從中漁利。

陸蓉教授的《行為金融學(xué)》欄目,對此有詳細介紹。

例如,人們追漲殺跌,認(rèn)為歷史會重演;

例如,吸引大眾關(guān)注到事件,總會帶來買入;

例如,人們會傾向于投資于自己熟悉的標(biāo)的;

例如,人們會購買下跌的已持倉標(biāo)的,來攤薄成本。

……

如果沒有大風(fēng)浪,這種對市場參與者行為規(guī)律的洞察,確實可以幫你賺錢。你可以從價格的歷史波動中,挖掘出這些規(guī)律的影響。但是這對沒有模型可用的人來說,不公平。教你建模,就如同教你考試作弊。

如果遇到黑天鵝事件,其影響大概率會超過市場參與者行為偏誤帶來的歷史價格波動規(guī)律。那么你,可能會因為應(yīng)用模型,而遭遇虧損。你大約不會認(rèn)為這是自己的錯誤,而直接把我當(dāng)做騙子,朝我扔雞蛋。

理性權(quán)衡后,我決定不用金融產(chǎn)品價格趨勢分析,作為循環(huán)神經(jīng)網(wǎng)絡(luò)的應(yīng)用樣例。

其他開放的序列數(shù)據(jù),當(dāng)然也有很多。例如共享單車租用數(shù)據(jù)、氣溫變化數(shù)據(jù)等。

不過這些應(yīng)用,一來別人都寫過了,不新鮮。二來,氣溫變化,你看天氣預(yù)報就好了。共享單車租用數(shù)量……你真的關(guān)心這里的規(guī)律嗎?

正在我猶豫的時候,一次偶然的機會,我接觸到了一個新的序列數(shù)據(jù)樣例——交通事件數(shù)據(jù)。我覺得,把它作為應(yīng)用案例分享給你,可能更合適一些。

比賽

拿到這個數(shù)據(jù),是因為我參與了一次編程馬拉松(hackathon)比賽。

比賽在 Frisco 的 UNT Inspire Park 舉辦。從早上8點開始,一直到晚上9點多才結(jié)束。中間可以自由吃免費提供的點心和水果,也可以到院子里曬曬太陽放放風(fēng)。大家還可以自由交流和組隊。

主辦方為參賽者提供了若干種開放數(shù)據(jù),也提了一些問題供大家參考解答。當(dāng)然,實際參賽的時候,你也可以自己擬定新的題目。

這其中,就包括了 Waze 數(shù)據(jù)。

我在中國開車,平時用的都是高德導(dǎo)航,對于 Waze 這款 App 不大熟悉。

簡而言之,這個 Waze 應(yīng)用除了提供一般的導(dǎo)航功能之外,還有一個類似于眾包的功能——讓司機們自由提交路況信息。

這樣一來,Waze 就利用群體智慧形成了一個眼觀六路耳聽八方的巨大網(wǎng)絡(luò),隨時依據(jù)用戶提供的情況,匯總成實時交通參考。并且匯報給用戶,以便于大家調(diào)整自己的行車路線。

我覺得最有用的特點是,在堵車的時候,你可以了解到前面究竟發(fā)生了什么。其他導(dǎo)航也有實時交通狀況提示,但是你對前面的情況一無所知。道路半幅施工?交通事故?

信息的對稱,可以在很大程度上,讓司機避免焦慮。

Waze 從幾年前開始,就和政府部門合作,進行數(shù)據(jù)開放共享。這樣一來,政府可以通過 Waze 的數(shù)據(jù)了解交通實時狀況,對于問題進行快速的響應(yīng)處理;與此同時, Waze 用戶也因為可以獲取整合其他相關(guān)類型的政府開放數(shù)據(jù)(例如道路規(guī)劃等),更加有效合理安排出行。

這次比賽,主辦方提供的數(shù)據(jù),是 DFW (達拉斯-沃斯堡都會區(qū))區(qū)域,11月1日到29日的 Waze 交通事件(Incidents)開放數(shù)據(jù),這是政府開放數(shù)據(jù)的一部分。這些數(shù)據(jù)基本都是來自于 Waze 用戶的提交。

原始的數(shù)據(jù),接近 300 MB。每一條事件信息,都包含了提交的經(jīng)緯度,以及時間。因此在探索性數(shù)據(jù)分析階段,我做了幾個可視化圖形。

這是我當(dāng)天跟新認(rèn)識的編程高手 Jesse 學(xué)的 QGIS 分析結(jié)果。

看看圖上的點,每一個都對應(yīng)一次事件匯報。這叫一個密密麻麻啊。

因為 QGIS 初學(xué),用得不熟,我還是用 Python 進行了分類繪圖。

這只是前 3000 條數(shù)據(jù)中部分類型的可視化。其中紅色代表交通擁堵,黃色代表事故發(fā)生,藍色代表有車停在了路肩上。

可以看到,紅色的數(shù)據(jù)量最大。這說明交通擁堵是個大問題。

我把全部的數(shù)據(jù)都拿了出來,提煉出包含的事件類型,包括以下這些類:

我看到,其中單是交通阻塞,也是分為若干級別的。其中最嚴(yán)重的,分別是“大型交通擁堵”(large traffic jam)和“超大型交通擁堵”(huge traffic jam)。

于是,我把所有這兩種嚴(yán)重交通擁堵事件,合并成一個集合;其他剩余事件,作為另一個集合。

對于每一個嚴(yán)重?fù)矶率录?,我追?0分鐘,把之前同一條道路上,發(fā)生的事件,按照順序存成一個列表。這樣的列表,有987個;但是,其中有一些,是驟然發(fā)生的,30分鐘的區(qū)間里面,沒有任何其他事件作為先兆。這樣的空列表,我進行了清除。剩下了861個有效序列。

同樣,從剩余事件集合中,我們隨機找到了861個非空有效序列。這些序列,后續(xù)緊隨事件,都不是嚴(yán)重?fù)矶隆?/p>

我們對嚴(yán)重?fù)矶轮?0分鐘的事件序列,標(biāo)記為1;對于非嚴(yán)重?fù)矶轮?0分鐘的事件序列,標(biāo)記為0。

于是,我們就把問題轉(zhuǎn)換成了,能否利用事件序列,進行分類,預(yù)測后續(xù)是否會發(fā)生嚴(yán)重?fù)矶隆?/p>

靠著這個模型,我們團隊(UNT IIA lab代表隊,其實不過就是我和春迎倆人,團隊昵稱 watch-dumpling )在這次比賽中,獲得第一名。

這是 HackNTX 官網(wǎng)的報道(http://t.cn/EUbS9m5) 。

UNT 網(wǎng)站也正式發(fā)布了這則新聞(http://t.cn/EUbS127),于是我周圍盡人皆知。我才剛拿到手的獎金,立即就因為請客被掃蕩一空了。

奪冠純屬是個意外,幸運占得比重很大。但是我覺得我們做的這個模型,還是有些應(yīng)用價值的。

下面,我就以這組 Waze 交通事件數(shù)據(jù),詳細給你講解一下,如何用 Python, Keras 和循環(huán)神經(jīng)網(wǎng)絡(luò),來實現(xiàn)這個序列數(shù)據(jù)分類模型。

環(huán)境

要運行深度學(xué)習(xí),你需要有 GPU 或者 TPU 的支持,否則會累壞你的筆記本電腦的。Google Colab 是個不錯的實驗平臺,可以讓你免費使用 TPU 來進行深度學(xué)習(xí)訓(xùn)練。你可以閱讀《如何免費云端運行Python深度學(xué)習(xí)框架?》一文,查詢更為詳細的介紹。

這里,請你使用 Chrome 瀏覽器,點擊這個鏈接,安裝一個插件 Colaboratory 。

把它添加到 Google Chrome 之后,你會在瀏覽器的擴展工具欄里面,看見下圖中間的圖標(biāo):

然后,請到本范例的github repo 主頁面。

打開其中的demo.ipynb文件。

點擊 Colaboratory 擴展圖標(biāo)。Google Chrome 會自動幫你開啟 Google Colab,并且裝載這個 ipynb 文件。

點擊上圖中紅色標(biāo)出的“復(fù)制到云端硬盤”按鈕。Google 會為你新建一個屬于你自己的副本。

點擊菜單欄里面的“代碼執(zhí)行程序”,選擇“更改運行時類型”。

在出現(xiàn)的對話框中,確認(rèn)選項如下圖所示。

點擊“保存”即可。

下面,你就可以依次執(zhí)行每一個代碼段落了。

注意第一次執(zhí)行的時候,可能會有警告提示。

出現(xiàn)上面這個警告的時候,點擊“仍然運行”就可以繼續(xù)了。

如果再次出現(xiàn)警告提示,反勾選“在運行前充值所有代碼執(zhí)行程序”選項,再次點擊“仍然運行”即可。

環(huán)境準(zhǔn)備好了,下面我們來一步步運行代碼。

代碼

首先,我們讀入 Pandas 軟件包,以便進行結(jié)構(gòu)化數(shù)據(jù)的處理。

importpandasaspd

這次還要讀入的一個軟件包,是 Python 中間進行數(shù)據(jù)存取的利器,叫做 pickle 。

importpickle

它可以把 Python 數(shù)據(jù),甚至是許多組數(shù)據(jù),一起存儲到指定文件。然后讀出的時候,可以完全恢復(fù)原先數(shù)據(jù)的格式。這一點上,它比用 csv 進行數(shù)據(jù)存儲和交換的效果更好,效率也更高。

下面我們從本文配套的 github 項目中,把數(shù)據(jù)傳遞過來。

!gitclonehttps://github.com/wshuyi/demo_traffic_jam_prediction.git

數(shù)據(jù)的下載,很快就可以完成。

Cloninginto'demo_traffic_jam_prediction'...remote:Enumeratingobjects:6,done.[Kremote:Countingobjects:100%(6/6),done.[Kremote:Compressingobjects:100%(4/4),done.[Kremote:Total6(delta0),reused3(delta0),pack-reused0[KUnpackingobjects:100%(6/6),done.

我們告訴 Jupyter Notebook ,數(shù)據(jù)文件夾的位置。

frompathlibimportPathdata_dir=Path('demo_traffic_jam_prediction')

打開數(shù)據(jù)文件,利用 pickle 把兩組數(shù)據(jù)分別取出。

withopen(data_dir/'data.pickle','rb')asf:[event_dict,df]=pickle.load(f)

先看其中的事件詞典event_dict:

event_dict

以下就是全部的事件類型。

{1:'roadclosedduetoconstruction',2:'trafficjam',3:'stoppedcarontheshoulder',4:'roadclosed',5:'other',6:'objectonroadway',7:'majorevent',8:'pothole',9:'trafficheavierthannormal',10:'roadconstruction',11:'fog',12:'accident',13:'slowdown',14:'stoppedcar',15:'smalltrafficjam',16:'stoppedtraffic',17:'heavytraffic',18:'minoraccident',19:'mediumtrafficjam',20:'malfunctioningtrafficlight',21:'missingsignontheshoulder',22:'animalontheshoulder',23:'animalstruck',24:'largetrafficjam',25:'hazardontheshoulder',26:'hazardonroad',27:'iceonroadway',28:'weatherhazard',29:'flooding',30:'roadclosedduetohazard',31:'hail',32:'hugetrafficjam'}

同樣,我們來看看存儲事件序列的數(shù)據(jù)框。

先看前10個:

df.head(10)

注意,每一行,都包含了標(biāo)記。

再看結(jié)尾部分:

df.tail(10)

讀取無誤。

下面我們來看看,最長的一個序列,編號是多少。

這里,我們利用的是 Pandas 的一個函數(shù),叫做idxmax(),它可以幫助我們,把最大值對應(yīng)的索引編號,傳遞回來。

max_len_event_id=df.events.apply(len).idxmax()max_len_event_id

結(jié)果為:

105

我們來看看,這個編號對應(yīng)的事件序列,是什么樣子的:

max_len_event=df.iloc[max_len_event_id]max_len_event.events

下面是長長的反饋結(jié)果:

['stoppedcarontheshoulder','heavytraffic','heavytraffic','heavytraffic','slowdown','stoppedtraffic','heavytraffic','heavytraffic','heavytraffic','heavytraffic','trafficheavierthannormal','stoppedcarontheshoulder','trafficjam','heavytraffic','stoppedtraffic','stoppedtraffic','stoppedtraffic','heavytraffic','trafficjam','stoppedcarontheshoulder','stoppedtraffic','stoppedtraffic','stoppedtraffic','heavytraffic','trafficheavierthannormal','trafficheavierthannormal','trafficheavierthannormal','trafficheavierthannormal','heavytraffic','stoppedtraffic','trafficheavierthannormal','pothole','stoppedcarontheshoulder','trafficjam','slowdown','stoppedtraffic','heavytraffic','trafficheavierthannormal','trafficjam','trafficjam','stoppedcarontheshoulder','majorevent','trafficjam','trafficjam','stoppedtraffic','heavytraffic','trafficheavierthannormal','stoppedcarontheshoulder','slowdown','heavytraffic','heavytraffic','stoppedcarontheshoulder','trafficjam','slowdown','slowdown','heavytraffic','stoppedcarontheshoulder','heavytraffic','minoraccident','stoppedcarontheshoulder','heavytraffic','stoppedcarontheshoulder','heavytraffic','stoppedtraffic','heavytraffic','trafficheavierthannormal','heavytraffic','stoppedcarontheshoulder','trafficheavierthannormal','stoppedtraffic','heavytraffic','heavytraffic','heavytraffic','stoppedcarontheshoulder','slowdown','stoppedtraffic','heavytraffic','stoppedcarontheshoulder','trafficheavierthannormal','heavytraffic','minoraccident','majorevent','stoppedcarontheshoulder','stoppedcarontheshoulder']

讀一遍,你就會發(fā)現(xiàn),在超級擁堵發(fā)生之前,確實還是有一些先兆的。當(dāng)然,這是由人來閱讀后,獲得的觀感。我們下面需要做的,是讓機器自動把握這些列表的特征,并且做出區(qū)別分類。

我們看看,這個最長列表的長度。

maxlen=len(max_len_event.events)maxlen

結(jié)果為:

84

這里的前導(dǎo)事件,還真是不少啊。

下面我們要做的,是把事件轉(zhuǎn)換成數(shù)字編號,這樣后面更容易處理。

我們使用以下的一個小技巧,把原先的事件詞典倒置,即變“序號:事件名稱”,為“事件名稱:序號”。這樣,以事件名稱查詢起來,效率會高很多。

reversed_dict={}fork,vinevent_dict.items():reversed_dict[v]=k

我們看看倒置的結(jié)果詞典:

reversed_dict

這是反饋結(jié)果:

{'accident':12,'animalontheshoulder':22,'animalstruck':23,'flooding':29,'fog':11,'hail':31,'hazardonroad':26,'hazardontheshoulder':25,'heavytraffic':17,'hugetrafficjam':32,'iceonroadway':27,'largetrafficjam':24,'majorevent':7,'malfunctioningtrafficlight':20,'mediumtrafficjam':19,'minoraccident':18,'missingsignontheshoulder':21,'objectonroadway':6,'other':5,'pothole':8,'roadclosed':4,'roadclosedduetoconstruction':1,'roadclosedduetohazard':30,'roadconstruction':10,'slowdown':13,'smalltrafficjam':15,'stoppedcar':14,'stoppedcarontheshoulder':3,'stoppedtraffic':16,'trafficheavierthannormal':9,'trafficjam':2,'weatherhazard':28}

成功了。

下面我們編寫一個函數(shù),輸入一個事件列表,返回對應(yīng)的事件編號列表。

defmap_event_list_to_idxs(event_list):list_idxs=[]foreventin(event_list):idx=reversed_dict[event]list_idxs.append(idx)returnlist_idxs

然后,我們在剛才是找到的最長列表上,實驗一下:

map_event_list_to_idxs(max_len_event.events)

結(jié)果是這樣的:

[3,17,17,17,13,16,17,17,17,17,9,3,2,17,16,16,16,17,2,3,16,16,16,17,9,9,9,9,17,16,9,8,3,2,13,16,17,9,2,2,3,7,2,2,16,17,9,3,13,17,17,3,2,13,13,17,3,17,18,3,17,3,17,16,17,9,17,3,9,16,17,17,17,3,13,16,17,3,9,17,18,7,3,3]

看來功能實現(xiàn)上,沒問題。

讀入 numpy 和 Keras 的一些工具。

importnumpyasnpfromkeras.utilsimportto_categoricalfromkeras.preprocessing.sequenceimportpad_sequences

系統(tǒng)自動提示我們,Keras 使用了 Tensorflow 作為后端框架。

UsingTensorFlowbackend.

我們需要弄清楚,一共有多少種事件類型。

len(event_dict)

結(jié)果是:

32

因此,我們需要對32種不同的事件類型,進行轉(zhuǎn)換和處理。

我們把整個數(shù)據(jù)集里面的事件類型,都變成事件編號。

df.events.apply(map_event_list_to_idxs)

結(jié)果如下:

0[9,17,18,14,13,17,3,13,16,3,17,17,...1[2,10,3]2[2]3[2]4[2,2,2,2,2,2,2,9]5[3,2,17]6[3,2,17]7[2,15,2,17,2,2,13,17,2]8[17,2,2,16,17,2]9[17,2,2,16,17,2]10[17,16,17,2,17,3,17,17,16,17,16,18,...11[17]12[17]13[24,24]14[24,2,24,24,2]15[24,2,24,24,2]16[2,10,2,2,2,18,16,16,7,2,16,2,2,9...17[2,10,2,2,2,18,16,16,7,2,16,2,2,9...18[24,24,24,16,2,16]19[24,24,24,16,2,16]20[2,2]21[2,16,2]22[2,16,2]23[2,2]24[2,2]25[24,24]26[2,2]27[2,2,2,17]28[2,19,2]29[24]...831[9,9,9,2,9,9,17,2,9,17]832[3,3,3]833[2,9,2,17,17,2]834[3,3,17,3,13,3,3,23,9,3,3,25,3,3]835[3,17,9,14,9,17,14,9,2,9,3,2,2,17]836[2]837[17,2,16,3,9,17,17,17,13,17,9,17]838[13,17,17,3,3,16,17,16,17,16,3,9,1...839[2]840[3]841[2]842[17,17,17,3,17,23,16,17,17,3,2,13,...843[3,3]844[2]845[2,17,2,2,2,2,2,17,2,2]846[7,17,3,18,17]847[3,3,3]848[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,...849[2,2]850[2,2,2,2,2,2,2,2,2,2,2,13,3,2]851[2,2,2]852[16,2,16]853[3,16,5,3,17,3,16,9,3,2,17]854[16]855[3,3,3,3,3,3,3,3,2,13,3,6,3,6,3,...856[17,17,17,2,3,2,2,2,2,2]857[2,2]858[2,2,9,17,2,2]859[17,3,2,2,2,2,2,2]860[17,3,3,17,3,17,2,3,18,14,3,3,16,...Name:events,Length:1722,dtype:object

現(xiàn)在,作為人類,我們確實是看不清楚,列表里面的事件都是什么了。好在計算機對于數(shù)字,更加喜聞樂見。

我們把該列表,起名為 sequences ,并且顯示前5項內(nèi)容。

sequences=df.events.apply(map_event_list_to_idxs).tolist()sequences[:5]

下面是結(jié)果:

[[9,17,18,14,13,17,3,13,16,3,17,17,16,3,16,17,9,17,2,17,2,7,16,17,17,17,17,13,5,17,9,9,16,16,3],[2,10,3],[2],[2],[2,2,2,2,2,2,2,9]]

注意,第一行,明顯比后幾行都要長。

對于輸入序列,我們希望它的長度都是一樣的。因此,下面我們就用最長的序列長度作為標(biāo)準(zhǔn),用 0 來填充其他短序列。

data=pad_sequences(sequences,maxlen=maxlen)data

這是結(jié)果:

array([[0,0,0,...,16,16,3],[0,0,0,...,2,10,3],[0,0,0,...,0,0,2],...,[0,0,0,...,17,2,2],[0,0,0,...,2,2,2],[0,0,0,...,3,3,2]],dtype=int32)

注意,所有的0,都補充到了序列的最前端。序列都一樣長了。

下面,我們把全部的分類標(biāo)記,存儲到 labels 變量里面。

labels=np.array(df.label)

后面,我們有好幾個函數(shù),需要用到隨機變量。

為了咱們運行結(jié)果的一致性。我這里指定隨機種子數(shù)值。你第一次嘗試運行的時候,不要動它。但是后面自己動手操作的時候,可以任意修改它。

np.random.seed(12)

好了,下面我們“洗牌”。打亂數(shù)據(jù)的順序,但是注意序列和對應(yīng)標(biāo)記之間,要保持一致性。

indices=np.arange(data.shape[0])np.random.shuffle(indices)data=data[indices]labels=labels[indices]

然后,我們?nèi)?80% 的數(shù)據(jù),作為訓(xùn)練;另外 20% 的數(shù)據(jù),作為驗證。

training_samples=int(len(indices)*.8)validation_samples=len(indices)-training_samples

我們正式劃分訓(xùn)練集和驗證集。

X_train=data[:training_samples]y_train=labels[:training_samples]X_valid=data[training_samples:training_samples+validation_samples]y_valid=labels[training_samples:training_samples+validation_samples]

看看訓(xùn)練集的內(nèi)容。

X_train

結(jié)果為:

array([[0,0,0,...,15,15,3],[0,0,0,...,0,2,2],[0,0,0,...,0,0,16],...,[0,0,0,...,2,15,16],[0,0,0,...,2,2,2],[0,0,0,...,0,0,2]],dtype=int32)

注意由于我們補充了“0”,作為填充,因此原先的32種事件類型的基礎(chǔ)上,又加了一種。

這就是我們新的事件類型數(shù)量:

num_events=len(event_dict)+1

我們使用嵌入層,把事件標(biāo)號,轉(zhuǎn)換成一系列數(shù)字組成的向量。這樣,可以避免模型把事件序號,當(dāng)成數(shù)值型數(shù)據(jù)來處理。

這里,我們指定每一個標(biāo)號,轉(zhuǎn)換成 20 個數(shù)字組成的向量。

embedding_dim=20

利用事件類型數(shù)量,和事件向量長度,我們隨機構(gòu)造初始的嵌入矩陣。

embedding_matrix=np.random.rand(num_events,embedding_dim)

下面我們搭建一個循環(huán)神經(jīng)網(wǎng)絡(luò)模型。其中的 LSTM 層,包含了32位輸出數(shù)字。

fromkeras.modelsimportSequentialfromkeras.layersimportEmbedding,Flatten,Dense,LSTMunits=32model=Sequential()model.add(Embedding(num_events,embedding_dim))model.add(LSTM(units))model.add(Dense(1,activation='sigmoid'))

這里,我假設(shè)你已經(jīng)看過了《如何用 Python 和循環(huán)神經(jīng)網(wǎng)絡(luò)做中文文本分類?》一文,所以就不對細節(jié)進行講述了。如果你沒有看過,或者已經(jīng)遺忘,可以點擊這個鏈接復(fù)習(xí)一下。

如果你對 Keras 的使用方法還不熟悉,我再次向你推薦 Fran?ois Chollet 的《Deep Learning with Python》。

下面,是處理其中的嵌入層參數(shù)。我們直接把剛才隨機生成的嵌入矩陣挪進來。而且,不讓模型在訓(xùn)練中對嵌入層參數(shù)進行修改。

model.layers[0].set_weights([embedding_matrix])model.layers[0].trainable=False

下面,我們開始訓(xùn)練。并且把模型運行結(jié)果保存起來。

model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['acc'])history=model.fit(X_train,y_train,epochs=50,batch_size=32,validation_data=(X_valid,y_valid))model.save("mymodel_embedding_untrainable.h5")

可以看到,因為有 TPU 的強力支持,程序在歡快地運行中。

訓(xùn)練過程結(jié)束之后,我們利用 matplotlib 繪圖功能,看一下訓(xùn)練中,準(zhǔn)確率和損失值的變化。

importmatplotlib.pyplotaspltacc=history.history['acc']val_acc=history.history['val_acc']loss=history.history['loss']val_loss=history.history['val_loss']epochs=range(1,len(acc)+1)plt.plot(epochs,acc,'bo',label='Trainingacc')plt.plot(epochs,val_acc,'b',label='Validationacc')plt.title('Trainingandvalidationaccuracy')plt.legend()plt.figure()plt.plot(epochs,loss,'bo',label='Trainingloss')plt.plot(epochs,val_loss,'b',label='Validationloss')plt.title('Trainingandvalidationloss')plt.legend()plt.show()

這是準(zhǔn)確率變化曲線。

可以看到,效果還是不錯的。因為我們數(shù)據(jù)中,不同標(biāo)記各占一半。因此如果構(gòu)建一個 dummy model 作為標(biāo)準(zhǔn)線的話,對所有的輸入都猜測0或者1,準(zhǔn)確率應(yīng)該只有50%。

這里的準(zhǔn)確率,已經(jīng)達到了65%-75%之間,證明我們的模型是有意義的。只不過,抖動比較厲害,穩(wěn)定性差。

這是損失值變化曲線。

這個圖看起來,就不是很美妙了。因為雖然訓(xùn)練集上面的損失值一路下降,但是驗證集上,這個效果并不是很明顯,一直劇烈波動。

看到結(jié)果,不是最重要的。關(guān)鍵是我們得分析出目前遇到問題,原因是什么。

注意我們前面使用了嵌入矩陣。它隨機生成,卻又沒有真正進行訓(xùn)練調(diào)整,這可能是個問題。

因此,我們這里再次構(gòu)建和跑一下模型。唯一改動的地方,在于讓嵌入矩陣的參數(shù)也可以隨著訓(xùn)練進行自動調(diào)整。

fromkeras.modelsimportSequentialfromkeras.layersimportEmbedding,Flatten,Dense,LSTMunits=32model=Sequential()model.add(Embedding(num_events,embedding_dim))model.add(LSTM(units))model.add(Dense(1,activation='sigmoid'))

注意這里的差別,就是trainable設(shè)置為真值。

model.layers[0].set_weights([embedding_matrix])model.layers[0].trainable=True

構(gòu)建模型,再次運行。

model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['acc'])history=model.fit(X_train,y_train,epochs=50,batch_size=32,validation_data=(X_valid,y_valid))model.save("mymodel_embedding_trainable.h5")

繪圖看看。

importmatplotlib.pyplotaspltacc=history.history['acc']val_acc=history.history['val_acc']loss=history.history['loss']val_loss=history.history['val_loss']epochs=range(1,len(acc)+1)plt.plot(epochs,acc,'bo',label='Trainingacc')plt.plot(epochs,val_acc,'b',label='Validationacc')plt.title('Trainingandvalidationaccuracy')plt.legend()plt.figure()plt.plot(epochs,loss,'bo',label='Trainingloss')plt.plot(epochs,val_loss,'b',label='Validationloss')plt.title('Trainingandvalidationloss')plt.legend()plt.show()

這次的準(zhǔn)確率曲線,看起來好多了。驗證集波動沒有這么劇烈,模型穩(wěn)定性好了許多。而且,準(zhǔn)確率的取值,也獲得了提升。后半程穩(wěn)定在了75%以上。這樣的模型,就有應(yīng)用價值了。

但是我們看看損失值曲線,可能就不這么樂觀了。

注意從半程之后,訓(xùn)練集和驗證集的損失值變化,就發(fā)生了分叉。

這是典型的過擬合(over-fitting)。

發(fā)生過擬合,主要原因就是相對于復(fù)雜的模型,訓(xùn)練數(shù)據(jù)不夠用。

這時候,要么增加訓(xùn)練數(shù)據(jù),要么降低模型復(fù)雜度。

立即增加數(shù)據(jù),不太現(xiàn)實。因為我們手中,目前只有那29天里積攢的數(shù)據(jù)。但是降低模型復(fù)雜度,是可以利用 Dropout 來嘗試完成的。

Dropout 的實現(xiàn)機理,是在訓(xùn)練的時候,每次隨機把一定比例的模型中神經(jīng)元對應(yīng)權(quán)重參數(shù),設(shè)置為0,讓它不起作用。這樣,模型的復(fù)雜度,就會降低。

下面,我們輕微修改一下,在 LSTM 層上,加入dropout=0.2, recurrent_dropout=0.2這兩個參數(shù)。

fromkeras.modelsimportSequentialfromkeras.layersimportEmbedding,Flatten,Dense,LSTMunits=32model=Sequential()model.add(Embedding(num_events,embedding_dim))model.add(LSTM(units,dropout=0.2,recurrent_dropout=0.2))model.add(Dense(1,activation='sigmoid'))

依然保持嵌入層可以被訓(xùn)練。

model.layers[0].set_weights([embedding_matrix])model.layers[0].trainable=True

再次運行。

model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['acc'])history=model.fit(X_train,y_train,epochs=50,batch_size=32,validation_data=(X_valid,y_valid))model.save("mymodel_embedding_trainable_with_dropout.h5")

繪制圖形的函數(shù)跟之前兩次完全一致。

importmatplotlib.pyplotaspltacc=history.history['acc']val_acc=history.history['val_acc']loss=history.history['loss']val_loss=history.history['val_loss']epochs=range(1,len(acc)+1)plt.plot(epochs,acc,'bo',label='Trainingacc')plt.plot(epochs,val_acc,'b',label='Validationacc')plt.title('Trainingandvalidationaccuracy')plt.legend()plt.figure()plt.plot(epochs,loss,'bo',label='Trainingloss')plt.plot(epochs,val_loss,'b',label='Validationloss')plt.title('Trainingandvalidationloss')plt.legend()plt.show()

這次的準(zhǔn)確率曲線,看起來達到的數(shù)值,跟沒有加入 Dropout 的差不多。

然而,我們可以感受到訓(xùn)練集和驗證集達到的準(zhǔn)確率更加貼近。曲線更加平滑。

下面我們看看損失值曲線的變化。

這個曲線上,過擬合的去除效果就更為明顯了??梢钥吹接?xùn)練集和驗證集兩條曲線的波動基本保持了一致。這樣我們更可以確信,模型預(yù)測能力是穩(wěn)定的,對外界新的輸入信息,適應(yīng)性更好。

如果把咱們的模型放在交通管理部門那里,可以期望它根據(jù) Waze 獲得的新序列數(shù)據(jù),能以大約 75% 的準(zhǔn)確率,預(yù)測嚴(yán)重交通擁堵的發(fā)生。這樣,交管部門就可以未雨綢繆,提前做出干預(yù)了。

用序列模型,欺負(fù)金融市場的散戶,屬于零和博弈。然而這種在交通管理上的應(yīng)用,大概更能造福社會,體現(xiàn)科技的價值吧。

小結(jié)

通過本文的學(xué)習(xí)和實際上手操作,希望你已了解了以下知識點:

不只是文本,其他序列數(shù)據(jù),也可以利用循環(huán)神經(jīng)網(wǎng)絡(luò)來進行分類預(yù)測。

對定類數(shù)據(jù)(categorical data)進行嵌入表示,如果用隨機數(shù)初始,那么在建模過程中把嵌入層一起訓(xùn)練,效果會更好。

數(shù)據(jù)量不夠的情況下,深度學(xué)習(xí)很可能會發(fā)生過擬合。使用 Dropout ,可以降低過擬合的影響,讓模型具有更好的穩(wěn)定性和可擴展性。

希望這篇文章,可以幫助你了解循環(huán)神經(jīng)網(wǎng)絡(luò)的更多應(yīng)用場景。在實際的工作和學(xué)習(xí)中,靈活運用它來處理序列數(shù)據(jù)的分類等任務(wù)。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 神經(jīng)網(wǎng)絡(luò)

    關(guān)注

    42

    文章

    4814

    瀏覽量

    103648
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7256

    瀏覽量

    91892
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4827

    瀏覽量

    86766

原文標(biāo)題:如何用Python和循環(huán)神經(jīng)網(wǎng)絡(luò)預(yù)測嚴(yán)重交通擁堵?

文章出處:【微信號:rgznai100,微信公眾號:rgznai100】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    有提供編寫神經(jīng)網(wǎng)絡(luò)預(yù)測程序服務(wù)的嗎?

    有提供編寫神經(jīng)網(wǎng)絡(luò)預(yù)測程序服務(wù)的嗎?
    發(fā)表于 12-10 13:50

    用matlab編程進行BP神經(jīng)網(wǎng)絡(luò)預(yù)測時如何確定最合適的,BP模型

    請問用matlab編程進行BP神經(jīng)網(wǎng)絡(luò)預(yù)測時,訓(xùn)練結(jié)果很多都是合適的,但如何確定最合適的?且如何用最合適的BP模型進行外推預(yù)測
    發(fā)表于 02-08 14:19

    關(guān)于BP神經(jīng)網(wǎng)絡(luò)預(yù)測模型的確定??!

    請問用matlab編程進行BP神經(jīng)網(wǎng)絡(luò)預(yù)測時,訓(xùn)練結(jié)果很多都是合適的,但如何確定最合適的?且如何用最合適的BP模型進行外推預(yù)測?
    發(fā)表于 02-08 14:23

    如何構(gòu)建神經(jīng)網(wǎng)絡(luò)?

    原文鏈接:http://tecdat.cn/?p=5725 神經(jīng)網(wǎng)絡(luò)是一種基于現(xiàn)有數(shù)據(jù)創(chuàng)建預(yù)測的計算系統(tǒng)。如何構(gòu)建神經(jīng)網(wǎng)絡(luò)?神經(jīng)網(wǎng)絡(luò)包括:輸入層:根據(jù)現(xiàn)有數(shù)據(jù)獲取輸入的層隱藏層:使用反
    發(fā)表于 07-12 08:02

    GABP神經(jīng)網(wǎng)絡(luò)交通預(yù)測中的應(yīng)用研究

    交通流的預(yù)測是智能交通系統(tǒng)的重要技術(shù)之一,傳統(tǒng)的神經(jīng)網(wǎng)絡(luò)預(yù)測方法存在對初始網(wǎng)絡(luò)權(quán)值設(shè)置敏感、易陷
    發(fā)表于 02-23 14:20 ?22次下載

    改進人工蜂群算法優(yōu)化RBF神經(jīng)網(wǎng)絡(luò)的短時交通預(yù)測模型

    為了提高徑向基函數(shù)RBF神經(jīng)網(wǎng)絡(luò)預(yù)測模型對短時交通流的預(yù)測準(zhǔn)確性,提出了一種基于改進人工蜂群算法優(yōu)化RBF神經(jīng)網(wǎng)絡(luò)的短時
    發(fā)表于 12-01 16:31 ?2次下載
    改進人工蜂群算法優(yōu)化RBF<b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>的短時<b class='flag-5'>交通</b>流<b class='flag-5'>預(yù)測</b>模型

    結(jié)合小波變換的LSTM循環(huán)神經(jīng)網(wǎng)絡(luò)的稅收預(yù)測

    分析歷史稅收數(shù)據(jù)之間的隱藏關(guān)系,利用數(shù)學(xué)模型來預(yù)測未來的稅收收入是稅收預(yù)測的研究重點。在此,提出了一種結(jié)合小波變換的長短期記憶(LSTM循環(huán)神經(jīng)網(wǎng)絡(luò)的稅收
    發(fā)表于 04-28 11:26 ?10次下載
    結(jié)合小波變換的LSTM<b class='flag-5'>循環(huán)</b><b class='flag-5'>神經(jīng)網(wǎng)絡(luò)</b>的稅收<b class='flag-5'>預(yù)測</b>

    卷積神經(jīng)網(wǎng)絡(luò)python代碼

    的卷積操作,將不同層次的特征進行提取,從而通過反向傳播算法不斷優(yōu)化網(wǎng)絡(luò)權(quán)重,最終實現(xiàn)分類和預(yù)測等任務(wù)。 在本文中,我們將介紹如何使用Python實現(xiàn)卷積神經(jīng)網(wǎng)絡(luò),并詳細說明每一個步驟及
    的頭像 發(fā)表于 08-21 16:41 ?1317次閱讀

    如何使用神經(jīng)網(wǎng)絡(luò)進行建模和預(yù)測

    神經(jīng)網(wǎng)絡(luò)是一種強大的機器學(xué)習(xí)技術(shù),可以用于建模和預(yù)測變量之間的關(guān)系。 神經(jīng)網(wǎng)絡(luò)的基本概念 神經(jīng)網(wǎng)絡(luò)是一種受人腦啟發(fā)的計算模型,由大量的節(jié)點(神經(jīng)
    的頭像 發(fā)表于 07-03 10:23 ?1374次閱讀

    循環(huán)神經(jīng)網(wǎng)絡(luò)和卷積神經(jīng)網(wǎng)絡(luò)的區(qū)別

    循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,RNN)和卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network,CNN)是深度學(xué)習(xí)領(lǐng)域中兩種非常重要的神經(jīng)網(wǎng)絡(luò)
    的頭像 發(fā)表于 07-04 14:24 ?2119次閱讀

    循環(huán)神經(jīng)網(wǎng)絡(luò)的基本概念

    循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,簡稱RNN)是一種具有循環(huán)結(jié)構(gòu)的神經(jīng)網(wǎng)絡(luò),其核心思想是將前一個時間步的輸出作為下一個時間步的輸入,從而實現(xiàn)對序列數(shù)據(jù)的建
    的頭像 發(fā)表于 07-04 14:31 ?1319次閱讀

    循環(huán)神經(jīng)網(wǎng)絡(luò)算法原理及特點

    循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,簡稱RNN)是一種具有記憶功能的神經(jīng)網(wǎng)絡(luò),能夠處理序列數(shù)據(jù)。與傳統(tǒng)的前饋神經(jīng)網(wǎng)絡(luò)(Feedforward Neural
    的頭像 發(fā)表于 07-04 14:49 ?1374次閱讀

    遞歸神經(jīng)網(wǎng)絡(luò)循環(huán)神經(jīng)網(wǎng)絡(luò)

    遞歸神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,簡稱RNN)和循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,簡稱RNN)實際上是同一個概念,只是不同的翻譯方式
    的頭像 發(fā)表于 07-04 14:54 ?1547次閱讀

    rnn是遞歸神經(jīng)網(wǎng)絡(luò)還是循環(huán)神經(jīng)網(wǎng)絡(luò)

    RNN(Recurrent Neural Network)是循環(huán)神經(jīng)網(wǎng)絡(luò),而非遞歸神經(jīng)網(wǎng)絡(luò)。循環(huán)神經(jīng)網(wǎng)絡(luò)是一種具有時間序列特性的
    的頭像 發(fā)表于 07-05 09:52 ?1043次閱讀

    python做bp神經(jīng)網(wǎng)絡(luò)預(yù)測數(shù)據(jù)

    介紹如何使用Python實現(xiàn)BP神經(jīng)網(wǎng)絡(luò)進行數(shù)據(jù)預(yù)測。 1. 神經(jīng)網(wǎng)絡(luò)基礎(chǔ) 1.1 神經(jīng)元模型 神經(jīng)
    的頭像 發(fā)表于 07-11 10:54 ?1878次閱讀