Почему TfidVectorizer.fit_transform() меняет количество выборок и меток для моих текстовых данных?

У меня есть набор данных, который содержит 3 столбца для 310 данных. Все столбцы текстовые. Один столбец — это текст, вводимый пользователем в форму запроса, а второй столбец — это метки (одна из шести меток), которые говорят, к какой категории запросов относится ввод.

>>> data.shape
(310 x 3)

Я делаю следующую предварительную обработку своих данных, прежде чем запускать их через алгоритм KMeans из sklearn.cluster

v = TfidfVectorizer()
vectorized = v.fit_transform(data)

В настоящее время,

>>> vectorized.shape
(3,4)

Откуда я смотрю, я, кажется, потерял данные. У меня больше нет моих 310 образцов. Я считаю, что форма vectorized относится к [n_samples, n_features].

Почему меняется значение образцов и признаков? Я ожидаю, что количество выборок будет 310, а количество признаков - 6 (уникальное количество групп для моих помеченных данных.


person M Waz    schedule 21.08.2019    source источник
comment
Можете ли вы предоставить автономный пример с примерами данных? Как описано в документация, вы должны вызывать .fit_transform для итерации необработанных документов, а не для какой-то таблицы. Вы должны вызывать fit_transform только для ваших данных X, а не для меток, которые вы пытаетесь предсказать.   -  person BrenBarn    schedule 22.08.2019
comment
вы упомянули только о двух столбцах, а как насчет третьего?   -  person Venkatachalam    schedule 22.08.2019


Ответы (1)


Проблема в том, что TfidfVectorizer() нельзя применить к трем столбцам одновременно.

Согласно документация:

fit_transform(self, raw_documents, y=None)

Изучите словарный запас и idf, верните матрицу терминов-документов.

Это эквивалентно подгонке с последующим преобразованием, но реализовано более эффективно.

Параметры: raw_documents : iterable
итерируемый объект, который возвращает объекты str, unicode или file.

Возвращает: X : разреженная матрица, [n_samples, n_features]
Tf-idf-взвешенная матрица документа-термина.

Следовательно, при применении только к одному столбцу текстовых данных. В вашем коде он только что перебрал имена столбцов и создал для них преобразование.

Пример, чтобы понять, что происходит:

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer

data = pd.DataFrame({'col1':['this is first sentence','this one is the second sentence'],
                    'col2':['this is first sentence','this one is the second sentence'],
                    'col3':['this is first sentence','this one is the second sentence'] })
vec = TfidfVectorizer()
vec.fit_transform(data).todense()

# 
# matrix([[1., 0., 0.],
#         [0., 1., 0.],
#         [0., 0., 1.]])

vec.get_feature_names()

# ['col1', 'col2', 'col3']

Теперь решение состоит в том, что вам нужно объединить все три столбца в один столбец или применить векторизатор отдельно к каждому столбцу, а затем добавить их в конец.

Подход 1

data.loc[:,'full_text'] = data.apply(lambda x: ' '.join(x), axis=1)
vec = TfidfVectorizer()
X = vec.fit_transform(data['full_text']).todense()
print(X.shape)
# (2, 7)

print(vec.get_feature_names())
# ['first', 'is', 'one', 'second', 'sentence', 'the', 'this']

Подход 2

from scipy.sparse import hstack
import numpy as np

vec={}
X = []
for col in data[['col1','col2','col3']]:
    vec[col]= TfidfVectorizer()
    X = np.append(X, 
                  vec[col].fit_transform(data[col]))

stacked_X = hstack(X).todense()
stacked_X.shape
# (2, 21)

for col, v in vec.items():
    print(col)
    print(v.get_feature_names())

# col1
# ['first', 'is', 'one', 'second', 'sentence', 'the', 'this']
# col2
# ['first', 'is', 'one', 'second', 'sentence', 'the', 'this']
# col3
# ['first', 'is', 'one', 'second', 'sentence', 'the', 'this']

person Venkatachalam    schedule 22.08.2019