У меня есть список списков, которые содержат классификационные метки для определенного домена. Пример:
data = [
['polmone', 'linfonodi'],
['osso'],
['polmone'],
['linfonodi', 'osso', 'polmone'],
['peritoneo', 'osso'],
['fegato'],
['polmone', 'linfonodi'],
['osso'],
['osso', 'fegato'],
]
Список содержит 331 список, и каждый из них может содержать одну или все возможные метки. Число возможных меток равно 20.
Мне нужно передать список списков меток в sklearn.neighbors.KNeighborsClassifier
, и я думал о преобразовании каждой возможной метки в число (например, 0-19).
Мне было интересно узнать о наиболее эффективном способе выполнения этого преобразования.
Полагаю, что «глупым» может быть способ создания словаря с каждой уникальной меткой и соответствующим значением, как в:
{'polmone': 0, 'linfonodi': 1, ..., 'label_19': 19}
... а затем переберите каждый элемент списка и выполните str.replace()
.
Я считаю, что должно быть более эффективное решение. Вы что-нибудь посоветуете?
Заранее спасибо.
PS Я искал похожую тему, но не смог ее найти. Если я по ошибке не заметил этого, не стесняйтесь закрыть эту ветку и отправить меня в ад.
Редактировать:
Прежде всего, я хотел бы поблагодарить всех за их ответы, так как каждый из них пришел, чтобы помочь по различным вопросам, с которыми я столкнулсяи я столкнусь.
Теперь я хочу поделиться другим решением, которое я только что нашел, когда имел дело с KNeighborClassifier
и целью с несколькими выходами. Подавая закодированные метки (как строки или целые числа, так и простые списки или массивы), я получил следующую ошибку:
Traceback (most recent call last):
File "embedding_gensim.py", line 111, in <module>
neigh.fit(doc_train, labls_train)
File "/home/matteo/anaconda3/envs/deep_l/lib/python3.7/site-packages/sklearn/neighbors/base.py", line 906, in fit
check_classification_targets(y)
File "/home/matteo/anaconda3/envs/deep_l/lib/python3.7/site-packages/sklearn/utils/multiclass.py", line 169, in check_classification_targets
raise ValueError("Unknown label type: %r" % y_type)
ValueError: Unknown label type: 'unknown'
Я обнаружил, что MultiLabelBinarizer
решает проблему подачиклассификатор со списком списков с несколькими метками (или массивами).
Итак, следуя решению @Assander Rossa:
binarized_labels = MultiLabelBinarizer().fit_transform(encoded_labels_list)
binarized_labels тогда выглядит так:
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0]
...
MultiLabelBinarizer()
фактически работает непосредственно со списками строк вsplit_labels
. Возможно, я решаю проблему с неправильной точки зрения.