Python 处理标签编码的未知值

Python 处理标签编码的未知值,python,pandas,scikit-learn,dummy-variable,one-hot-encoding,Python,Pandas,Scikit Learn,Dummy Variable,One Hot Encoding,如何处理sk learn中标签编码的未知值? 标签编码器只有在检测到新标签时才会爆炸 我想要的是通过一个热编码器对分类变量进行编码。但是,sk learn不支持字符串。所以我在每一列上使用了一个标签编码器 我的问题是,在我的管道交叉验证步骤中,未知标签会出现。 基本的one热编码器可以选择忽略此类情况。 aprioripandas.getDummies/cat.code是不够的,因为管道应该处理现实生活中的新传入数据,这些数据可能也包含未知的标签 是否可以为此使用计数矢量器?编辑: 使用scik

如何处理sk learn中标签编码的未知值? 标签编码器只有在检测到新标签时才会爆炸

我想要的是通过一个热编码器对分类变量进行编码。但是,sk learn不支持字符串。所以我在每一列上使用了一个标签编码器

我的问题是,在我的管道交叉验证步骤中,未知标签会出现。 基本的one热编码器可以选择忽略此类情况。 apriori
pandas.getDummies/cat.code
是不够的,因为管道应该处理现实生活中的新传入数据,这些数据可能也包含未知的标签

是否可以为此使用
计数矢量器

编辑:

使用scikit learn处理此问题的一种更简单/更好的方法是使用类
sklearn.preprocessing.OneHotEncoder

from sklearn.preprocessing import OneHotEncoder

enc = OneHotEncoder(handle_unknown='ignore')
enc.fit(train)

enc.transform(train).toarray()
旧答案:

有几个答案提到了熊猫。获取假人作为一种方法,但我觉得
labelEncoder
方法对于实现模型来说更干净。 其他类似的答案提到了使用DictVectorizer,但是再次将整个数据帧转换为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是一个比较少见的城市,它不存在于训练数据中,而是在测试集中,我们可以在推理时间考虑新的数据。 诀窍是将此值转换为“其他”,并将其包含在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完成


这个答案是基于这个,我觉得我不完全清楚,所以添加了这个例子

你有这样一个例子吗?你能捕获异常,记录它(或其他什么),然后继续吗?或者干脆忽略它们?如果预测模型作为API部署,它很可能会遇到未知的特性标签。我如何在sklearn中处理这个问题?您是否建议将错误传播到API?@GeorgHeiler,您是否尝试过查看
DictVectorizer
,它对字符串功能进行二进制热编码?但是,您需要输入字典列表。因此,选择存在分类值的子集,并执行类似于
df[cat\u cols].to\u dict(orient='records')
的操作,以创建dict列表的映射,然后将其馈送到
dictvectorier
。这些也可以包含在scikit学习估计器可以使用的管道中。@NickilMaveli我用它做了一点实验,但还没有成功。你的意思是,你的解决方案只需要内存中的一列,而我的解决方案需要内存中的所有列?Sehr你建议其他列还是空列?我认为null也是好的,因为预处理代码将在标签编码器之前处理调用它。如果
le.classes\uu
中有一个比
other
更大的值,那么
是否会对分。在左(le\u classes,'other')
中,在该元素之前插入
other
?如果是这种情况,则
other
之后元素的代码将发生更改,从而影响代码映射的完整性。在修改labelEncoder之前,请注意不要进行
le.fit_变换(train[c])
。否则,labelEncoder在列车和测试中的映射不同。相反,在修改旧答案中的labelEncoder后,执行
le.fit(train[c])
,然后执行
le.transform(train[c])
。将
le.classes=le\u classes
更改为
le.classes=np.array(le\u classes)
,以保持
预处理.labelEncoder().reverse\u变换()的有用性。