龔大豐,田啟明
(溫州職業技術學院 信息技術系,浙江 溫州 325035)
據國家發改委、中國物流與采購聯合會的通報顯示,2017年全國社會物流總額252.8萬億元,按可比價格計算,同比增長6.7%,增速比上年同期提高0.6個百分點。從分季度看,2017年一季度56.7萬億元,增長7.1%,提高1.1個百分點;上半年118.9萬億元,增長7.1%,提高0.9個百分點,全年社會物流總需求呈現穩中有升的發展態勢。[1]隨著國家對長三角區域經濟發展的重視,浙江省貨運規模不斷擴大,經濟結構、服務模式逐步優化。據浙江省統計局公開發布的數據顯示,2007年1月—2018年3月,浙江省鐵路貨運總量超過37 730萬t,公路貨運總量超過1 222 347萬t,水路貨運總量超過723 398萬t,同比和環比都有明顯增長[2]。這對浙江省交通規劃和運輸能力等提出了嚴峻考驗。
經濟和科技的高速發展,促進了浙江省貨運的現代化轉型,貨運在當今的經濟發展中有著重要地位,而貨運量的變化,直接反應一個地區的經濟狀況。運用大數據技術進行管理,做好公路貨運量的科學預測,能幫助各地區進行智慧交通管理[3],也可提高公路貨運企業的效益,促進公路貨運行業持續、健康和穩定發展[4],為政府開展更合理的路政管理和服務工作及對當地公路規劃和建設具有較強的指導意義。本文運用機器學習算法分析浙江省公路貨運量的變化情況,嘗試發現其變化規律并做出預測,為相關部門提供參考依據。
由于浙江省公路貨運量數據源本身帶有所需屬性和結果標簽值,因而選擇監督機器學習算法,結合當前開源且主流的python編程語言和scrapy數據采集框架,實現訓練模型的預測功能。目前,國內外貨運量預測中通常采用組合模型、無偏灰色預測模型、神經網絡、回歸曲線模型等多種形式,其中回歸模型是一種具體的、行之有效的、實用價值很高的預測途徑,因而在貨運量預測中常常選用回歸模型。通過分析浙江省歷年公路貨運量數據,可得出它們具有較強的相關性,基本符合回歸預測的條件。由于回歸預測模型類型較多,致使預測方法不易選擇,不同的模型預測結果與實際的差距在精度和可靠性方面都不盡相同。本文對監督機器學習算法中的嶺回歸算法、樸素貝葉斯算法和KNN算法進行預測分析,對比結果優劣,同時也為分析其他數據提供參考。
嶺回歸,又稱脊回歸或吉洪諾夫正則化,是對不適定問題進行回歸分析時最經常使用的一種正則化方法[5]。嶺回歸通過對矩陣X'X的對角線上增加一組正常數(即嶺參數),降低其病態程度,使得求逆運算相對穩定。如果嶺參數的選擇合理,嶺回歸估計的結果會在僅犧牲較小的無偏性下極大地降低參數估計量的方差。因此,從MSE的標準看,嶺回歸可能優于普通最小二乘估計,即β=(X'X)-1X'Y。在X'X主對角線上增加一個常數后,得到嶺回歸估計的一般形式為:

其中,k為嶺參數,通常k≥0,當k=0時,嶺估計即為最小二乘估計,Ip+1為單位矩陣[6]。嶺回歸是對最小二乘回歸的一種補充,它損失了無偏性來換取高的數值穩定性,從而得到較高的計算精度。
樸素貝葉斯算法是基于貝葉斯定理與特征條件獨立假設的分類方法,二者是樸素貝葉斯的兩個重要的理論基礎。
先驗證多項式分布的樸素貝葉斯假設特征的先驗概率為多項式分布,多項式樸素貝葉斯是一種生成式模型,可通過(2)式獲得,即:

對于樸素貝葉斯算法而言,也就是具有最大后驗概率(max-imum a posteriori)估計值的類別,即:

(3)式計算條件概率的乘積,可能會導致浮點數下界溢出,所以引入對數得[7]:

KNN算法,又稱k個近鄰分類(k-nearest neighbor classification)算法。它是根據不同特征值之間的距離進行分類的一種簡單的機器學習方法,其訓練數據都是有標簽的數據。KNN算法可用于回歸,通過找出一個樣本的k個最近鄰居,將這些鄰居的屬性的平均值賦給該樣本,就可得到該樣本的屬性。
KNN算法用于分類的核心思想是:存在一個樣本數據集合,又稱訓練樣本集,并且樣本集中每個數據都存在標簽。輸入沒有標簽的新數據后,將新數據的每個特征與樣本集中數據對應的特征進行比較,然后算法提取樣本集中特征最相似數據(最近鄰)的結果。一般而言,只選擇樣本數據集中前k個最相似的數據,這就是k近鄰算法中k的出處(通常k<20)[8]。
為了對浙江省公路貨運量進行合理預測,獲得一個比較滿意的模型供今后參考使用,為數據采集到結果分析的整個實現過程設計如下流程:
(1)通過目前常用的爬蟲技術,從浙江省統計局官方網站采集2007年1月—2018年3月所有關于公路的貨運數據,部分月份數據不全者進行簡單的預處理,保存到本地存儲。
(2)以公路貨運數據為研究對象,由于所采集數據是當年當月累加值,如3月公布的數據是1月至3月的三個月總量,還需要進一步處理數據,轉化為當月貨運量。
(3)對預處理后的公路貨運數據,按照嶺回歸算法、樸素貝葉斯算法和KNN算法要求,設計出模型所需的訓練集和測試集數據,訓練出各模型對應參數,然后用測試集數據進行測試,得出各種算法的準確度。
(4)分析各模型的準確度,選擇一種較好的算法作為預測模型。
(5)根據上一步驟的結果,確定公路貨運預測算法。
浙江省公路貨運量數據采集分析流程如圖1所示。

圖1 浙江省公路貨運量數據采集分析流程
數據采集環節采用當前流行的python環境下的scrapy爬蟲框架。scrapy是python開發的一個快速、高層次的屏幕抓取和web抓取框架,用于抓取web站點,并從頁面中提取結構化的數據。其步驟如下:
(1)安裝scrapy框架,在命令行下,運行pip install scrapy命令即可實現。
(2)創建爬蟲項目,在命令行下,執行scrapy startproject zjstatistics,就會在目標目錄下創建框架文件,如圖2所示。

圖2 scrapy項目框架結構
(3)創建爬蟲文件spider.py,主要實現對網絡請求返回的數據解析,爬取url深度為2,即目錄頁和貨運量數據具體內容頁,參考代碼如下:
#解析內容函數
def parse(self, response):
item = ZjstatisticsItem( )
#獲得當前Web請求結果,并正則匹配子頁鏈接URL
res = response.selector.xpath('//tr/td//@href')
#遍歷所有結果
for re in res:
#字符按utf-8解碼
suburl = re.extract( ).decode('utf-8')
#拼湊成完整的url
item['url'] = suburl[1:]
......
#返回解析結果
yield item
(4)代碼調試無誤后,運行scrapy crawl zjstatistics命令即可實現數據采集,保存到當前data.csv文件,所采集結果見表1。根據公路貨運量數據,將其中的90%數據作為各模型的訓練集使用,10%數據作為驗證對應模型的準確度進行分析對比。

表1 浙江省公路貨運量數據采集結果
數據預處理的目的是清洗無效數據,將所需數據轉化為目標要求格式,為下一步調用算法需要傳遞的數據集參數做準備。其預處理的主要代碼如下:
#讀取文件內容
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]
#獲得三列數據
src = pd.DataFrame(data, columns=['year','month',’highway’])
#讀取第1、2列為變量集,第3列為結果集
X = src.iloc[:,0:2]
Y = src.iloc[:,2:3]
#隨機分配訓練集和測試集,由于數據量不夠大,按9:1分配
trainx,testx,trainy,testy=train_test_split(X,Y,test_size=0.1,random_state=0)
分別采用嶺回歸算法、樸素貝葉斯算法和KNN算法,實現對公路貨運量數據模型的訓練。
(1)基于嶺回歸算法的實現。
#這里指定使用嶺回歸作為基函數
#定義模型
pp = make_pipeline(PolynomialFeatures((3)),Ridge( ))
#訓練模型
pp.fit(trainx, trainy)
#預測測試集
pp_pred = pp.predict(testx)
#計算符合誤差范圍的個數,符合一個標準差的值+1
right_num = 0
right_num =( abs(trainy - pp_pred)<=err_railway).sum( )
#計算在誤差范圍內的準確度
err2=float(right_num) / len(testx)
#打印顯示結果
print "PolynomialFeatures accuracy :%f" %( err2)
(2)基于樸素貝葉斯算法的實現。
#定義貝葉斯模型
clf=MultinomialNB( )
#訓練模型并預測測試集
clf_pred = clf.fit(trainx, trainy).predict(testx)
right_num =( )
#計算符合誤差范圍的個數,符合一個標準方差的值+1
for i in range(len(clf_pred)):
if abs(trainy.iat[i, 0] - clf_pred[i]) < err_railway:
right_num += 1
#計算在誤差范圍內的準確度
err3=float(right_num) / len(testx)
print "MultinomialNB accuracy :%f" %( err3)
(3)基于KNN算法的實現。
#定義Knn模型
knn = neighbors.KNeighborsClassifier( )
#訓練模型
knn.fit(trainx, trainy)
#預測測試集
knn_pred = knn.predict(testx)
right_num = 0
#計算符合誤差范圍的個數,符合一個標準方差的值+1
for i in range(len(knn_pred)):
if abs(trainy.iat[i, 0] - knn_pred[i]) < err_railway:
right_num += 1
#計算在誤差范圍內的準確度
err4=float(right_num) / len(testx)
print "KNeighborsClassifier accuracy :%f" %( err4)
利用numpy庫可計算出公路貨運量數據的標準差為1 932。對公路貨運量預測結果和真實值進行比較,在一個標準差的誤差范圍內,預測的準確度見表2。

表2 浙江省公路貨運量準確度
由表2可知,在三種算法中,嶺回歸算法的預測準確度比較高,為86%;KNN算法的準確度排第二,為84%;樸素貝葉斯算法準確度僅為77%。三種算法在浙江省公路貨運量上的誤差曲線如圖3所示。根據不同算法的測試結果可得出,嶺回歸算法對浙江省公路貨運量預測準確度高,可采用此模型進行預測。

圖3 三種算法在浙江省公路貨運量上的誤差曲線
本文結合監督學習算法中的嶺回歸算法、樸素貝葉斯算法和KNN算法在深度學習領域中的應用,提出一種浙江省公路貨運量預測方法。在三種算法中,根據浙江省2007年1月以來的公路貨運量數據集的標簽集合,選擇年份和月份值作為輸入變量的特征值,實際公路貨運量表示為比較標準值;然后分別利用三種算法作為預測模型,訓練樣本數據,獲得較高的準確度,可在最后的測試集進行準確度驗證,利用訓練后的模型對將來的某年某月(兩個特征值)的公路貨運量數據進行預測。嶺回歸算法在測試集中取得了良好的效果,獲得了較好的準確度,表明具有一定的優越性。后續將繼續對其他不同算法進行分析討論,選出更優模型。在此基礎上,相關部門應基于大數據平臺強化行業輔助決策分析思想,提出整個體系的總體思路、決策體系和實施路徑,并進一步加強大數據分析、基礎設施規劃、貨運管理與優化、征信體系建設等方面貨運物流大數據的應用。