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转换它们,然后重新粘贴数字特征.
有更优雅的方式吗?
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它,因为它不太可能是一个有用的功能,它很容易导致过度拟合.)