首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >sklearn.preprocessing.OneHotEncoder:使用drop和handle_ignore=“忽略”

sklearn.preprocessing.OneHotEncoder:使用drop和handle_ignore=“忽略”
EN

Stack Overflow用户
提问于 2020-01-31 17:15:22
回答 2查看 3K关注 0票数 6

我有一些pandas.Series - s,下面-我想要一个热编码。通过研究,我发现'b'级别对于我的预测建模任务并不重要。我可以这样把它排除在我的分析之外:

代码语言:javascript
运行
复制
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'的系列时,我会得到一个错误:

代码语言:javascript
运行
复制
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']之外的所有类,无论是在拟合步骤还是随后的转换步骤中。我试过这个:

代码语言:javascript
运行
复制
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‘,因为这两者都会创建全部为零的类别。

似乎这种模式在科学学习中是不支持的。有谁知道一种与科学知识兼容的模式来完成这一任务吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-09-29 17:52:03

您还可以使用以下方法来处理这个问题:

代码语言:javascript
运行
复制
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

试试看:

代码语言:javascript
运行
复制
>>> 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.]])
票数 1
EN

Stack Overflow用户

发布于 2020-09-29 13:23:26

看起来sklearn.preprocessing.LabelBinarizer可以适用于这个用例,因为它没有任何参数来指定是出错还是忽略新类:

代码语言:javascript
运行
复制
>>> 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]])
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60008477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档