-1

我正在努力解决以下问题。我训练了一个模型并将训练好的模型加载到 R 中,如下所示:

model <- readRDS("C://tests/my_model.rds")
result <- predict(model, trainset, type = "prob")[, 2]

一切正常,我可以得到预测。

trainset =
   col1    col2    col2
   1       0       1

但是,当我尝试使用pyperfrom R 调用相同的模型时,我收到以下消息:

TypeError: object of type 'NoneType' has no len()

特别是,expr = 'model <- readRDS(rmodel); result <- predict(model, rdata, type="prob")[,2]'似乎返回无。

这是我的代码:

import json
import numpy as np
import pandas as pd
from pyper import R

def init():
    global r
    r=R(RCMD="C://Program Files/R/R-3.6.2/bin/x64/R.exe", use_pandas=True)
    rds_path = "C://tests/my_model.rds"
    r.assign("rmodel", rds_path)

def run(raw_data, request_headers):
    data = json.loads(raw_data)["data"]
    cols = json.loads(raw_data)["cols"]
    data = pd.DataFrame(np.array(data), columns = cols)
    r.assign("rdata", data)
    expr = 'model <- readRDS(rmodel); result <- predict(model, rdata, type="prob")[,2]'
    r(expr)
    result = r.get('result')

    print(('{{"RequestId":"{0}", '
       '"TraceParent":"{1}", '
       '"NumberOfPredictions":{2}}}'
       ).format(
           request_headers.get("X-Ms-Request-Id", ""),
           request_headers.get("Traceparent", ""),
           len(result)
       ))

    return {"result": result.tolist()}

这就是我调用函数的方式:

init()
test_row = '{"data":[[1,0,1]],"cols":[["col1","col2","col3"]]}'
prediction = run(test_row, {})
print("Test result: ", prediction)

我将非常感谢有关检测问题的任何帮助,因为错误消息的信息量不是很大……</p>

我在 Jupyter Notebook 中做实验。

即使我尝试expr像这样替换(虚拟 R 代码):

expr = 'p <- c(1,2); result <- p'

我收到一个错误:

OSError                                   Traceback (most recent call last)
<ipython-input-97-240ae868eecb> in <module>
      3 test_row  = json.dumps(input_data)
      4 
----> 5 prediction = run(test_row, {})

<ipython-input-96-370705f72e83> in run(raw_data, request_headers)
     23         print(data.head())
     24 
---> 25     r.assign("rdata", data)
     26     expr = 'p <- rdata[1,1:2]; result <- [p]'
     27     r(expr)

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pyper.py in __setitem__(self, obj, val)
    692         if obj.startswith('_'):
    693             raise RError('Leading underscore ("_") is not permitted in R variable names!')
--> 694         self.__call__('%s <- %s' % (obj, Str4R(val)))
    695 
    696     def __delitem__(self, obj):  # to model a dict: "del r['XXX']"

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pyper.py in __call__(self, CMDS, use_try)
    646         rlt = []
    647         if isinstance(CMDS, basestring):  # a single command
--> 648             rlt.append(self.__runOnce(CMDS, use_try=use_try))
    649         else: # should be a list of commands
    650             # for CMD in CMDS:

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pyper.py in __runOnce(self, CMD, use_try)
    622             fn = fn.replace('\\', '/')
    623             CMD = (use_try and 'try({source("%s")})%sfile.remove(%r)%s%s' or '%s%s%s') % (fn, newline, fn, newline, tail_cmd)
--> 624         self.sendAll(self.prog, CMD)
    625         rlt = ''
    626         while not re_tail.search(rlt):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\pyper.py in sendAll(p, s)
    167         p.stdin.write(_mybytes(s))
    168         #os.write(p.stdin.fileno(), s)
--> 169         p.stdin.flush()
    170 
    171     def readLine(p, dump_stdout=False, *a, **b):

OSError: [Errno 22] Invalid argument
4

2 回答 2

1

检查 R 程序返回的数据类型。PypeR 不支持 R 的所有数据类型,并且在转换非原始数据类型时可能会出现一些问题,这就是您r.get()返回None. 尝试将 R 中生成的结果转换为data.frame()或在 R 中list()返回数据之前。

于 2021-02-05T15:07:03.850 回答
1

虽然我没有使用 pyper,但我认为你的错误是当你使用r.assign("rmodel", rds_path). 这应该用于分配 Python 对象,例如将 pandas 数据框分配给 R 实例以使其可用(这是您在run()函数中所做的)。但是,在init()你只传递一个路径的字符串,它不是一个对象。

我认为,将您的 R 模型直接读入 Python 是不可能的。但是,您应该尝试将模型加载到 Python R 实例中。所以把它翻译model <- readRDS("C://tests/my_model.rds")成pypyer。然后,您的模型应该可用并且能够进行预测。

于 2020-01-30T17:04:17.317 回答