代码之家  ›  专栏  ›  技术社区  ›  Todd Shannon

在statsols类中使用分类变量

  •  1
  • Todd Shannon  · 技术社区  · 6 年前

    statsmodels

    import statsmodels.api as sm
    import pandas as pd
    import numpy as np
    
    dict = {'industry': ['mining', 'transportation', 'hospitality', 'finance', 'entertainment'],
      'debt_ratio':np.random.randn(5), 'cash_flow':np.random.randn(5) + 90} 
    
    df = pd.DataFrame.from_dict(dict)
    
    x = data[['debt_ratio', 'industry']]
    y = data['cash_flow']
    
    def reg_sm(x, y):
        x = np.array(x).T
        x = sm.add_constant(x)
        results = sm.OLS(endog = y, exog = x).fit()
        return results
    

    reg_sm(x, y)
    

    我得到以下错误:

    TypeError: '>=' not supported between instances of 'float' and 'str'
    

    我试过把 industry 变量,但我仍然得到一个错误。我别无选择。

    1 回复  |  直到 6 年前
        1
  •  7
  •   Brad Solomon    6 年前

    转换为分类数据类型的方法是正确的。但是,一旦将DataFrame转换为NumPy数组,就会得到一个 object dtype(NumPy数组作为一个整体是一个统一的类型)。这意味着个人价值观仍然是潜在的 str 回归肯定不会喜欢。

    dummify 此功能。而不是 factorizing 它将有效地将变量视为连续变量,您希望保持某种分类的外观:

    >>> import statsmodels.api as sm
    >>> import pandas as pd
    >>> import numpy as np
    >>> np.random.seed(444)
    >>> data = {
    ...     'industry': ['mining', 'transportation', 'hospitality', 'finance', 'entertainment'],
    ...    'debt_ratio':np.random.randn(5),
    ...    'cash_flow':np.random.randn(5) + 90
    ... }
    >>> data = pd.DataFrame.from_dict(data)
    >>> data = pd.concat((
    ...     data,
    ...     pd.get_dummies(data['industry'], drop_first=True)), axis=1)
    >>> # You could also use data.drop('industry', axis=1)
    >>> # in the call to pd.concat()
    >>> data
             industry  debt_ratio  cash_flow  finance  hospitality  mining  transportation
    0          mining    0.357440  88.856850        0            0       1               0
    1  transportation    0.377538  89.457560        0            0       0               1
    2     hospitality    1.382338  89.451292        0            1       0               0
    3         finance    1.175549  90.208520        1            0       0               0
    4   entertainment   -0.939276  90.212690        0            0       0               0
    

    drop_first 是为了避免 dummy trap :

    >>> y = data['cash_flow']
    >>> x = data.drop(['cash_flow', 'industry'], axis=1)
    >>> sm.OLS(y, x).fit()
    <statsmodels.regression.linear_model.RegressionResultsWrapper object at 0x115b87cf8>
    

    最后,只需要一个小指针:它有助于避免使用隐藏了内置对象类型的名称来命名引用,例如 dict

        2
  •  7
  •   Dogemore    4 年前

    我也有这个问题,有很多列需要被视为绝对的,这使它相当恼人的处理 dummify . 并转换为 string 不适合我。

    R接口提供了一种很好的方法:

    import statsmodels.formula.api as smf
    import pandas as pd
    import numpy as np
    
    dict = {'industry': ['mining', 'transportation', 'hospitality', 'finance', 'entertainment'],
      'debt_ratio':np.random.randn(5), 'cash_flow':np.random.randn(5) + 90} 
    
    df = pd.DataFrame.from_dict(dict)
    
    x = df[['debt_ratio', 'industry']]
    y = df['cash_flow']
    
    # NB. unlike sm.OLS, there is "intercept" term is included here
    smf.ols(formula="cash_flow ~ debt_ratio + C(industry)", data=df).fit()
    

    参考文献: https://www.statsmodels.org/stable/example_formulas.html#categorical-variables