Примените CountVectorizer к столбцу со списком слов в строках в Python

Я сделал часть предварительной обработки для анализа текста и после удаления стоп-слов и основ следующим образом:

test[col] = test[col].apply(
    lambda x: [ps.stem(item) for item in re.findall(r"[\w']+", x) if ps.stem(item) not in stop_words])

train[col] = train[col].apply(
    lambda x: [ps.stem(item) for item in re.findall(r"[\w']+", x) if ps.stem(item) not in stop_words])

У меня есть столбец со списком "очищенных слов". Вот 3 строки в столбце:

['size']
['pcs', 'new', 'x', 'kraft', 'bubble', 'mailers', 'lined', 'bubble', 'wrap', 'protection', 'self', 'sealing', 'peelandseal', 'adhesive', 'keeps', 'contents', 'secure', 'tamper', 'proof', 'durable', 'lightweight', 'kraft', 'material', 'helps', 'save', 'postage', 'approved', 'ups', 'fedex', 'usps']
['brand', 'new', 'coach', 'bag', 'bought', 'rm', 'coach', 'outlet']

Теперь я хочу применить CountVectorizer к этому столбцу:

from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(max_features=1500, analyzer='word', lowercase=False) # will leave only 1500 words
X_train = cv.fit_transform(train[col])

Но я получил ошибку:

TypeError: expected string or bytes-like object

Было бы немного странно создавать строку из списка, а затем снова разделять ее с помощью CountVectorizer.


person Yury Wallet    schedule 08.12.2017    source источник
comment
Из вашего кода и обсуждения неясно, используете ли вы pandas для обработки столбцов (и строк), но если нет, я рекомендую это. Особенно, когда вы говорите 'У меня есть столбец со списком вычищенных слов', но не показываете столбец кадра данных pandas, а только список Python (из списка).   -  person smci    schedule 18.12.2019


Ответы (4)


Чтобы применить CountVectorizer к списку слов, вы должны отключить анализатор.

x=[['ab','cd'], ['ab','de']]
vectorizer = CountVectorizer(analyzer=lambda x: x)
vectorizer.fit_transform(x).toarray()

Out:
array([[1, 1, 0],
       [1, 0, 1]], dtype=int64)
person Aleksandr Gavrilov    schedule 12.09.2020

Поскольку другого способа избежать ошибки я не нашел, я объединил списки в колонке

train[col]=train[col].apply(lambda x: " ".join(x) )
test[col]=test[col].apply(lambda x: " ".join(x) )

Только после этого я начал получать результат

X_train = cv.fit_transform(train[col])
X_train=pd.DataFrame(X_train.toarray(), columns=cv.get_feature_names())
person Yury Wallet    schedule 08.12.2017

Когда вы используете fit_transform, передаваемые параметры должны быть итерируемыми строками или объектами, подобными байтам. Похоже, вы должны применить это вместо своего столбца.

X_train = train[col].apply(lambda x: cv.fit_transform(x))

Вы можете прочитать документацию для fit_transform здесь.

person Justin    schedule 08.12.2017
comment
к сожалению, выдает ошибку ValueError: пустой словарный запас; возможно, документы содержат только стоп-слова - person Yury Wallet; 08.12.2017
comment
Возможно ли, что некоторые из ваших строк содержат пустые очищенные слова? - person Justin; 08.12.2017
comment
Разве вы не получаете просто строку со всеми 0 для этого случая? - person Yury Wallet; 08.12.2017

Ваш ввод должен быть списком строк или байтов, в этом случае вы, кажется, предоставляете список списка.

Похоже, вы уже токенизировали свою строку в токены внутри отдельных списков. Что вы можете сделать, это взломать, как показано ниже:

inp = [['size']
['pcs', 'new', 'x', 'kraft', 'bubble', 'mailers', 'lined', 'bubble', 'wrap', 
'protection', 'self', 'sealing', 'peelandseal', 'adhesive', 'keeps', 
'contents', 'secure', 'tamper', 'proof', 'durable', 'lightweight', 'kraft', 
'material', 'helps', 'save', 'postage', 'approved', 'ups', 'fedex', 'usps']]
['brand', 'new', 'coach', 'bag', 'bought', 'rm', 'coach', 'outlet']


inp = ["<some_space>".join(x) for x in inp]

vectorizer = CountVectorizer(tokenizer = lambda x: x.split("<some_space>"), analyzer="word")

vectorizer.fit_transform(inp)
person Kerem T    schedule 28.11.2018