我的管道看起来像这样:
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelBinarizer
train_animals = pd.DataFrame({'animal': ['cat', 'dog', 'dog']})
lb = LabelBinarizer()
lb.fit_transform(train_animals.animal)
生成:
array([[0],
[1],
[1]])
但是,当我在看不见的数据上应用我的管道时:
test_animals = pd.DataFrame({'animal': ['cat', 'cat', 'duck', 'fish']})
lb.transform(test_animals)
它会吐出来:
array([[1, 0],
[1, 0],
[0, 0],
[0, 0]])
打破了一切。
我需要LabelBinarizer来保持onehotencode并且永远不会生成单个列。所以:
lb = LabelBinarizer()
lb.fit_transform(train_animals.animal)
理想情况下会产生:
array([[1, 0],
[0, 1],
[0, 1]])
答案 0 :(得分:1)
我认为我已经提出了一个破解内部label_binarize
功能的解决方案,该解决方案适用于DataFrameMapper
import pandas as pd
import numpy as np
from sklearn.preprocessing import label_binarize, LabelBinarizer
from sklearn.base import TransformerMixin
from sklearn_pandas import DataFrameMapper
class SafeLabelBinarizer(TransformerMixin):
def __init__(self):
self.lb = LabelBinarizer()
def fit(self, X):
X = np.array(X)
self.lb.fit(X)
self.classes_ = self.lb.classes_
def transform(self, X):
K = np.append(self.classes_, ['__FAKE__'])
X = label_binarize(X, K, pos_label=1, neg_label=0)
X = np.delete(X, np.s_[-1], axis=1)
return X
def fit_transform(self, X):
self.fit(X)
return self.transform(X)
培训数据:
train_animals = pd.DataFrame({'animal': ['cat', 'dog', 'dog']})
mapper = DataFrameMapper([
('animal', SafeLabelBinarizer())], df_out=True)
mapper.fit_transform(train_animals)
>>>
animal_cat animal_dog
0 1 0
1 0 1
2 0 1
看不见的数据:
test_animals = pd.DataFrame({'animal': ['cat', 'cat', 'duck', 'fish']})
mapper.transform(test_animals)
>>>
animal_cat animal_dog
0 1 0
1 1 0
2 0 0
3 0 0
答案 1 :(得分:0)
它的documented here二进制数据只包含1列。
返回:Y: 形状的数组或CSR矩阵[n_samples,n_classes]。 对于二元问题,形状将为[n_samples,1]。
如果每个类别需要一列,可以尝试以下方法:
train_animals = pd.DataFrame({'animal': ['cat', 'dog', 'dog']})
pd.get_dummies(train_animals).values
array([[1, 0],
[0, 1],
[0, 1]])
但是这种方法的警告是你需要在分割成训练和测试之前转换数据。不只是火车数据。因为在测试数据上它会生成不同数量的列。
from sklearn.preprocessing import CategoricalEncoder
enc = CategoricalEncoder()
train_animals = pd.DataFrame({'animal': ['cat', 'dog', 'dog']})
enc.fit_tranform(train_animals[['animals']])
array([[1, 0],
[0, 1],
[0, 1]])
现在,CategoricalEncoder仍在开发分支中,因此可能不容易使用。
3)您可以使用LabelEncoder和OneHotEncoder的组合代替CategoricalEncoder。有关使用的更多详细信息,请参阅我的其他答案:
但对于第2点和第3点,您需要确保“动物”中的所有可能值。列出现在火车上。如果测试集包含看不见的值,则会抛出错误,因为ML模型无法对测试数据做任何事情,而且还没有看到。