如果将asklearn.LabelEncoder
拟合到训练集上,则在测试集上使用时如果遇到新的值,它可能会损坏。
为此我唯一能想到的解决方案是将测试集中的所有新内容(即不属于任何现有类)映射到"<unknown>"
,然后在其后显式添加一个相应的类LabelEncoder
:
# train and test are pandas.DataFrame's and c is whatever column
le = LabelEncoder()
le.fit(train[c])
test[c] = test[c].map(lambda s: '<unknown>' if s not in le.classes_ else s)
le.classes_ = np.append(le.classes_, '<unknown>')
train[c] = le.transform(train[c])
test[c] = le.transform(test[c])
这可行,但是有更好的解决方案吗?
更新资料
正如@sapo_cosmico在评论中指出的那样,鉴于我假设是中的实现更改LabelEncoder.transform
,现在上述似乎不再起作用了,该更改现在似乎正在使用np.searchsorted
(我不知道以前是否是这种情况)。因此,无需将<unknown>
类追加到LabelEncoder
已经提取的类的列表中,而需要按排序顺序将其插入:
import bisect
le_classes = le.classes_.tolist()
bisect.insort_left(le_classes, '<unknown>')
le.classes_ = le_classes
但是,由于总体而言这感觉很笨拙,因此我敢肯定有更好的方法。