宮薇薇 齊向春 裴世廉
1(中國(guó)鐵道科學(xué)研究院運(yùn)輸及經(jīng)濟(jì)研究所 北京 100081) 2(沈陽(yáng)鐵路局信息技術(shù)所 遼寧 沈陽(yáng) 110002)
Python由Guido van Rossum于20世紀(jì)90年代編寫,是一種面向?qū)ο蟮慕忉屝驼Z(yǔ)言,功能強(qiáng)大、簡(jiǎn)單易學(xué)、完全免費(fèi)。擁有大量的算法、圖庫(kù)及各種基于Web的應(yīng)用庫(kù),受編程初學(xué)者及試驗(yàn)者的廣泛歡迎。特別是在大數(shù)據(jù)時(shí)代,Python兼顧算法和應(yīng)用開(kāi)發(fā),是Spark三大開(kāi)發(fā)語(yǔ)言之一,是大數(shù)據(jù)采集、處理及數(shù)據(jù)可視化的最佳開(kāi)發(fā)語(yǔ)言。但是其在數(shù)理統(tǒng)計(jì)特別是預(yù)測(cè)算法方面略顯不足,以Holt-Winters算法為例,Python seasonal算法包不夠成熟,使用復(fù)雜,應(yīng)用需要大量的編程工作。R語(yǔ)言是一種超強(qiáng)的數(shù)理統(tǒng)計(jì)算法庫(kù),歷史悠久,擁有比Python更加成熟的算法包,使用方便,參數(shù)簡(jiǎn)潔,自身不具備Web應(yīng)用開(kāi)發(fā)的諸多功能,但對(duì)Java、.net、Python都具有良好的接口。
因此,本文提出通過(guò)Python調(diào)用R語(yǔ)言,充分利用各自的優(yōu)點(diǎn),發(fā)揮Python開(kāi)發(fā)應(yīng)用程序和粘合的功能,彌補(bǔ)其在算法包方面的不足。討論本地和遠(yuǎn)程兩種調(diào)用方法,并開(kāi)發(fā)基于Echarts可視化數(shù)據(jù)面板的Holt-Winters算法Web應(yīng)用。
Python對(duì)R的調(diào)用方法主要通過(guò)第三方庫(kù)進(jìn)行。如果將兩種語(yǔ)言均安裝在同一臺(tái)PC上,需要在設(shè)置完環(huán)境變量的基礎(chǔ)上,通過(guò)rpy2庫(kù)進(jìn)行調(diào)用。如果分別設(shè)置服務(wù)器,則需要在R語(yǔ)言的基礎(chǔ)上安裝RServe,在Python上安裝PyRserve進(jìn)行服務(wù)的遠(yuǎn)程調(diào)用。兩種方法的調(diào)用流程如圖1所示。

圖1 Python調(diào)用R流程圖
單機(jī)版通過(guò)rpy2,服務(wù)器版通過(guò)RServe/PyRserve進(jìn)行調(diào)用。通過(guò)Python進(jìn)行Flask Web、MySQLdb進(jìn)行數(shù)據(jù)庫(kù)、pySaprk進(jìn)行大數(shù)據(jù)、ECharts進(jìn)行數(shù)據(jù)可視化等擴(kuò)展開(kāi)發(fā),調(diào)用R語(yǔ)言pylr、forecast提高應(yīng)用平臺(tái)預(yù)測(cè)算法的能力。
在混編之前,首先需要對(duì)兩種軟件進(jìn)行安裝和測(cè)試。如果采用本地模式,則將兩種軟件安裝在同一臺(tái)PC機(jī)上;如果采用服務(wù)器模式則將兩種軟件分別運(yùn)行安裝。
Python:在https://www.continuum.io/downloads,下載Anaconda軟件并安裝。與安裝Python軟件相比,該軟件不需要配置Python環(huán)境變量,同時(shí)已完成大量常用庫(kù)的更新。cmd進(jìn)入命令行,輸入python(如圖2所示),如果能夠顯示Python和Anaconda的版本號(hào),說(shuō)明安裝成功。

圖2 Python安裝成功
在http://www.jetbrains.com/pycharm/網(wǎng)站,下載Pycharm軟件,進(jìn)行安裝。在File—〉Settings—〉Project—〉Project Interpreter中選擇安裝目錄下的Python作為編譯器,如:C:UsersgwwAnaconda2python.exe。如果需要添加更多的庫(kù),點(diǎn)擊右側(cè)加號(hào)進(jìn)行搜索添加。新建.py文件,輸入print('hello'),首次運(yùn)行,環(huán)境需要一段時(shí)間進(jìn)行更新,完畢后執(zhí)行py文件查看打印結(jié)果。
R語(yǔ)言:訪問(wèn)官網(wǎng)https://www.r-project.org/,點(diǎn)擊download下載最新版本R語(yǔ)言軟件。安裝完畢后,在系統(tǒng)環(huán)境變量Path中添加R語(yǔ)言的include和bin文件夾的位置,如:
C:Program FilesRR-3.3.0include;C:Program FilesRR-3.3.0in
cmd進(jìn)入命令行,輸入R,如果能夠顯示R語(yǔ)言版本號(hào),說(shuō)明安裝成功。打開(kāi)R語(yǔ)言環(huán)境,輸入命令install.packages安裝預(yù)測(cè)軟件包,設(shè)置dependencies 為TRUE完成依賴包的安裝,完整書(shū)寫如下:
install.packages(″forecast″, dependencies = TRUE)
在R語(yǔ)言環(huán)境中輸入以下語(yǔ)句進(jìn)行測(cè)試:
skirts<- scan(″http://robjhyndman.com/tsdldata/roberts/
skirts.dat″,skip=5)
skirtsseries <- ts(skirts,start=c(1866))
plot.ts(skirtsseries)
執(zhí)行效果如圖3所示,說(shuō)明安裝成功。

圖3 R語(yǔ)言輸出結(jié)果
在完成了兩種軟件的安裝及測(cè)試后,對(duì)于采用本地模式,具體調(diào)用步驟如下:
步驟1從http://www.lfd.uci.edu/~gohlke/pythonlibs/#rpy2下載文件rpy2-2.5.6-cp27-none-win_amd64.whl,將其拷貝至新建工程的根目錄下,執(zhí)行pip install命令:pip install rpy2-2.5.6-cp27-none-win_amd64.whl。
步驟2新建用戶變量R_HOME,變量值為R語(yǔ)言安裝目錄,如:C:Program FilesRR-3.3.2。
步驟3新建用戶變量R_USER,變量值為rpy2的安裝目錄,如:C:UsersgwwAnaconda2libsite-packages py2。
步驟4在Pycharm中新建.py文件,引入rpy2庫(kù),然后使用ro.r('')執(zhí)行R語(yǔ)言,通過(guò)變量賦值形式獲得計(jì)算結(jié)果,代碼如下:
import rpy2.robjects as ro
ro.r(′library(forecast)′)
ro.r(′skirts<- scan(″http://robjhyndman.com/tsdldata/
roberts/
skirts.dat″,skip=5)′) # generate x at R
ro.r(′skirtsseries <- ts(skirts,start=c(1866))′)
ro.r(′skirtsseriesforecasts <- HoltWinters
(skirtsseries, gamma=FALSE)′)
ro.r(′skirtsseriesforecasts2 <- forecast.HoltWinters
(skirtsseriesforecasts, h=19)′)
skirtsseries =ro.r(′skirtsseries′)
print skirtsseries
skirtsseriesforecasts2 =ro.r(′skirtsseriesforecasts2′)
print skirtsseriesforecasts2
遠(yuǎn)程調(diào)用方式,需要在R語(yǔ)言上安裝RServe,在Python上安裝PyRserve庫(kù),具體步驟如下:
步驟1在http://www.rforge.net/Rserve/files/下載Rserve_1.8-0.zip,在R語(yǔ)言中點(diǎn)擊程序包->Install package(s) from local files進(jìn)行本地安裝。也可以在使用命令行進(jìn)行遠(yuǎn)程安裝:
install.packages(′Rserve′,,′http://www.rforge.net/′)
步驟2啟動(dòng)RServe,執(zhí)行如下命令開(kāi)啟遠(yuǎn)程訪問(wèn)連接:
> library(Rserve)
> Rserve(args=′--RS-enable-remote′)
輸出以下結(jié)果,說(shuō)明啟動(dòng)成功。
Starting Rserve...
″C:ANACON~1LibSITE-P~1 py2RWIN-LI~13.3Rservelibsx64Rserve.exe″ --RS-enable-remote
步驟3在Pycharm環(huán)境下,打開(kāi)File—〉Settings—〉Project—〉Project Interpreter,點(diǎn)擊右側(cè)加號(hào),搜索pyRserve,并進(jìn)行安裝。
步驟4在.py文件中編寫代碼,引入PyRserve,建立conn,進(jìn)行RServe的遠(yuǎn)程連接。通過(guò)conn.eval和conn.voidEval進(jìn)行R語(yǔ)言語(yǔ)句的執(zhí)行。如果想進(jìn)一步查找更多實(shí)用方法及變量互傳,訪問(wèn)pyRserve網(wǎng)站http://pythonhosted.org/pyRserve/。使用以下代碼進(jìn)行測(cè)試:
import pyRserve
conn = pyRserve.connect(host=′Rserve IP地址′, port=6311)
aa = conn.eval(′13 + 25′)
conn.voidEval(″t <- c(-8.49, 0.99)″)
print(conn.r.t)
print(aa)
conn.close()
使用R語(yǔ)言的HoltWinters方法,執(zhí)行語(yǔ)句如下:
import pyRserve
conn = pyRserve.connect(host=′ Rserve IP地址′, port=6311)
conn.eval(′library(forecast)′)
conn.eval(′skirts <- scan(″http://robjhyndman.com/
tsdldata/
roberts/skirts.dat″,skip=5)′)
conn.eval(′skirtsseries <- ts(skirts,start=c(1866))′)
conn.eval(′skirtsseriesforecasts <- HoltWinters(
skirtsseries, gamma=FALSE)′)
conn.eval(′skirtsseriesforecasts2 <- forecast.
HoltWinters(skirtsseriesforecasts, h=6)′)
conn.eval(′skirtsseriesforecasts2 <- forecast.
HoltWinters(skirtsseriesforecasts, h=19)′)
conn.voidEval(′func0<-function(){skirtsseriesforecasts2}′)
print(conn.r.func0())
使用ECharts作為測(cè)算結(jié)果的可視化工具,應(yīng)用Python Flask作為網(wǎng)站框架,在阿里云平臺(tái)上申請(qǐng)ECS作為R語(yǔ)言服務(wù)器,實(shí)現(xiàn)Holt-Winters預(yù)測(cè)算法的Web應(yīng)用示例開(kāi)發(fā)。
步驟1布置阿里云ECS R語(yǔ)言服務(wù)器。為了R語(yǔ)言運(yùn)算和使用方便,應(yīng)用于多用戶解決實(shí)際問(wèn)題,在阿里云上申請(qǐng)ECS空間實(shí)例,系統(tǒng)選擇Windows Server 2012 R2 數(shù)據(jù)中心版64位中文版(如圖4所示),設(shè)置白名單,允許遠(yuǎn)程訪問(wèn)。

圖4 阿里云ESC設(shè)置
使用mstsc.exe進(jìn)行遠(yuǎn)程桌面的連接和登錄,安裝R語(yǔ)言、更新軟件包、完成配置、啟動(dòng)遠(yuǎn)程訪問(wèn)。如圖5所示。

圖5 阿里云R語(yǔ)言服務(wù)器配置
步驟2配置Flask環(huán)境。在本地機(jī)器上安裝Python,Pycharm,并加載flask、pyRserve等包。新建Flask Web應(yīng)用,選擇Anaconda作為編譯器。
步驟3Holt-Winters算法編入。打開(kāi)Flask項(xiàng)目的.py路由文件,將遠(yuǎn)程訪問(wèn)步驟4中的語(yǔ)句輸入,采用json數(shù)據(jù)形式進(jìn)行參數(shù)返回,代碼框架如下:
from flask import Flask, jsonify
@app.route(′/getResult′)
def getResult():
import pyRserve
conn = pyRserve.connect(host=′ Rserve IP地址′,
port=6311)
…
conn.voidEval(′func0<-function(){skirtsseriesforecasts2}′)
return jsonify(result= conn.r.func0())
步驟4ECharts可視化顯示。使用Boostrap框架設(shè)計(jì)Web界面樣式,嵌入需要使用的ECharts圖表,通過(guò)步驟3中的getResult()函數(shù)獲取輸出結(jié)果,進(jìn)行Echarts圖表的數(shù)據(jù)更新和顯示。核心javascript編碼如下:
$.getJSON(′/ getResult ′, function(data){
console.log(″從服務(wù)器收到:″+data.result[1]);
option.series[0].data.shift();
option.series[0].data = data.result[1];
myChart.setOption(option);}
基于上述方法,使用月度貨運(yùn)量數(shù)據(jù)進(jìn)行程序運(yùn)行,使用Holt-Winters預(yù)測(cè)未來(lái)6個(gè)月的運(yùn)量,輸出界面如圖6所示。

圖6 ECharts輸出面板
Python和R語(yǔ)言都是主流的免費(fèi)計(jì)算科學(xué)軟件,Python的各種應(yīng)用開(kāi)發(fā)功能是R語(yǔ)言所不具備的,R語(yǔ)言簡(jiǎn)潔成熟的算法包可以彌補(bǔ)Python軟件在該方面的不足。因此,通過(guò)使用Python調(diào)用R語(yǔ)言,可以發(fā)揮R語(yǔ)言算法在Web應(yīng)用中的大數(shù)據(jù)挖掘功能,完善Python解決實(shí)際問(wèn)題的運(yùn)算功能。通過(guò)開(kāi)發(fā)基于ECharts的Flask Web應(yīng)用,嵌入R語(yǔ)言Holt-Winters算法,證明了該方案的有效性和實(shí)際應(yīng)用的可行性。
[1] 孫強(qiáng),李建華,李生紅.基于Python的文本分類系統(tǒng)開(kāi)發(fā)研究[J].計(jì)算機(jī)應(yīng)用與軟件,2011,28(3):13-14.
[2] 王國(guó)強(qiáng),張貝克.基于Python的嵌入式腳本研究[J].計(jì)算機(jī)應(yīng)用與軟件,2010,27(3):107-109.
[3] 王曉宇,陳吉紅,黃植紅.一種基于Python的紅外圖像分析軟件結(jié)構(gòu)[J].計(jì)算機(jī)應(yīng)用與軟件,2008,25(11):31-33.
[4] 羅霄,任勇,山秀明.基于Python的混合語(yǔ)言編程及其實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用與軟件,2004,21(12):17-18,112.
[5] Grinberg M.Flask Web開(kāi)發(fā):基于Python的Web應(yīng)用開(kāi)發(fā)實(shí)戰(zhàn)[M].安道,譯.北京:人民郵電出版社,2015:7-18.
[6] 張若愚.Python科學(xué)計(jì)算[M].北京:清華大學(xué)出版社,2012:1.
[7] http://pythonhosted.org/pyRserve/.
[8] https://cran.r-project.org/web/packages/forecast/.
[9] http://echarts.baidu.com/.