【问题标题】:Python - Feature hashing on list of dictionaries with lists of stringsPython - 具有字符串列表的字典列表上的特征散列
【发布时间】:2017-05-09 11:42:49
【问题描述】:

我希望能够获取一个字典(记录)列表,其中一些列具有一个值列表作为单元格的值。这是一个例子

[{'fruit': 'apple', 'age': 27}, {'fruit':['apple', 'banana'], 'age': 32}]

如何获取此输入并对其执行特征哈希(在我的数据集中,我有数千列)。目前我正在使用一种热编码,但这似乎消耗了大量内存(比我系统上的内存还多)。

我尝试按上述方式获取我的数据集,但出现错误:

x__ = h.transform(data)

Traceback (most recent call last):

  File "<ipython-input-14-db4adc5ec623>", line 1, in <module>
    x__ = h.transform(data)

  File "/usr/local/lib/python2.7/dist-packages/sklearn/feature_extraction/hashing.py", line 142, in transform
    _hashing.transform(raw_X, self.n_features, self.dtype)

  File "sklearn/feature_extraction/_hashing.pyx", line 52, in sklearn.feature_extraction._hashing.transform (sklearn/feature_extraction/_hashing.c:2103)

TypeError: a float is required

我还尝试将其转换为数据帧并将其传递给哈希器:

x__ = h.transform(x_y_dataframe)

Traceback (most recent call last):

  File "<ipython-input-15-109e7f8018f3>", line 1, in <module>
    x__ = h.transform(x_y_dataframe)

  File "/usr/local/lib/python2.7/dist-packages/sklearn/feature_extraction/hashing.py", line 142, in transform
    _hashing.transform(raw_X, self.n_features, self.dtype)

  File "sklearn/feature_extraction/_hashing.pyx", line 46, in sklearn.feature_extraction._hashing.transform (sklearn/feature_extraction/_hashing.c:1928)

  File "/usr/local/lib/python2.7/dist-packages/sklearn/feature_extraction/hashing.py", line 138, in <genexpr>
    raw_X = (_iteritems(d) for d in raw_X)

  File "/usr/local/lib/python2.7/dist-packages/sklearn/feature_extraction/hashing.py", line 15, in _iteritems
    return d.iteritems() if hasattr(d, "iteritems") else d.items()

AttributeError: 'unicode' object has no attribute 'items'

知道如何使用 pandas 或 sklearn 实现这一点吗?或者也许我可以一次构建我的虚拟变量几千行?

这是我如何使用 pandas 获取我的虚拟变量:

def one_hot_encode(categorical_labels):
    res = []
    tmp = None
    for col in categorical_labels:
        v = x[col].astype(str).str.strip('[]').str.get_dummies(', ')#cant set a prefix
        if len(res) == 2:
            tmp = pandas.concat(res, axis=1)
            del res
            res = []
            res.append(tmp)
            del tmp
            tmp = None
        else:
            res.append(v)
    result = pandas.concat(res, axis=1)
    return result

【问题讨论】:

  • 您可以将列表转换为可散列的元组。

标签: python pandas scikit-learn feature-engineering


【解决方案1】:

考虑以下方法:

from sklearn.feature_extraction.text import CountVectorizer

lst = [{'fruit': 'apple', 'age': 27}, {'fruit':['apple', 'banana'], 'age': 32}]

df = pd.DataFrame(lst)

vect = CountVectorizer()

X = vect.fit_transform(df.fruit.map(lambda x: ' '.join(x) if isinstance(x, list) else x))

r = pd.DataFrame(X.A, columns=vect.get_feature_names(), index=df.index)

df.join(r)

结果:

In [66]: r
Out[66]:
   apple  banana
0      1       0
1      1       1

In [67]: df.join(r)
Out[67]:
   age            fruit  apple  banana
0   27            apple      1       0
1   32  [apple, banana]      1       1

更新:从 Pandas 0.20.1 开始,我们可以直接从稀疏矩阵创建 SparseDataFrame:

In [13]: r = pd.SparseDataFrame(X, columns=vect.get_feature_names(), index=df.index, default_fill_value=0)

In [14]: r
Out[14]:
   apple  banana
0      1       0
1      1       1

In [15]: r.memory_usage()
Out[15]:
Index     80   
apple     16   # 2 * 8 byte (np.int64)
banana     8   # 1 * 8 byte (as there is only one `1` value)
dtype: int64

In [16]: r.dtypes
Out[16]:
apple     int64
banana    int64
dtype: object

【讨论】:

  • 这确实有效,虽然我似乎内存不足(32 gb)我猜有很多列。我还注意到,当我将 df 分开时,这样我就可以在集合中进行操作,它给了我很多 nans(即使我提前从我的数据框中删除了所有 nans)
  • 我意识到我得到 na 的原因是因为我在没有将轴设置为 1 的情况下进行连接
  • @Kevin,在 Pandas 0.20.1 中,您可以直接从稀疏矩阵(CountVectorizer 的结果)创建 SparseDataFrame。请检查我的更新答案
  • 它实际上适用于字段中的数字,只需执行 astype(str)。谢谢!
  • @Kevin,很高兴它有帮助:)
猜你喜欢
  • 2018-07-01
  • 2021-01-29
  • 1970-01-01
  • 2021-03-17
  • 2011-12-25
  • 1970-01-01
  • 2012-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多