python - sklearn.preprocessing.OneHotEncoder:使用 drop 和 handle_unknown='ignore'
问题描述
我有一些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, handle_unknown=self.handle_unknown) 文件“/Users/user/Documents/assets/envs/data-science/venv/lib/python3.7/ site-packages/sklearn/preprocessing/_encoders.py",第 124 行,在 _transform 中引发 ValueError(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 中,
handle_unknown
当 drop 参数为“ValueError:handle_unknown
必须为 'error' 时,在 _validate_keywords 中”必须为 'error',因为两者都会创建全为零的类别。
scikit-learn 似乎不支持这种模式。有谁知道完成这项任务的 scikit-learn 兼容模式?
解决方案
看起来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]])
推荐阅读
- firebase - Firebase apple-app-site-association 如何添加 webcredentials
- google-drive-api - Google Drive API Search for folders
- matplotlib - Matplotlib,如何在条之间放置空间?
- javascript - javascript loop through dynamic array of elements, get values then use values as interval to set timer countdown
- reactjs - REACT 组件不返回 axios 数据
- jquery - Laravel API 和 jQuery 的问题 - 使用 response()->json 时响应为空
- java - 在其他方法内部调用其他类的方法
- ajax - 这个参数(当前)在这个 AJAX 调用中做了什么?
- azure-data-explorer - 如何在 Kusto 资源管理器中查询大型结果集?
- reactjs - 如何隐藏 API 密钥并仍然运行 heroku 应用程序?