sklearn的LabelBinarizer可以和DictVectorizer类似吗?

Noa*_*men 0 python machine-learning scikit-learn

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

RecipeId   Ingredients    TimeToPrep
1          Flour, Milk    20
2          Milk           5
3          Unobtainium    100
Run Code Online (Sandbox Code Playgroud)

如果我每个配方只有一个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()
Run Code Online (Sandbox Code Playgroud)

给出输出:

array([[   1.,    0.,    0.,    1.,   20.],
       [   0.,    1.,    0.,    2.,    5.],
       [   0.,    0.,    1.,    3.,  100.]])
Run Code Online (Sandbox Code Playgroud)

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

但是,DictVectorizer无法处理列表值功能和扼流圈

RecipeData = [{'RecipeID':1,'成分':['面粉','牛奶'],'TimeToPrep':20},{'RecipeID':2,'成分':'牛奶','TimeToPrep': 5},{'RecipeID':3,'成分':'Unobtainium','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]])
Run Code Online (Sandbox Code Playgroud)

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

有更优雅的方式吗?

Fre*_*Foo 7

LabelBinarizer 用于课堂标签,而不是功能(虽然正确的按摩它也将处理分类功能).

预期用途DictVectorizer是将数据特定函数映射到样本以提取有用的特征,该函数返回a 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'}]
Run Code Online (Sandbox Code Playgroud)

在行动:

>>> 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']
Run Code Online (Sandbox Code Playgroud)

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