проблема с sklearn MultiLabelBinarizer()

#scikit-learn #multilabel-classification

#scikit-learn #multilabel-классификация

Вопрос:

начиная с моего фрейма данных x_train, я хотел бы выделить столбец «жанры». Существует более 1000 уникальных различных жанров, но когда я использую функцию multilabelbinarizer, она сообщает только о 31 столбце, и, глядя на класс, они на самом деле не имеют смысла, если посмотреть на страницу справки, предлагается использовать не список, а массив, как я сделал здесь в примере, но все жене дает мне матрицу 36158 x 1388. Чего мне не хватает?

 x_train:

   movie_id year                   synopsis                            genres
0   30924   2005    Cruel But Necessary is the story of Betty Muns...   Drama
1   34841   2012    Yorkshire, 1974, the Maynard family moves into...   Drama Horror Thriller
2   23408   2017    When a renowned architecture scholar falls sud...   Drama
3   39470   1996    The story dealt with Lord Rama and his retalia...   Children Drama
4   7108    2003    A Thai playboy cons a girl into bed and then l...   Comedy Drama Horror Thriller
... ... ... ... ...

x_train.shape:
(36518,5)

gen = np.array(x_train['genres'])
np.unique(gen).shape
(1388,)


from sklearn.preprocessing import MultiLabelBinarizer
multilabel_binarizer = MultiLabelBinarizer()
y=multilabel_binarizer.fit_transform(gen)

y.shape:
(36518, 31)

multilabel_binarizer.classes_:
array([' ', '-', 'A', 'C', 'D', 'F', 'H', 'I', 'M', 'N', 'R', 'S', 'T',
      'W', 'X', 'a', 'c', 'd', 'e', 'h', 'i', 'l', 'm', 'n', 'o', 'r',
      's', 't', 'u', 'v', 'y'], dtype=object)
  

Комментарии:

1. Если кто-нибудь хочет попробовать, вот ссылка, это открытая записная книжка на Kaggle: kaggle.com/domizianostingi/very-easy-nlp/edit/run/43087491

Ответ №1:

Странный вывод связан с тем, что параметр fit_transform() должен быть итерируемым из итерируемых (см. Документ).

Формат вашей переменной gen должен быть изменен, чтобы разделить жанры. Разделите строки, содержащие жанры, на список строк, чтобы разделить жанры, например:

 'Drama Horror Thriller' => ['Drama', 'Horror', 'Thriller']
  

Вы можете сделать это в одной строке:

 gen = [x.split(' ') for x in list(x_train['genres'])]
gen

[['Drama'],
 ['Drama', 'Horror', 'Thriller'],
 ['Drama'],
 ['Children', 'Drama'],
 ['Comedy', 'Drama', 'Horror', 'Thriller']]
  

gen теперь имеет правильный формат для fit_transform() :

 from sklearn.preprocessing import MultiLabelBinarizer

multilabel_binarizer = MultiLabelBinarizer()
y = multilabel_binarizer.fit_transform(gen)

multilabel_binarizer.classes_
['Children' 'Comedy' 'Drama' 'Horror' 'Thriller']

y
array([[0, 0, 1, 0, 0],
       [0, 0, 1, 1, 1],
       [0, 0, 1, 0, 0],
       [1, 0, 1, 0, 0],
       [0, 1, 1, 1, 1]])
  

Комментарии:

1. Я пытаюсь использовать предложенную вами функцию, но теперь она возвращает вектор 1 длиной 1388: array([[1, 1, 1, …, 1, 1, 1]]) . Разве это не должна быть матрица размером 36158 (количество наблюдений) x 1388 (количество уникальных жанров)?

2. Хорошо, я не совсем применил это к вашей проблеме. Я отредактировал ответ

3. Не совсем, теперь он возвращает мне матрицу с 36158 x 38, я пытаюсь понять, почему, я думаю, это связано с тем, что таким образом он распознает только первый присутствующий член

4. Я думаю, у вас должно быть только 38 разных жанров. Для вас «Драма, триллер ужасов» — это 1 или 3 жанра ?

5. Я хотел бы рассмотреть «drama horror thrilelr» как единственное значение, поскольку моя цель — реализовать мультиклассовую модель (вместо мультиметки, как это могло бы быть, если «drama horror thriller» — это 3 разных класса)