在Python中使用rpy2进行有序Logistic回归(Python的R接口):共线预测值问题

5sxhfpxr  于 2022-12-20  发布在  Python
关注(0)|答案(2)|浏览(169)

我尝试在Python中使用rpy2(Python的R语言接口)调用R的mass.polr函数来执行有序逻辑回归,但是当预测值中有一些共线或几乎共线的列时,我遇到了麻烦:polr在拟合过程中会自动丢弃其中的一些列,这会在我尝试对训练数据进行预测时导致错误。
下面是一个最小的例子:

from rpy2.robjects import r, pandas2ri
from rpy2.robjects.packages import importr

pandas2ri.activate()

mass = importr("MASS")

# dataframe with two collinear predictors (x1 and x2)
df = pd.DataFrame(columns = ['target', 'x1', 'x2', 'x3'],
                  data    = [[   0   ,  0  ,  0  ,  1  ],
                             [   1   ,  1  ,  1  ,  0  ],
                             [   2   ,  1  ,  1  ,  1  ]])

model = mass.polr('as.factor(target) ~ .', df, Hess = True) # gives warning below
'''
Warning message:
In polr(as.factor(target) ~ ., data = df, Hess = TRUE) :
  design appears to be rank-deficient, so dropping some coefs

'''

r.predict(model, df, type = "class").__array__() # gives error below
'''
Error in X %*% object$coefficients : non-conformable arguments
'''

同样的错误实际上也发生在R中,但至少可以通过查看summary(model)来查看哪些列被丢弃了。
相反,在Python中,r.summary(model).rx2('coefficients')(应该显示与R中summary(model)相同的输出)不显示系数名称,而只显示裸值:

array([[4.57292582e+01, 8.25605929e+02, 5.53887231e-02],
       [2.11604944e+01, 2.85721885e+02, 7.40597606e-02],
       [3.19476895e+01, 3.60605165e+02, 8.85946531e-02],
       [5.66312792e+01, 8.93862000e+02, 6.33557296e-02]])

有没有人知道在Python中检索系数名称的方法?或者有没有其他的变通方法?

31moq8wy

31moq8wy1#

即使没有pandas2ri.activate(),从r.summary(model).rx2('coefficients')返回的FloatMatrix也不包含变量名。但是,我们可以使用R的dimnames函数提取这些变量名。完整示例如下:

import pandas as pd
import rpy2.robjects as ro
from rpy2.robjects import r, pandas2ri
from rpy2.robjects.packages import importr
from rpy2.robjects.conversion import localconverter
mass = importr("MASS")

df = pd.DataFrame(columns = ['target', 'x1', 'x2', 'x3'],
                  data    = [[   0   ,  0  ,  0  ,  1  ],
                             [   1   ,  1  ,  1  ,  0  ],
                             [   2   ,  1  ,  1  ,  1  ]])

with localconverter(ro.default_converter + pandas2ri.converter):
    df = ro.conversion.py2rpy(df)

model = mass.polr('as.factor(target) ~ .', df, Hess = True)

coefs = r.summary(model).rx2('coefficients')

[x for x in r('dimnames')(coefs)[0]]

返回['x1', 'x3', '0|1', '1|2'],显示x2已删除。
或者,可以使用r.print(r.summary(model))打印完整模型输出

hl0ma9xz

hl0ma9xz2#

r.summary(model).rx2('coefficients')返回一个没有名称的对象,因为您在该脚本前面(第pandas2ri.activate()行)请求将R对象转换为pandas(并且隐式地转换为numpy)。Numpy数组没有命名元素。
不再建议使用activate。请考虑在上下文中使用本地转换器(例如文档中的pandashttps://rpy2.github.io/doc/v3.3.x/html/generated_rst/pandas.html)。

相关问题