在Python中访问R用户定义函数

3

我需要进行带交叉验证的主成分回归(Principle Component Regression),但在Python中找不到相应的软件包。我编写了自己的PCR类,但与R的pls包进行测试时,在高维数据(~50000个特征)上表现显著较差,并且速度更慢,尽管我仍不确定原因,但这是另一个问题。由于我的其他代码都是用Python编写的,为了节省时间,我决定最好的方法可能是编写一个利用R中PLS软件包的R函数。以下是该函数:

R_pls <-function(X_train,y_train,X_test){
  library(pls)
  X<-as.matrix(X_train)
  y<-as.matrix(y_train)
  tdata<-data.frame(y,X=I(X))
  REGmodel <- pcr(y~X,scale=FALSE,data=tdata,validation="CV")
  B<-RMSEP(REGmodel)
  C<-B[[1]]
  q<-length(C)
  degs<-c(1:q)
  allvals<-C[degs%%2==0]
  allvals<-allvals[-1]
  comps<-which.min(allvals)
  xt<-as.matrix(X_test)
  ndata<-data.frame(X=I(xt))
  ypred_test<-as.data.frame(predict(REGmodel,ncomp=comps,newdata=ndata,se.fit=TRUE))
  ntdata<-data.frame(X=I(X))
  ypred_train<-as.data.frame(predict(REGmodel,ncomp=comps,newdata=ntdata,se.fit=TRUE))
  data_out=list(ypred_test=ypred_test,ypred_train=ypred_train)
  return(data_)
}

我发现了很多关于如何访问R内置函数的信息,但对于这种情况似乎没有找到任何内容。因此,我尝试了以下方法:

import rpy2.robjects as ro
prs=ro('R_pls')

R_pls是上面所述的R函数。这将产生

TypeError: 'module' object is not callable.

有什么想法可以让这个工作起来,如果有更好的方法,我很乐意听取建议。

谢谢。


我相当确定sklearn中有偏最小二乘回归和PCA分解。你试过在那里找找看它是否有你需要的东西吗?我知道这不是标题的直接答案,但可能会有所帮助。 - be_green
因此,我使用了sklearn.decomposition PCA和sklearn线性回归来构建PCR类,但是这种方法的表现不如R好,我不确定原因是什么? - Joshua Mannheimer
虽然它本身不执行PCR,但您可以始终计算组件,然后使用具有Python和R接口的h2o执行lm / glm模型。http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/pca.html - be_green
1个回答

4
考虑使用rpy2的SignatureTranslatedAnonymousPackage (STAP)将任意的R用户定义函数作为一个包导入:
from rpy2.robjects.numpy2ri import numpy2ri, pandas2ri
from rpy2.robjects.packages import STAP
# for rpy2 < 2.6.1
# from rpy2.robjects.packages import SignatureTranslatedAnonymousPackage as STAP    

r_fct_string = """    
R_pls <- function(X_train, y_train, X_test){
  library(pls)

  X <- as.matrix(X_train)
  y <- as.matrix(y_train)
  xt <- as.matrix(X_test)

  tdata <- data.frame(y,X=I(X))
  REGmodel <- pls::pcr(y~X,scale=FALSE,data=tdata,validation="CV")
  B <- RMSEP(REGmodel)
  C <- B[[1]]
  q <- length(C)
  degs <- c(1:q)
  allvals <- C[degs%%2==0]
  allvals <- allvals[-1]
  comps <- which.min(allvals)
  ndata <- data.frame(X=I(xt))

  ypred_test <- as.data.frame(predict(REGmodel,ncomp=comps,newdata=ndata,se.fit=TRUE))
  ntdata <- data.frame(X=I(X))
  ypred_train <- as.data.frame(predict(REGmodel,ncomp=comps,newdata=ntdata,se.fit=TRUE))
  data_out <- list(ypred_test=ypred_test, ypred_train=ypred_train)

  return(data_out)
}
"""

r_pkg = STAP(r_fct_string, "r_pkg")

# CONVERT PYTHON NUMPY MATRICES TO R OBJECTS
r_X_train, r_y_train, r_X_test = map(numpy2ri, py_X_train, py_y_train, py_X_test)

# PASS R OBJECTS INTO FUNCTION (WILL NEED TO EXTRACT DFs FROM RESULT)
p_res = r_pkg.R_pls(r_X_train, r_y_train, r_X_test)

或者,您可以像@agstudy在这里所示的那样获取该函数的源代码,如果该函数保存在单独的.R脚本中,则可以像调用任何Python函数一样调用它。

import rpy2.robjects as ro
robjects.r('''source('my_R_pls_func.r')''')

r_pls = ro.globalenv['R_pls']

# CONVERT PYTHON NUMPY MATRICES TO R OBJECTS
r_X_train, r_y_train, r_X_test = map(numpy2ri, py_X_train, py_y_train, py_X_test)

# PASS R OBJECTS INTO FUNCTION (WILL NEED TO EXTRACT DFs FROM RESULT)
p_res = r_pls(r_X_train, r_y_train, r_X_test)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接