#python #scikit-learn
#python #scikit-learn
Вопрос:
Я пытаюсь использовать sklearn.preprocessing.LabelBinarizer()
для создания одного горячего кодирования только меток из двух столбцов, т. Е. я хочу классифицировать только два набора объектов. В этом случае, когда я использую fit(range(0,2))
, он просто возвращает одномерный массив вместо 2×1. Это нормально, но когда я хочу использовать их в Tensorflow
, форма действительно должна быть (2,1) для согласованности размеров. Пожалуйста, посоветуйте, как я могу это решить.
Вот код:
from sklearn import preprocessing
lb = preprocessing.LabelBinarizer()
lb.fit(range(0, 3))
Вызывая lb.transform([1, 0])
, результат:
[[0 1 0]
[1 0 0]]
принимая во внимание, что когда мы меняем 3 на 2, т. е. lb.fit(range(0, 2))
, результат будет
[[1]
[0]]
вместо
[[0 1]
[1 0]]
Это создаст проблемы в алгоритмах, которые последовательно работают с массивами с n
размерами. Есть ли какой-либо способ решить эту проблему?
Комментарии:
1. Можете ли вы объяснить, какой метод вы вызываете, чтобы получить результат?
lb.fit()
ничего не возвращает,2. Извините, что не включил его. Вот код:
print(lb.transform([1, 0]))
3. Во-первых, это не проблема метода. Согласно документации:
Binary targets transform to a column vector
( scikit-learn.org/stable/modules/generated /… ) Вы можете построить нужный массив из результата colomn vector, в случае, если размерность равна 2. Я попытаюсь написать ответ, если это неясно.4. Спасибо, я бы тоже не назвал это проблемой метода, однако, на мой взгляд, лучшая реализация позволила бы разработчикам управлять типами вывода, чтобы сделать их согласованными. Как вы подчеркнули, я должен написать другой настраиваемый метод на всякий случай,
n=2
например.
Ответ №1:
labelBinarizer()
согласно документации, целью является
Бинаризуйте метки по принципу «один против всех»
В scikit-learn доступно несколько алгоритмов регрессии и двоичной классификации. Простой способ распространить эти алгоритмы на случай многоклассовой классификации — использовать так называемую схему «один против всех».
Если ваши данные содержат только два типа меток, вы можете напрямую передать их в двоичный классификатор. Следовательно, одного столбца достаточно для захвата двух классов способом «Один против остальных».
Двоичные цели преобразуются в вектор-столбец
>>> lb = preprocessing.LabelBinarizer()
>>> lb.fit_transform(['yes', 'no', 'no', 'yes'])
array([[1],
[0],
[0],
[1]])
Если вы намерены просто создать одноразовое горячее кодирование, используйте следующий метод.
from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder()
>>> enc.fit_transform([['yes'], ['no'], ['no'], ['yes']]).toarray()
array([[0., 1.],
[1., 0.],
[1., 0.],
[0., 1.]])
Надеюсь, это проясняет ваш вопрос о том, почему Sklearn labelBinarizer()
не преобразует данные 2 класса в выходные данные в два столбца.
Ответ №2:
Как уже говорилось в комментарии, это не проблема метода. Согласно документации: Двоичные цели преобразуются в вектор-столбец. Вы можете построить нужный массив из результата colomn vector, в случае, если размерность равна 2.
Прямой и простой способ сделать это:
from sklearn import preprocessing
lb = preprocessing.LabelBinarizer()
lb.fit(range(2) # range(0, 2) is the same as range(2)
a = lb.transform([1, 0])
result_2d = np.array([[item[0], 0 if item[0] else 1] for item in a])