使用带插入符号的 rpy2 尝试分类而不是回归
Using rpy2 w/ caret attempts classification instead of regression
我有在 Python 中创建和预处理的数据,我想将其导入 R 并使用 glmnet
执行 k 折交叉验证 LASSO 拟合。我想控制每次折叠中使用哪些观察结果,所以我想使用 caret
来执行此操作。
但是,我发现 caret
将我的数据解释为分类问题而不是回归问题,并迅速失败。我希望这是一个可重现的例子:
import numpy as np
import pandas as pd
import rpy2.robjects as robjects
from rpy2.robjects.packages import importr
from rpy2.robjects import pandas2ri
from rpy2.robjects import numpy2ri
from rpy2.robjects.conversion import localconverter
pandas2ri.activate()
numpy2ri.activate()
# Import essential R packages
glmnet = importr('glmnet')
caret = importr('caret')
base = importr('base')
# Define X and y input
dummy_x = pd.DataFrame(np.random.rand(10000, 5), columns=('a', 'b', 'c', 'd', 'e'))
dummy_y = np.random.rand(10000)
# Convert pandas DataFrame to R data.frame
with localconverter(robjects.default_converter + pandas2ri.converter):
dummy_x_R = robjects.conversion.py2rpy(dummy_x)
# Use caret to perform the fit using default settings
caret_test = caret.train(**{'x': dummy_x_R, 'y': dummy_y, 'method': 'glmnet'})
rpy2 失败,给出来自 R:
的神秘错误消息
RRuntimeError: Error: Metric RMSE not applicable for classification models
这可能是什么原因造成的?根据 ,caret 可能假设我的至少一个变量是整数类型,因此默认认为这是一个分类问题而不是回归问题。
但是,我已经使用 typeof
检查了 X 和 y,它们显然是双打:
base.sapply(dummy_x_R, 'typeof')
>>> array(['double', 'double', 'double', 'double', 'double'], dtype='<U6')
base.sapply(dummy_y, 'typeof')
>>> array(['double', 'double', 'double', ..., 'double', 'double', 'double'],
dtype='<U6')
为什么会出现此错误? train
的所有默认设置都假定为回归模型,那么为什么 caret
以这种方式使用时假定为分类模型?
在这种情况下,第一步是确定意外结果是来自 Python 或 rpy2 端,还是 R 端。
从 pandas 到 R 或 numpy 到 R 的转换似乎按预期工作,至少对于数组类型:
>>> [x.typeof for x in dummy_x_R]
[<RTYPES.REALSXP: 14>,
<RTYPES.REALSXP: 14>,
<RTYPES.REALSXP: 14>,
<RTYPES.REALSXP: 14>,
<RTYPES.REALSXP: 14>]
我猜这就是您可能为 dummy_y
所做的。
>>> from rpy2.robjects import numpy2ri
>>> with localconverter(robjects.default_converter + numpy2ri.converter):
dummy_y_R = robjects.conversion.py2rpy(dummy_y)
>>> dummy_y_R.typeof
<RTYPES.REALSXP: 14>
但是,一个相当微妙的转换细节是问题的根源。 dummy_y_R
具有“形状”(R 中的属性 dim
),而 caret
需要无形状的 R 数组(R 术语中的“向量”)以执行回归。可以强制 dummy_y
成为一个 R 向量:
caret_test = caret.train(**{'x': dummy_x_R,
'y': robjects.FloatVector(dummy_y),
'method': 'glmnet'})
要使用 R 方法,请确保所有输入都是 R 对象。因此,考虑将 dummy_y
numpy 数组转换为 R 向量,您可以使用 base.as_double
:
...
dummy_y_R = base.as_double(dummy_y)
caret.train(x=dummy_x_R, y=dummy_y_R, method='glmnet')
我有在 Python 中创建和预处理的数据,我想将其导入 R 并使用 glmnet
执行 k 折交叉验证 LASSO 拟合。我想控制每次折叠中使用哪些观察结果,所以我想使用 caret
来执行此操作。
但是,我发现 caret
将我的数据解释为分类问题而不是回归问题,并迅速失败。我希望这是一个可重现的例子:
import numpy as np
import pandas as pd
import rpy2.robjects as robjects
from rpy2.robjects.packages import importr
from rpy2.robjects import pandas2ri
from rpy2.robjects import numpy2ri
from rpy2.robjects.conversion import localconverter
pandas2ri.activate()
numpy2ri.activate()
# Import essential R packages
glmnet = importr('glmnet')
caret = importr('caret')
base = importr('base')
# Define X and y input
dummy_x = pd.DataFrame(np.random.rand(10000, 5), columns=('a', 'b', 'c', 'd', 'e'))
dummy_y = np.random.rand(10000)
# Convert pandas DataFrame to R data.frame
with localconverter(robjects.default_converter + pandas2ri.converter):
dummy_x_R = robjects.conversion.py2rpy(dummy_x)
# Use caret to perform the fit using default settings
caret_test = caret.train(**{'x': dummy_x_R, 'y': dummy_y, 'method': 'glmnet'})
rpy2 失败,给出来自 R:
的神秘错误消息RRuntimeError: Error: Metric RMSE not applicable for classification models
这可能是什么原因造成的?根据
但是,我已经使用 typeof
检查了 X 和 y,它们显然是双打:
base.sapply(dummy_x_R, 'typeof')
>>> array(['double', 'double', 'double', 'double', 'double'], dtype='<U6')
base.sapply(dummy_y, 'typeof')
>>> array(['double', 'double', 'double', ..., 'double', 'double', 'double'],
dtype='<U6')
为什么会出现此错误? train
的所有默认设置都假定为回归模型,那么为什么 caret
以这种方式使用时假定为分类模型?
在这种情况下,第一步是确定意外结果是来自 Python 或 rpy2 端,还是 R 端。
从 pandas 到 R 或 numpy 到 R 的转换似乎按预期工作,至少对于数组类型:
>>> [x.typeof for x in dummy_x_R]
[<RTYPES.REALSXP: 14>,
<RTYPES.REALSXP: 14>,
<RTYPES.REALSXP: 14>,
<RTYPES.REALSXP: 14>,
<RTYPES.REALSXP: 14>]
我猜这就是您可能为 dummy_y
所做的。
>>> from rpy2.robjects import numpy2ri
>>> with localconverter(robjects.default_converter + numpy2ri.converter):
dummy_y_R = robjects.conversion.py2rpy(dummy_y)
>>> dummy_y_R.typeof
<RTYPES.REALSXP: 14>
但是,一个相当微妙的转换细节是问题的根源。 dummy_y_R
具有“形状”(R 中的属性 dim
),而 caret
需要无形状的 R 数组(R 术语中的“向量”)以执行回归。可以强制 dummy_y
成为一个 R 向量:
caret_test = caret.train(**{'x': dummy_x_R,
'y': robjects.FloatVector(dummy_y),
'method': 'glmnet'})
要使用 R 方法,请确保所有输入都是 R 对象。因此,考虑将 dummy_y
numpy 数组转换为 R 向量,您可以使用 base.as_double
:
...
dummy_y_R = base.as_double(dummy_y)
caret.train(x=dummy_x_R, y=dummy_y_R, method='glmnet')