如果一个 sklearn.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
然而,由于这感觉相当笨重,总的来说,我确信有一个更好的方法。