rpy2中行魔法执行SVM回归时递归深度超限问题
解决rpy2行魔法调用R SVM回归时的递归深度超出错误
问题重现
使用Python 3.9.13 + rpy2 3.5.1,在Jupyter Notebook中通过**行魔法%R**执行SVM回归代码时触发RecursionError: maximum recursion depth exceeded in comparison,但用单元格魔法%%R执行相同逻辑却正常。需要将代码整合进Python类,因此必须使用行魔法,调整sys.setrecursionlimit()无效。
原代码:
%load_ext rpy2.ipython import pandas as pd from sklearn.datasets import load_iris iris_data = load_iris() Data = pd.DataFrame(data=iris_data.data, columns=iris_data.feature_names) from rpy2.robjects.conversion import localconverter from rpy2.robjects import pandas2ri import rpy2.robjects as ro with localconverter(ro.default_converter + pandas2ri.converter): R_Data = ro.conversion.py2rpy(Data) %R -i R_Data %R library('e1071') %R model_full <- svm(R_Data , R_Data['sepal length (cm)']) %R full_pred <- predict(model_full , newdata = R_Data)
解决方法
方法1:提前提取目标变量,避免行魔法中嵌套索引
行魔法中直接使用R_Data['sepal length (cm)']可能触发Python与R对象转换的递归循环,先把目标变量单独转为R对象再传入:
# 提取目标变量并转为R对象 with localconverter(ro.default_converter + pandas2ri.converter): R_target = ro.conversion.py2rpy(Data['sepal length (cm)']) %R -i R_Data -i R_target %R library('e1071') %R model_full <- svm(R_Data, R_target) %R full_pred <- predict(model_full, newdata = R_Data)
方法2:改用rpy2的原生API调用R函数(更适合整合进Python类)
直接通过rpy2.robjects调用R的e1071::svm和predict,完全绕开魔法命令,更适合类封装:
%load_ext rpy2.ipython import pandas as pd from sklearn.datasets import load_iris from rpy2.robjects.conversion import localconverter from rpy2.robjects import pandas2ri import rpy2.robjects as ro # 加载R的e1071库 ro.r('library(e1071)') iris_data = load_iris() Data = pd.DataFrame(data=iris_data.data, columns=iris_data.feature_names) # 转换数据到R with localconverter(ro.default_converter + pandas2ri.converter): R_Data = ro.conversion.py2rpy(Data) R_target = ro.conversion.py2rpy(Data['sepal length (cm)']) # 调用R的svm函数 model_full = ro.r['svm'](R_Data, R_target) # 调用predict函数 full_pred = ro.r['predict'](model_full, newdata=R_Data) # 如需转回Python对象 with localconverter(ro.default_converter + pandas2ri.converter): pred_py = ro.conversion.rpy2py(full_pred)
方法3:禁用自动转换,手动管理对象
关闭rpy2的自动转换功能,避免递归转换问题:
from rpy2.robjects import globalenv # 把R_Data直接放入R全局环境 globalenv['R_Data'] = R_Data # 提取目标变量到R全局环境 globalenv['R_target'] = R_target # 用行魔法执行 %R library('e1071') %R model_full <- svm(R_Data, R_target) %R full_pred <- predict(model_full, newdata = R_Data)
原因说明
行魔法%R在处理嵌套的R对象索引时,可能触发Python与R之间的双向转换递归循环,而单元格魔法%%R是在独立的R上下文执行,不会触发这类递归。调整递归深度无法解决根本问题,需要从变量传递或调用方式上避免循环转换。
内容的提问来源于stack exchange,提问作者Bharath Chand
相关产品推荐
相关产品推荐

