如何在转换后获取分类数据?

时间:2016-01-22 21:38:15

标签: python pandas scikit-learn

我有一个DataFrame:

data = pd.DataFrame({
'foo': ['hi', 'no', 'please', 'no', 'yea', 'hi'], 
'bar': [1, 5, 7, 2, 4, 5], 
'zoo': ['car', 'bike', 'car', 'bus', 'bus', 'car']
})

我创建了以列名为键的字典,列/行值为值

X = data.iloc[:]
X_dicts = X.T.to_dict().values()

产生:

{'foo': 'hi', 'bar': 1, 'zoo': 'car'}
{'foo': 'no', 'bar': 5, 'zoo': 'bike'}
{'foo': 'please', 'bar': 7, 'zoo': 'car'}
{'foo': 'no', 'bar': 2, 'zoo': 'bus'}
{'foo': 'yea', 'bar': 4, 'zoo': 'bus'}
{'foo': 'hi', 'bar': 5, 'zoo': 'car'}

现在我想将每个字典转换为numpy数组,以便我可以将数组放入scikit-learn分类器中,所以我这样做了:

vec = feature_extraction.DictVectorizer()
X_vec = vec.fit_transform(X).toarray()

哪个产生了:

[[ 1.  1.  0.  0.  0.  0.  0.  1.]
 [ 5.  0.  1.  0.  0.  1.  0.  0.]
 [ 7.  0.  0.  1.  0.  0.  0.  1.]
 [ 2.  0.  1.  0.  0.  0.  1.  0.]
 [ 4.  0.  0.  0.  1.  0.  1.  0.]
 [ 5.  1.  0.  0.  0.  0.  0.  1.]]

到目前为止一切顺利。但是,当我尝试使用其.inverse_transform方法反转矢量化器时,我没有得到我预期的结果(这是我原来的字典列表)。我明白了:

[{'foo=hi': 1.0, 'bar': 1.0, 'zoo=car': 1.0}, 
 {'foo=no': 1.0, 'bar': 5.0, 'zoo=bike': 1.0}, 
 {'foo=please': 1.0, 'bar': 7.0, 'zoo=car': 1.0}, 
 {'foo=no': 1.0, 'bar': 2.0, 'zoo=bus': 1.0}, 
 {'foo=yea': 1.0, 'bar': 4.0, 'zoo=bus': 1.0}, 
 {'foo=hi': 1.0, 'bar': 5.0, 'zoo=car': 1.0}]

有人可以告诉我如何取回原来的词典列表吗? (这些 - > X_dicts = X.T.to_dict().values())。您是否也可以解释为什么尝试使用带有DictVectorizer的.inverse_transform方法获取预转换数据,并不像使用与PCA相同的方法那样简单?

1 个答案:

答案 0 :(得分:1)

the docs

  

当特征值是字符串时,此变换器将执行二进制一次性操作     (又名一个K)编码:为每个编码构造一个布尔值特征     功能可以采用的可能字符串值。例如,a     功能“f”可以采用值“火腿”和“垃圾邮件”将成为两个     输出中的功能,一个表示“f = ham”,另一个表示“f =垃圾邮件”。

所以你看到的行为完全符合预期。

要恢复原始DataFrame,您可以遍历feature_mapvec.inverse_transform返回并反转一个K编码 例如,{'foo=bar': 1.0}变为{'foo':'bar'}

import pandas as pd
import sklearn.feature_extraction as FE

data = pd.DataFrame({
    'foo': ['hi', 'no', 'please', 'no', 'yea', 'hi'], 
    'bar': [1, 5, 7, 2, 4, 5], 
    'zoo': ['car', 'bike', 'car', 'bus', 'bus', 'car']})

X_dicts = data.to_dict('records')
vec = FE.DictVectorizer(sparse=False)
X_vec = vec.fit_transform(X_dicts)

def inverse_transform(vec, X_vec):
    feature_map = vec.inverse_transform(X_vec)
    result = list()
    for dct in feature_map:
        newdct = dict()
        for k, v in dct.items():
            if '=' in k:
                k, v = k.split('=', 1)
            newdct[k] = v
        result.append(newdct)
    return result

data2 = pd.DataFrame(inverse_transform(vec, X_vec))
print(data2)

产量

   bar     foo   zoo
0    1      hi   car
1    5      no  bike
2    7  please   car
3    2      no   bus
4    4     yea   bus
5    5      hi   car