sklearn的LabelBinarizer可以和DictVectorizer类似吗?

时间:2014-01-15 11:49:54

标签: python machine-learning scikit-learn

我有一个包含数字和分类功能的数据集,其中分类功能可以包含标签列表。例如:

RecipeId   Ingredients    TimeToPrep
1          Flour, Milk    20
2          Milk           5
3          Unobtainium    100

如果我每个食谱只有一个Ingeredient,DictVecorizer会优雅地将编码处理为适当的虚拟变量:

from sklearn feature_extraction import DictVectorizer
RecipeData=[{'RecipeID':1,'Ingredients':'Flour','TimeToPrep':20}, {'RecipeID':2,'Ingredients':'Milk','TimeToPrep':5}
,{'RecipeID':3,'Ingredients':'Unobtainium','TimeToPrep':100}
dc=DictVectorizer()
dc.fit_transform(RecipeData).toarray()

作为输出:

array([[   1.,    0.,    0.,    1.,   20.],
       [   0.,    1.,    0.,    2.,    5.],
       [   0.,    0.,    1.,    3.,  100.]])

在将分类标签编码为布尔特征时,可以正确处理整数要素。

但是,DictVectorizer无法处理

上的列表值功能和阻塞

RecipeData = [{'RecipeID':1,'成分':['面粉','牛奶'] ,'TimeToPrep':20},{'RecipeID':2,'成分':' 牛奶”, 'TimeToPrep':5} ,{ 'RecipeID':3 '成分': '难得素', 'TimeToPrep':100}

LabelBinarizer正确处理此问题,但必须分别提取和处理分类变量:

from sklearn.preprocessing import LabelBinarizer
lb=LabelBinarizer()
lb.fit_transform([('Flour','Milk'), ('Milk',), ('Unobtainium',)])
array([[1, 1, 0],
       [0, 1, 0],
       [0, 0, 1]])

这就是我目前的做法 - 从混合数字/分类输入数组中提取包含标签列表的分类要素,使用LabelBinarizer转换它们,然后重新粘贴数字要素。

有更优雅的方式吗?

1 个答案:

答案 0 :(得分:7)

LabelBinarizer适用于课程标签,而不是功能(虽然正确按摩它也会处理分类功能)。

DictVectorizer的用途是将数据特定函数映射到样本以提取有用的特征,该函数返回dict。因此,解决此问题的优雅方法是编写一个函数来展平您的特征序列,并使用值为True的单个特征替换列表:

>>> def flatten_ingredients(d):
...     # in-place version
...     if isinstance(d.get('Ingredients'), list):
...         for ingredient in d.pop('Ingredients'):
...             d['Ingredients=%s' % ingredient] = True
...     return d
... 
>>> RecipeData=[{'RecipeID':1,'Ingredients':['Flour','Milk'],'TimeToPrep':20}, {'RecipeID':2,'Ingredients':'Milk','TimeToPrep':5} ,{'RecipeID':3,'Ingredients':'Unobtainium','TimeToPrep':100}]
>>> map(flatten_ingredients, RecipeData)
[{'Ingredients=Milk': True, 'RecipeID': 1, 'TimeToPrep': 20, 'Ingredients=Flour': True}, {'RecipeID': 2, 'TimeToPrep': 5, 'Ingredients': 'Milk'}, {'RecipeID': 3, 'TimeToPrep': 100, 'Ingredients': 'Unobtainium'}]

行动中:

>>> from sklearn.feature_extraction import DictVectorizer
>>> dv = DictVectorizer()
>>> dv.fit_transform(flatten_ingredients(d) for d in RecipeData).toarray()
array([[   1.,    1.,    0.,    1.,   20.],
       [   0.,    1.,    0.,    2.,    5.],
       [   0.,    0.,    1.,    3.,  100.]])
>>> dv.feature_names_
['Ingredients=Flour', 'Ingredients=Milk', 'Ingredients=Unobtainium', 'RecipeID', 'TimeToPrep']

(如果我是你,我也会移除RecipeID,因为它不太可能是一个有用的功能,很容易导致过度拟合。)