【问题标题】:How can an interaction design matrix be created from categorical variables?如何从分类变量创建交互设计矩阵?
【发布时间】:2014-06-23 05:35:19
【问题描述】:

我主要从事 R 领域的统计建模/机器学习工作,并希望提高我的 Python 技能。我想知道在 python 中创建分类交互(任意程度)的设计矩阵的最佳方法。

一个玩具例子:

import pandas as pd
from urllib import urlopen
page = urlopen("http://www.shatterline.com/MachineLearning/data/tennis_anyone.csv")
df = pd.read_csv(page)
df.head(n=5)

假设我们要在 Outlook、Temp 和 Humidity 之间创建交互。有没有一种有效的方法来做到这一点?我可以在熊猫中手动做这样的事情:

OutTempFact=pd.Series(pd.factorize(pd.lib.fast_zip([df.Outlook.values, df.Temperature.values]))[0],name='OutTemp')
OutHumFact=pd.Series(pd.factorize(pd.lib.fast_zip([df.Outlook.values, df.Humidity.values]))[0],name='OutHum')
TempHumFact=pd.Series(pd.factorize(pd.lib.fast_zip([df.Temperature.values, df.Humidity.values]))[0],name='TempHum')

IntFacts=pd.concat([OutTempFact,OutHumFact,TempHumFact],axis=1)
IntFacts.head(n=5)

然后我可以将其传递给 scikit-learn one-hot 编码器,但可能有一种更好、更少手动的方法来创建分类变量之间的交互,而无需逐步完成每个组合。

import sklearn as sk
enc = sk.preprocessing.OneHotEncoder()
IntFacts_OH=enc.fit_transform(IntFacts)
IntFacts_OH.todense()

【问题讨论】:

    标签: python pandas scikit-learn


    【解决方案1】:

    如果在设计矩阵上使用OneHotEncoder获取单热门设计矩阵,则互动不仅仅是列之间的乘法。如果X_1hot是您的单热门设计矩阵,样本是线条的,那么对于2nd订单交互,您可以写入

    X_2nd_order = (X_1hot[:, np.newaxis, :] * X_1hot[:, :, np.newaxis]).reshape(len(X_1hot), -1)
    

    将有重复的交互,它也将包含原始功能。

    将任意顺序将使您的设计矩阵爆炸。如果你真的想这样做,那么你应该用多项式内核调查内链,这将让您轻松地转到任意度。

    使用您呈现的数据框,我们可以按如下方式进行。首先,使用数据帧构建单热门设计的手动方法:

    import numpy as np
    indicators = []
    state_names = []
    for column_name in df.columns:
        column = df[column_name].values
        one_hot = (column[:, np.newaxis] == np.unique(column)).astype(float)
        indicators.append(one_hot)
        state_names = state_names + ["%s__%s" % (column_name, state) for state in np.unique(column)]
    
    X_1hot = np.hstack(indicators)
    

    列名在state_names和指示符矩阵中存储为X_1hot。然后我们计算二阶功能

    X_2nd_order = (X_1hot[:, np.newaxis, :] * X_1hot[:, :, np.newaxis]).reshape(len(X_1hot), -1)
    

    为了了解二阶矩阵列的名称,我们将它们建立如此

    from itertools import product
    one_hot_interaction_names = ["%s___%s" % (column1, column2) 
                                 for column1, column2 in product(state_names, state_names)]
    

    【讨论】:

    • 当我在我的玩具示例上运行时...我发现一些矢量有“3.”。这些是标记重复的人吗?您能否向新手扩展一下这段代码正在进行的新手? span>
    • 这很奇怪。我正在引用的单热编码基本上将设计矩阵转向每个类别状态的指示器函数,即 Outlook i>将成为三列 Outlooksunny i>, Outlookovercast 我>, Outloktrain i>。设计矩阵的每一行都将包含1 inspolite之一,而另外两个列中的0。您对其他类别进行了同样的事情,最终以宽@ 98765433和几个1 s的宽矩阵。我在答案中写的操作需要设计矩阵的每一行,并用自己计算外部产品。 span>
    • 外部产品在这种情况下是该样本的所有功能条目的所有可能产品的矩阵。由于样品线只能在@ 987654333和1,外部产品结果只能是矩阵,@ 987654336和1内容。 Rehape操作将交互矩阵丧失到长向量中,因此整个操作创建了一个增强的单热设计矩阵,其中指标是对类别状态的。由于每个状态对在矩阵中都是双倍表示的,因此它将在颠簸向量中倍增。 span>
    • 您可以复制和粘贴更新的示例。 X_1hot包含所有州的指示器,X_2nd_order包含所有交互的指示灯。交互的名称在one_hot_interaction_names。如果这实际上是您打算获得的内容,请告诉我:) span>
    • 谢谢!我需要研究这一点以了解它。我请注意,如果在X_2ND_ORDER函数中使用intfacts_oh.todense(),则使用3个结果的奇数结果。 span>
    【解决方案2】:

    现在面临着一个类似的问题,即想要一种简单的方法来集成来自文献中的基线 OLS 模型的特定交互以与 ML 方法进行比较,我遇到了 patsy (http://patsy.readthedocs.io/en/latest/overview.html) 和这个 scikit-learn 集成 patsylearn (https://github.com/amueller/patsylearn)。

    下面,如何将交互变量传递给模型:

    from patsylearn import PatsyModel
    model = PatsyModel(sk.linear_model.LinearRegression(), "Play-Tennis ~ C(Outlook):C(Temperature) + C(Outlook):C(Humidity) + C(Outlook):C(Wind)")
    

    请注意,在这个公式中,您不需要 OneHotEncoder(),因为公式中的 C 告诉 Patsy 解释器这些是分类变量,它们是为您单独编码的!但请在他们的文档 (http://patsy.readthedocs.io/en/latest/categorical-coding.html) 中阅读更多相关信息。

    或者,您也可以使用我更喜欢的 PatsyTransformer,因为它可以轻松集成到 scikit-learn 管道中:

    from patsylearn import PatsyTransformer
    transformer = PatsyTransformer("C(Outlook):C(Temperature) + C(Outlook):C(Humidity) + C(Outlook):C(Wind)")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-04
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多