我很难使用statsmodels.formula.api函数
ols(formula,data).fit().rsquared_adj
因为我的预测者名字的性质。
预测器里有数字和空格等,显然不喜欢。
我知道我需要用patsy.builtins.q之类的东西
所以假设我的预测值是体重,单位是千克,应该输入如下:
Q("weight.in.kg")
所以我需要从一个列表中提取我的公式,用这个patsy.builtin.Q修改列表中的每一项都会遇到困难
formula = "{} ~ {} + 1".format(response, ' + '.join([candidate])
[候选人]是我的预测者名单。
亲爱的python专家,我想问你的问题是,我究竟如何将列表中的每一项[候选项]都放在下面表达式中的引号内:
Q('')
所以ols函数可以真正读取它?
抱歉,如果这是非常明显的,我不擅长python。
最佳答案
现在,您要从公式中需要的术语列表开始,然后尝试将它们粘贴到一个复杂的字符串中,patsy将解析并转换回术语列表。您可以看到patsy为此类公式生成的数据结构(ModelDesc.from_formula
是patsy的解析器):
In [7]: from patsy import ModelDesc
In [8]: ModelDesc.from_formula("y ~ x1 + x2 + x3")
Out[8]:
ModelDesc(lhs_termlist=[Term([EvalFactor('y')])],
rhs_termlist=[Term([]),
Term([EvalFactor('x1')]),
Term([EvalFactor('x2')]),
Term([EvalFactor('x3')])])
这看起来可能有点吓人,但它非常简单--您有一个表示单个公式的
ModelDesc
,它有一个左侧的术语列表和一个右侧的术语列表。每个术语都由Term
对象表示,每个Term
都有一个因子列表(这里每个术语只有一个因素——如果你有任何交互作用,那么这些术语将有多个因素。)此外,“空交互作用”Term([])
是patsy如何表示截距术语的。因此,您可以通过直接创建所需的术语并将它们传递给patsy,跳过字符串解析步骤来避免所有这些复杂的引用/解析工作。
from patsy import ModelDesc, Term, LookupFactor
response_terms = [Term([LookupFactor(response)])]
# start with intercept...
model_terms = [Term([])]
# ...then add another term for each candidate
model_terms += [Term([LookupFactor(c)]) for c in candidates]
model_desc = ModelDesc(response_terms, model_terms)
现在您可以将
model_desc
对象传递到通常传递patsy公式的任何函数中:ols(model_desc, data).fit().rsquared_adj
这里还有另一个技巧:您会注意到第一个示例有
EvalFactor
对象,现在我们使用LookupFactor
对象。不同的是,EvalFactor
需要一个任意的python代码字符串,如果您想编写类似于np.log(x1)
的代码,这是很好的,但是如果您有类似于weight.in.kg
的名称的变量,则非常烦人。LookupFactor
直接获取要在数据中查找的变量的名称,因此不需要进一步引用。或者,您可以使用一些更奇特的python字符串处理来完成此操作,例如:
quoted = ["Q('{}')".format(c) for c in candidates]
formula = "{} ~ {} + 1".format(response, ' + '.join(quoted))
但是,虽然这一点开始比较简单,但它要脆弱得多——例如,考虑(或尝试)如果您的一个参数包含引号字符会发生什么!你不应该在处理管道中写这样的东西,因为候选名字来自其他你无法控制的地方(例如,一个随机的CSV文件),你可以得到各种各样的任意代码执行上述解决方案避免了所有这些问题。
参考:
https://patsy.readthedocs.io/en/latest/expert-model-specification.html
https://patsy.readthedocs.io/en/latest/formulas.html
关于python - 对包含数字/空格的参数使用ols函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38149482/