我有一个包含数字和分类功能的数据集,其中分类功能可以包含标签列表。例如:
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转换它们,然后重新粘贴数字要素。
有更优雅的方式吗?
答案 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
,因为它不太可能是一个有用的功能,很容易导致过度拟合。)