处理标签编码的未知值
Handling unknown values for label encoding
我如何处理 sk-learn 中标签编码的未知值?
标签编码器只会在检测到新标签时出现异常。
我想要的是通过one-hot编码器对分类变量进行编码。但是,sk-learn 不支持字符串。所以我在每一列上都使用了一个标签编码器。
我的问题是在我的管道交叉验证步骤中出现了未知标签。
基本的单热编码器可以选择忽略这种情况。
先验 pandas.getDummies /cat.codes
是不够的,因为管道应该处理现实生活中的新鲜传入数据,这些数据也可能包含未知标签。
是否可以为此目的使用 CountVectorizer
?
编辑:
最近 simpler/better 使用 scikit-learn 处理这个问题的方法是使用 class sklearn.preprocessing.OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(handle_unknown='ignore')
enc.fit(train)
enc.transform(train).toarray()
旧答案:
有几个答案提到 pandas.get_dummies
作为一种方法,但我觉得 labelEncoder
方法对于实现模型来说更清晰。
其他类似的答案提到为此使用 DictVectorizer
,但再次将整个 DataFrame
转换为 dict 可能不是一个好主意。
让我们假设以下有问题的列:
from sklearn import preprocessing
import numpy as np
import pandas as pd
train = {'city': ['Buenos Aires', 'New York', 'Istambul', 'Buenos Aires', 'Paris', 'Paris'],
'letters': ['a', 'b', 'c', 'd', 'a', 'b']}
train = pd.DataFrame(train)
test = {'city': ['Buenos Aires', 'New York', 'Istambul', 'Buenos Aires', 'Paris', 'Utila'],
'letters': ['a', 'b', 'c', 'a', 'b', 'b']}
test = pd.DataFrame(test)
Utila 是一个比较罕见的城市,它不存在于训练数据中,而是存在于测试集中,我们可以在推理时考虑新数据。
诀窍是将此值转换为 "other" 并将其包含在 labelEncoder 对象中。然后我们可以在生产中重用它。
c = 'city'
le = preprocessing.LabelEncoder()
train[c] = le.fit_transform(train[c])
test[c] = test[c].map(lambda s: 'other' if s not in le.classes_ else s)
le_classes = le.classes_.tolist()
bisect.insort_left(le_classes, 'other')
le.classes_ = le_classes
test[c] = le.transform(test[c])
test
city letters
0 1 a
1 3 b
2 2 c
3 1 a
4 4 b
5 0 b
要将其应用于新数据,我们只需要为每一列保存一个 le
对象,这可以使用 Pickle 轻松完成。
这个答案是基于这个 question 我觉得我不太清楚,因此添加了这个例子。
我如何处理 sk-learn 中标签编码的未知值? 标签编码器只会在检测到新标签时出现异常。
我想要的是通过one-hot编码器对分类变量进行编码。但是,sk-learn 不支持字符串。所以我在每一列上都使用了一个标签编码器。
我的问题是在我的管道交叉验证步骤中出现了未知标签。
基本的单热编码器可以选择忽略这种情况。
先验 pandas.getDummies /cat.codes
是不够的,因为管道应该处理现实生活中的新鲜传入数据,这些数据也可能包含未知标签。
是否可以为此目的使用 CountVectorizer
?
编辑:
最近 simpler/better 使用 scikit-learn 处理这个问题的方法是使用 class sklearn.preprocessing.OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(handle_unknown='ignore')
enc.fit(train)
enc.transform(train).toarray()
旧答案:
有几个答案提到 pandas.get_dummies
作为一种方法,但我觉得 labelEncoder
方法对于实现模型来说更清晰。
其他类似的答案提到为此使用 DictVectorizer
,但再次将整个 DataFrame
转换为 dict 可能不是一个好主意。
让我们假设以下有问题的列:
from sklearn import preprocessing
import numpy as np
import pandas as pd
train = {'city': ['Buenos Aires', 'New York', 'Istambul', 'Buenos Aires', 'Paris', 'Paris'],
'letters': ['a', 'b', 'c', 'd', 'a', 'b']}
train = pd.DataFrame(train)
test = {'city': ['Buenos Aires', 'New York', 'Istambul', 'Buenos Aires', 'Paris', 'Utila'],
'letters': ['a', 'b', 'c', 'a', 'b', 'b']}
test = pd.DataFrame(test)
Utila 是一个比较罕见的城市,它不存在于训练数据中,而是存在于测试集中,我们可以在推理时考虑新数据。
诀窍是将此值转换为 "other" 并将其包含在 labelEncoder 对象中。然后我们可以在生产中重用它。
c = 'city'
le = preprocessing.LabelEncoder()
train[c] = le.fit_transform(train[c])
test[c] = test[c].map(lambda s: 'other' if s not in le.classes_ else s)
le_classes = le.classes_.tolist()
bisect.insort_left(le_classes, 'other')
le.classes_ = le_classes
test[c] = le.transform(test[c])
test
city letters
0 1 a
1 3 b
2 2 c
3 1 a
4 4 b
5 0 b
要将其应用于新数据,我们只需要为每一列保存一个 le
对象,这可以使用 Pickle 轻松完成。
这个答案是基于这个 question 我觉得我不太清楚,因此添加了这个例子。