Одно горячее кодирование с использованием бинаризатора меток предварительной обработки sklearn

#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])