1

对于回归,我通常使用 sklearn 对分类变量进行编码OneHotEncoder

我现在正在探索使用 patsy,但它似乎不提供 One-hot 编码: http: //patsy.readthedocs.io/en/latest/categorical-coding.html

是否可以使用 patsy 指定 One-hot 编码?

4

2 回答 2

5

这里有两件事可能会有所帮助:(1)patsy 默认包含一个截距(1 +每个公式的开头都有一个不可见的),以及(2)在编码分类值时,patsy 会自动选择一种编码策略,以避免创建一个过参数化的模型。

如果你结合拦截 + 全秩 one-hot 编码,那么你会得到一个过度参数化的模型。因此,patsy 切换到处理编码(= 基本上从您正在考虑的 one-hot 编码中删除一列)。这避免了在您的编码列和截距列之间创建线性相关性。

避免这种情况的一种简单方法是删除截距 - 然后 patsy 不会担心线性相关性,并且会使用您期望的那种单热编码:(y ~ -1 + a取消-1不可见1以删除截距)。

或者,如果您真的想要一个过度参数化的模型,那么如果您在链接到的文档页面上进一步向下滚动,它会告诉您如何定义任意自定义编码方案。

import numpy as np
from patsy import ContrastMatrix

class FullRankOneHot(object):
    def __init__(self, reference=0):
        self.reference = reference

    # Called to generate a full-rank encoding
    def code_with_intercept(self, levels):
        return ContrastMatrix(np.eye(len(levels)),
                              ["[My.%s]" % (level,) for level in levels])

    # Called to generate a non-full-rank encoding. But we don't care,
    # we do what we want, and return a full-rank encoding anyway.
    # Take that, patsy.
    def code_without_intercept(self, levels):
        return self.code_with_intercept(levels)

然后你可以像这样使用它:y ~ 1 + C(a, FullRankOneHot).

于 2017-10-22T03:47:25.587 回答
0

您提供的链接中的第一个示例确实是单热编码:

In [3]: data
Out[3]: {'a': ['a1', 'a2', 'a3', 'a1', 'a2', 'a3']}

In [4]: dmatrix("a", data)
Out[4]: 
DesignMatrix with shape (6, 3)
  Intercept  a[T.a2]  a[T.a3]
          1        0        0
          1        1        0
          1        0        1
          1        0        0
          1        1        0
          1        0        1
  Terms:
    'Intercept' (column 0)
    'a' (columns 1:3)

请注意,要对具有 3 个级别的分类变量进行编码,您只需要 2 个二进制变量。本文档中的编码被视为基础并为和a1添加另外两个二进制变量。如果两者都为 0,则表示值为。a2a3a2a3a1

在 sklearnOneHotEncoder或 pandas 中pd.get_dummies(),它们返回一个矩阵,其列数与分类变量的级别相同,但包含一个额外的列,因为您可以用其他列中的值表示其中一列的值。

于 2017-10-19T15:22:39.977 回答