龔大豐,田啟明
(溫州職業(yè)技術(shù)學(xué)院 信息技術(shù)系,浙江 溫州 325035)
據(jù)國家發(fā)改委、中國物流與采購聯(lián)合會的通報顯示,2017年全國社會物流總額252.8萬億元,按可比價格計算,同比增長6.7%,增速比上年同期提高0.6個百分點。從分季度看,2017年一季度56.7萬億元,增長7.1%,提高1.1個百分點;上半年118.9萬億元,增長7.1%,提高0.9個百分點,全年社會物流總需求呈現(xiàn)穩(wěn)中有升的發(fā)展態(tài)勢。[1]隨著國家對長三角區(qū)域經(jīng)濟(jì)發(fā)展的重視,浙江省貨運(yùn)規(guī)模不斷擴(kuò)大,經(jīng)濟(jì)結(jié)構(gòu)、服務(wù)模式逐步優(yōu)化。據(jù)浙江省統(tǒng)計局公開發(fā)布的數(shù)據(jù)顯示,2007年1月—2018年3月,浙江省鐵路貨運(yùn)總量超過37 730萬t,公路貨運(yùn)總量超過1 222 347萬t,水路貨運(yùn)總量超過723 398萬t,同比和環(huán)比都有明顯增長[2]。這對浙江省交通規(guī)劃和運(yùn)輸能力等提出了嚴(yán)峻考驗。
經(jīng)濟(jì)和科技的高速發(fā)展,促進(jìn)了浙江省貨運(yùn)的現(xiàn)代化轉(zhuǎn)型,貨運(yùn)在當(dāng)今的經(jīng)濟(jì)發(fā)展中有著重要地位,而貨運(yùn)量的變化,直接反應(yīng)一個地區(qū)的經(jīng)濟(jì)狀況。運(yùn)用大數(shù)據(jù)技術(shù)進(jìn)行管理,做好公路貨運(yùn)量的科學(xué)預(yù)測,能幫助各地區(qū)進(jìn)行智慧交通管理[3],也可提高公路貨運(yùn)企業(yè)的效益,促進(jìn)公路貨運(yùn)行業(yè)持續(xù)、健康和穩(wěn)定發(fā)展[4],為政府開展更合理的路政管理和服務(wù)工作及對當(dāng)?shù)毓芬?guī)劃和建設(shè)具有較強(qiáng)的指導(dǎo)意義。本文運(yùn)用機(jī)器學(xué)習(xí)算法分析浙江省公路貨運(yùn)量的變化情況,嘗試發(fā)現(xiàn)其變化規(guī)律并做出預(yù)測,為相關(guān)部門提供參考依據(jù)。
由于浙江省公路貨運(yùn)量數(shù)據(jù)源本身帶有所需屬性和結(jié)果標(biāo)簽值,因而選擇監(jiān)督機(jī)器學(xué)習(xí)算法,結(jié)合當(dāng)前開源且主流的python編程語言和scrapy數(shù)據(jù)采集框架,實現(xiàn)訓(xùn)練模型的預(yù)測功能。目前,國內(nèi)外貨運(yùn)量預(yù)測中通常采用組合模型、無偏灰色預(yù)測模型、神經(jīng)網(wǎng)絡(luò)、回歸曲線模型等多種形式,其中回歸模型是一種具體的、行之有效的、實用價值很高的預(yù)測途徑,因而在貨運(yùn)量預(yù)測中常常選用回歸模型。通過分析浙江省歷年公路貨運(yùn)量數(shù)據(jù),可得出它們具有較強(qiáng)的相關(guān)性,基本符合回歸預(yù)測的條件。由于回歸預(yù)測模型類型較多,致使預(yù)測方法不易選擇,不同的模型預(yù)測結(jié)果與實際的差距在精度和可靠性方面都不盡相同。本文對監(jiān)督機(jī)器學(xué)習(xí)算法中的嶺回歸算法、樸素貝葉斯算法和KNN算法進(jìn)行預(yù)測分析,對比結(jié)果優(yōu)劣,同時也為分析其他數(shù)據(jù)提供參考。
嶺回歸,又稱脊回歸或吉洪諾夫正則化,是對不適定問題進(jìn)行回歸分析時最經(jīng)常使用的一種正則化方法[5]。嶺回歸通過對矩陣X'X的對角線上增加一組正常數(shù)(即嶺參數(shù)),降低其病態(tài)程度,使得求逆運(yùn)算相對穩(wěn)定。如果嶺參數(shù)的選擇合理,嶺回歸估計的結(jié)果會在僅犧牲較小的無偏性下極大地降低參數(shù)估計量的方差。因此,從MSE的標(biāo)準(zhǔn)看,嶺回歸可能優(yōu)于普通最小二乘估計,即β=(X'X)-1X'Y。在X'X主對角線上增加一個常數(shù)后,得到嶺回歸估計的一般形式為:
其中,k為嶺參數(shù),通常k≥0,當(dāng)k=0時,嶺估計即為最小二乘估計,Ip+1為單位矩陣[6]。嶺回歸是對最小二乘回歸的一種補(bǔ)充,它損失了無偏性來換取高的數(shù)值穩(wěn)定性,從而得到較高的計算精度。
樸素貝葉斯算法是基于貝葉斯定理與特征條件獨立假設(shè)的分類方法,二者是樸素貝葉斯的兩個重要的理論基礎(chǔ)。
先驗證多項式分布的樸素貝葉斯假設(shè)特征的先驗概率為多項式分布,多項式樸素貝葉斯是一種生成式模型,可通過(2)式獲得,即:
對于樸素貝葉斯算法而言,也就是具有最大后驗概率(max-imum a posteriori)估計值的類別,即:
(3)式計算條件概率的乘積,可能會導(dǎo)致浮點數(shù)下界溢出,所以引入對數(shù)得[7]:
KNN算法,又稱k個近鄰分類(k-nearest neighbor classification)算法。它是根據(jù)不同特征值之間的距離進(jìn)行分類的一種簡單的機(jī)器學(xué)習(xí)方法,其訓(xùn)練數(shù)據(jù)都是有標(biāo)簽的數(shù)據(jù)。KNN算法可用于回歸,通過找出一個樣本的k個最近鄰居,將這些鄰居的屬性的平均值賦給該樣本,就可得到該樣本的屬性。
KNN算法用于分類的核心思想是:存在一個樣本數(shù)據(jù)集合,又稱訓(xùn)練樣本集,并且樣本集中每個數(shù)據(jù)都存在標(biāo)簽。輸入沒有標(biāo)簽的新數(shù)據(jù)后,將新數(shù)據(jù)的每個特征與樣本集中數(shù)據(jù)對應(yīng)的特征進(jìn)行比較,然后算法提取樣本集中特征最相似數(shù)據(jù)(最近鄰)的結(jié)果。一般而言,只選擇樣本數(shù)據(jù)集中前k個最相似的數(shù)據(jù),這就是k近鄰算法中k的出處(通常k<20)[8]。
為了對浙江省公路貨運(yùn)量進(jìn)行合理預(yù)測,獲得一個比較滿意的模型供今后參考使用,為數(shù)據(jù)采集到結(jié)果分析的整個實現(xiàn)過程設(shè)計如下流程:
(1)通過目前常用的爬蟲技術(shù),從浙江省統(tǒng)計局官方網(wǎng)站采集2007年1月—2018年3月所有關(guān)于公路的貨運(yùn)數(shù)據(jù),部分月份數(shù)據(jù)不全者進(jìn)行簡單的預(yù)處理,保存到本地存儲。
(2)以公路貨運(yùn)數(shù)據(jù)為研究對象,由于所采集數(shù)據(jù)是當(dāng)年當(dāng)月累加值,如3月公布的數(shù)據(jù)是1月至3月的三個月總量,還需要進(jìn)一步處理數(shù)據(jù),轉(zhuǎn)化為當(dāng)月貨運(yùn)量。
(3)對預(yù)處理后的公路貨運(yùn)數(shù)據(jù),按照嶺回歸算法、樸素貝葉斯算法和KNN算法要求,設(shè)計出模型所需的訓(xùn)練集和測試集數(shù)據(jù),訓(xùn)練出各模型對應(yīng)參數(shù),然后用測試集數(shù)據(jù)進(jìn)行測試,得出各種算法的準(zhǔn)確度。
(4)分析各模型的準(zhǔn)確度,選擇一種較好的算法作為預(yù)測模型。
(5)根據(jù)上一步驟的結(jié)果,確定公路貨運(yùn)預(yù)測算法。
浙江省公路貨運(yùn)量數(shù)據(jù)采集分析流程如圖1所示。
圖1 浙江省公路貨運(yùn)量數(shù)據(jù)采集分析流程
數(shù)據(jù)采集環(huán)節(jié)采用當(dāng)前流行的python環(huán)境下的scrapy爬蟲框架。scrapy是python開發(fā)的一個快速、高層次的屏幕抓取和web抓取框架,用于抓取web站點,并從頁面中提取結(jié)構(gòu)化的數(shù)據(jù)。其步驟如下:
(1)安裝scrapy框架,在命令行下,運(yùn)行pip install scrapy命令即可實現(xiàn)。
(2)創(chuàng)建爬蟲項目,在命令行下,執(zhí)行scrapy startproject zjstatistics,就會在目標(biāo)目錄下創(chuàng)建框架文件,如圖2所示。
圖2 scrapy項目框架結(jié)構(gòu)
(3)創(chuàng)建爬蟲文件spider.py,主要實現(xiàn)對網(wǎng)絡(luò)請求返回的數(shù)據(jù)解析,爬取url深度為2,即目錄頁和貨運(yùn)量數(shù)據(jù)具體內(nèi)容頁,參考代碼如下:
#解析內(nèi)容函數(shù)
def parse(self, response):
item = ZjstatisticsItem( )
#獲得當(dāng)前Web請求結(jié)果,并正則匹配子頁鏈接URL
res = response.selector.xpath('//tr/td//@href')
#遍歷所有結(jié)果
for re in res:
#字符按utf-8解碼
suburl = re.extract( ).decode('utf-8')
#拼湊成完整的url
item['url'] = suburl[1:]
......
#返回解析結(jié)果
yield item
(4)代碼調(diào)試無誤后,運(yùn)行scrapy crawl zjstatistics命令即可實現(xiàn)數(shù)據(jù)采集,保存到當(dāng)前data.csv文件,所采集結(jié)果見表1。根據(jù)公路貨運(yùn)量數(shù)據(jù),將其中的90%數(shù)據(jù)作為各模型的訓(xùn)練集使用,10%數(shù)據(jù)作為驗證對應(yīng)模型的準(zhǔn)確度進(jìn)行分析對比。
表1 浙江省公路貨運(yùn)量數(shù)據(jù)采集結(jié)果
數(shù)據(jù)預(yù)處理的目的是清洗無效數(shù)據(jù),將所需數(shù)據(jù)轉(zhuǎn)化為目標(biāo)要求格式,為下一步調(diào)用算法需要傳遞的數(shù)據(jù)集參數(shù)做準(zhǔn)備。其預(yù)處理的主要代碼如下:
#讀取文件內(nèi)容
data_str = open('data.json', encoding='utf-8').read( )
data_list = json.loads(data_str)
data = [[d[' year '], d[' month '],d[' highway ']] for d in data_list]
#獲得三列數(shù)據(jù)
src = pd.DataFrame(data, columns=['year','month',’highway’])
#讀取第1、2列為變量集,第3列為結(jié)果集
X = src.iloc[:,0:2]
Y = src.iloc[:,2:3]
#隨機(jī)分配訓(xùn)練集和測試集,由于數(shù)據(jù)量不夠大,按9:1分配
trainx,testx,trainy,testy=train_test_split(X,Y,test_size=0.1,random_state=0)
分別采用嶺回歸算法、樸素貝葉斯算法和KNN算法,實現(xiàn)對公路貨運(yùn)量數(shù)據(jù)模型的訓(xùn)練。
(1)基于嶺回歸算法的實現(xiàn)。
#這里指定使用嶺回歸作為基函數(shù)
#定義模型
pp = make_pipeline(PolynomialFeatures((3)),Ridge( ))
#訓(xùn)練模型
pp.fit(trainx, trainy)
#預(yù)測測試集
pp_pred = pp.predict(testx)
#計算符合誤差范圍的個數(shù),符合一個標(biāo)準(zhǔn)差的值+1
right_num = 0
right_num =( abs(trainy - pp_pred)<=err_railway).sum( )
#計算在誤差范圍內(nèi)的準(zhǔn)確度
err2=float(right_num) / len(testx)
#打印顯示結(jié)果
print "PolynomialFeatures accuracy :%f" %( err2)
(2)基于樸素貝葉斯算法的實現(xiàn)。
#定義貝葉斯模型
clf=MultinomialNB( )
#訓(xùn)練模型并預(yù)測測試集
clf_pred = clf.fit(trainx, trainy).predict(testx)
right_num =( )
#計算符合誤差范圍的個數(shù),符合一個標(biāo)準(zhǔn)方差的值+1
for i in range(len(clf_pred)):
if abs(trainy.iat[i, 0] - clf_pred[i]) < err_railway:
right_num += 1
#計算在誤差范圍內(nèi)的準(zhǔn)確度
err3=float(right_num) / len(testx)
print "MultinomialNB accuracy :%f" %( err3)
(3)基于KNN算法的實現(xiàn)。
#定義Knn模型
knn = neighbors.KNeighborsClassifier( )
#訓(xùn)練模型
knn.fit(trainx, trainy)
#預(yù)測測試集
knn_pred = knn.predict(testx)
right_num = 0
#計算符合誤差范圍的個數(shù),符合一個標(biāo)準(zhǔn)方差的值+1
for i in range(len(knn_pred)):
if abs(trainy.iat[i, 0] - knn_pred[i]) < err_railway:
right_num += 1
#計算在誤差范圍內(nèi)的準(zhǔn)確度
err4=float(right_num) / len(testx)
print "KNeighborsClassifier accuracy :%f" %( err4)
利用numpy庫可計算出公路貨運(yùn)量數(shù)據(jù)的標(biāo)準(zhǔn)差為1 932。對公路貨運(yùn)量預(yù)測結(jié)果和真實值進(jìn)行比較,在一個標(biāo)準(zhǔn)差的誤差范圍內(nèi),預(yù)測的準(zhǔn)確度見表2。
表2 浙江省公路貨運(yùn)量準(zhǔn)確度
由表2可知,在三種算法中,嶺回歸算法的預(yù)測準(zhǔn)確度比較高,為86%;KNN算法的準(zhǔn)確度排第二,為84%;樸素貝葉斯算法準(zhǔn)確度僅為77%。三種算法在浙江省公路貨運(yùn)量上的誤差曲線如圖3所示。根據(jù)不同算法的測試結(jié)果可得出,嶺回歸算法對浙江省公路貨運(yùn)量預(yù)測準(zhǔn)確度高,可采用此模型進(jìn)行預(yù)測。
圖3 三種算法在浙江省公路貨運(yùn)量上的誤差曲線
本文結(jié)合監(jiān)督學(xué)習(xí)算法中的嶺回歸算法、樸素貝葉斯算法和KNN算法在深度學(xué)習(xí)領(lǐng)域中的應(yīng)用,提出一種浙江省公路貨運(yùn)量預(yù)測方法。在三種算法中,根據(jù)浙江省2007年1月以來的公路貨運(yùn)量數(shù)據(jù)集的標(biāo)簽集合,選擇年份和月份值作為輸入變量的特征值,實際公路貨運(yùn)量表示為比較標(biāo)準(zhǔn)值;然后分別利用三種算法作為預(yù)測模型,訓(xùn)練樣本數(shù)據(jù),獲得較高的準(zhǔn)確度,可在最后的測試集進(jìn)行準(zhǔn)確度驗證,利用訓(xùn)練后的模型對將來的某年某月(兩個特征值)的公路貨運(yùn)量數(shù)據(jù)進(jìn)行預(yù)測。嶺回歸算法在測試集中取得了良好的效果,獲得了較好的準(zhǔn)確度,表明具有一定的優(yōu)越性。后續(xù)將繼續(xù)對其他不同算法進(jìn)行分析討論,選出更優(yōu)模型。在此基礎(chǔ)上,相關(guān)部門應(yīng)基于大數(shù)據(jù)平臺強(qiáng)化行業(yè)輔助決策分析思想,提出整個體系的總體思路、決策體系和實施路徑,并進(jìn)一步加強(qiáng)大數(shù)據(jù)分析、基礎(chǔ)設(shè)施規(guī)劃、貨運(yùn)管理與優(yōu)化、征信體系建設(shè)等方面貨運(yùn)物流大數(shù)據(jù)的應(yīng)用。