我有一些pandas.Series - s,下面-我想要一个热编码。通过研究,我发现'b'级别对于我的预测建模任务并不重要。我可以这样把它排除在我的分析之外:
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
s = pd.Series(['a', 'b', 'c']).values.reshape(-1, 1)
enc = OneHotEncoder(drop=['b'], sparse=False, handle_unknown='error')
enc.fit_transform(s)
# array([[1., 0.],
# [0., 0.],
# [0., 1.]])
enc.get_feature_names()
# array(['x0_a', 'x0_c'], dtype=object)但是,当我去转换一个新的系列,一个包含'b'和一个新级别'd'的系列时,我会得到一个错误:
new_s = pd.Series(['a', 'b', 'c', 'd']).values.reshape(-1, 1)
enc.transform(new_s)文件跟踪(最近一次调用):文件"",第1行,文件"/Users/user/Documents/assets/envs/data-science/venv/lib/python3.7/site-packages/sklearn/preprocessing/_encoders.py",第390行,转换X_int,X_mask = self._transform(X,文件"/Users/user/Documents/assets/envs/data-science/venv/lib/python3.7/site-packages/sklearn/preprocessing/_encoders.py",第124行,在_transform raise (Msg)ValueError中:在转换过程中在第0列中找到未知类别'd‘
这是预料中的,因为我在上面设置了handle_unknown='error'。但是,我想完全忽略除['a', 'c']之外的所有类,无论是在拟合步骤还是随后的转换步骤中。我试过这个:
enc = OneHotEncoder(drop=['b'], sparse=False, handle_unknown='ignore')
enc.fit_transform(s)
enc.transform(new_s)文件跟踪(最近一次调用):文件"",第1行,文件"/Users/user/Documents/assets/envs/data-science/venv/lib/python3.7/site-packages/sklearn/preprocessing/_encoders.py",第371行,fit_transform self._validate_keywords()文件"/Users/user/Documents/assets/envs/data-science/venv/lib/python3.7/site-packages/sklearn/preprocessing/_encoders.py",行289,在_validate_keywords中,在指定drop参数时,drop参数为“ValueError:handle_unknown必须是‘handle_unknown’时,"handle_unknown必须是'error‘,因为这两者都会创建全部为零的类别。
似乎这种模式在科学学习中是不支持的。有谁知道一种与科学知识兼容的模式来完成这一任务吗?
发布于 2020-09-29 17:52:03
您还可以使用以下方法来处理这个问题:
class IgnorantOneHotEncoder(OneHotEncoder):
def transform(self, X, y=None):
try:
return super().transform(X)
except ValueError as e:
if 'Found unknown categories' in str(e):
X = np.copy(X)
# Keep track of indices corresponding to unknown categories
unknown_categories_mask = ~np.isin(X, self.categories_[0]).ravel()
# Overwrite the unknown categories in the input matrix, X, with the first known category
X[unknown_categories_mask] = self.categories_[0][0]
# Transform X, whose categories are all known now
X = super().transform(X)
# Overwrite originally unknown-category records with 0 to indicate
# absence of any value for any category for that feature
X[unknown_categories_mask, 0] = 0
return X
else:
raise试试看:
>>> ienc = IgnorantOneHotEncoder(sparse=False)
>>> ienc.fit(s)
IgnorantOneHotEncoder(sparse=False)
>>> ienc.transform(s)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
>>> ienc.transform(new_s)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.],
[0., 0., 0.]])发布于 2020-09-29 13:23:26
看起来sklearn.preprocessing.LabelBinarizer可以适用于这个用例,因为它没有任何参数来指定是出错还是忽略新类:
>>> import pandas as pd
>>> from sklearn.preprocessing import LabelBinarizer
>>> s = pd.Series(['a', 'b', 'c']).values.reshape(-1, 1)
>>> enc = LabelBinarizer()
>>> enc.fit_transform(s)
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
>>> enc.classes_
array(['a', 'b', 'c'], dtype='<U1')
>>> new_s = pd.Series(['a', 'b', 'c', 'd']).values.reshape(-1, 1)
>>> enc.transform(new_s)
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
[0, 0, 0]])https://stackoverflow.com/questions/60008477
复制相似问题