IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    利用R和opencpu搭建HTTP服务

    刘思喆@贝吉塔行星发表于 2017-04-28 00:00:00
    love 0

    opencpu在CentOS 7平台上的安装

    不同平台的安装方式不同,这里使用了标配的CentOS 7,该平台需要自行编译rpm包,具体操作过程请参考这里。

    安装结束后,请测试

    curl http://localhost/ocpu/library/
    

    返回了全部的R包列表,则表明安装成功。

    可能会涉及 opencpu 的重新启动,直接利用以下命令:

    sudo apachectl restart
    

    利用RStudio快速创建服务

    使用RStudio做package check&build非常方便,我们可以很轻松在CentOS7上安装一个Server版。 这里有一个小细节,RStudio安装完毕后,利用Web界面登陆(建议用Firefox),此时不能使用root账号直接登录,我们可以add一个名为 bjt 的账号登录,并创建名为 mypackage的包

    利用线上redis缓存来做预测

    特征服务的模拟

    首先将一些数据通过hashmap存入redis缓存,这里利用了pipeline操作

    set.seed(1)
    z <- data.frame(id = sample(30000:90000, 150), iris[, 1:4])
    library("rredis")
    redisConnect()
    redisSetPipeline(TRUE)
    tr <- function(x)
      charToRaw(as.character(x))
    for (i in 1:nrow(z))
      redisHMSet(
        as.character(z[i, 'id']),
        list(
          Sepal.Length = tr(z[i, 'Sepal.Length']),
          Sepal.Width = tr(z[i, 'Sepal.Width']),
          Petal.Length = tr(z[i, 'Petal.Length']),
          Petal.Width = tr(z[i, 'Petal.Width'])
        )
      )
    resp <- redisGetResponse()
    

    我们可以找一些values:

    127.0.0.1:6379> HVALS 42356
    1) "5.4"
    2) "3.7"
    3) "1.5"
    4) "0.2"
    

    关于rredis的使用可以参考以前的博文

    模拟一个预测模型

    利用随机森林包:

    library(randomForest)
    m <- randomForest(Species ~ ., data = iris)
    save(m, file = 'm.Rdata')
    

    保存模型的结果 m.Rdata,注意该文件在构建R包时,需要放置在inst/extdata目录下。

    创建R包

    以下就非常容易了,在RStudio中

    File - New Project - New Directory - R package

    填写包名 mypackage,将以下代码贴入 hello.R 文件中(偷懒了)

    getdata <- function(id='52795'){
      id <- as.character(id)
      rredis::redisConnect()
      nn <- c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width")
      d <- data.frame(t(as.numeric(rredis::redisHVals(id))))
      names(d) <- unlist(rredis::redisHKeys(id))
      rredis::redisClose()
      return(d[nn])
    }
    
    
    hello <- function(id='52795'){
      load(system.file("extdata", "m.Rdata", package = "mypackage"))
      v = randomForest:::predict.randomForest(object = m, newdata = getdata(id))
      v = as.character(v)
      return(list(class = v,
                  url = paste("cc.bjt.name/data?v=", v, "&id=", id, sep = '')))
    }
    

    在DESCRIPTION文件中增加

    Imports:
        randomForest,
        rredis
    

    Ctrl + Shift + E check 一下包是否有问题。没有问题的话,可以选择 Build Binary Package。 返回服务器,在创建好的包目录执行

    R CMD INSTALL mypackage_0.1.0_R_x86_64-redhat-linux-gnu.tar.gz
    

    此时我们的函数通过R包生效。

    通过opencpu提供服务

    opencpu贴心的提供了测试页面,对于我来说是

    http://47.92.114.121:8004/ocpu/test/
    

    在 HTTP request options 中变更请求方式为post,Endpoint 为 ../library/mypackage/R/getdata,同时增加 Param Name 和 Param Value, 请求Ajax,看到

    /ocpu/tmp/x023b988e25/R/.val
    /ocpu/tmp/x023b988e25/stdout
    /ocpu/tmp/x023b988e25/source
    /ocpu/tmp/x023b988e25/console
    /ocpu/tmp/x023b988e25/info
    /ocpu/tmp/x023b988e25/files/DESCRIPTION
    

    说明服务是正常的。

    当然既然服务已就绪,在其他段上可以直接调用返回JSON结果,比如我的是

    [root@iz8vbblvp84015jmqwu5tlz ~]# curl http://47.92.114.121:8004/ocpu/library/mypackage/R/hello/json -d "id=89392" 
    {
      "class": ["virginica"],
      "url": ["cc.bjt.name/data?v=virginica&id=89392"]
    }
    


沪ICP备19023445号-2号
友情链接