ColumnTransformer с TfidfVectorizer выдает ошибку «пустой словарь» - PullRequest
0 голосов
/ 14 февраля 2019

Я провожу очень простой эксперимент с ColumnTransformer с намерением преобразовать массив столбцов, ["a"] в этом примере:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.compose import ColumnTransformer
dataset = pd.DataFrame({"a":["word gone wild","gone with wind"],"c":[1,2]})
tfidf = TfidfVectorizer(min_df=0)
clmn = ColumnTransformer([("tfidf", tfidf, ["a"])],remainder="passthrough")
clmn.fit_transform(dataset)

, что дает мне:

ValueError: empty vocabulary; perhaps the documents only contain stop words

Очевидно, что TfidfVectorizer может сделать fit_transform() самостоятельно:

tfidf.fit_transform(dataset.a)
<2x5 sparse matrix of type '<class 'numpy.float64'>'
    with 6 stored elements in Compressed Sparse Row format>

В чем может быть причина такой ошибки и как ее исправить?

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

мы можем создать собственный преобразователь tfidf, который может взять массив столбцов и затем соединить их перед применением .fit() или .transform().

Попробуйте это!

from sklearn.base import BaseEstimator,TransformerMixin

class custom_tfidf(BaseEstimator,TransformerMixin):
    def __init__(self,tfidf):
        self.tfidf = tfidf

    def fit(self, X, y=None):
        joined_X = X.apply(lambda x: ' '.join(x), axis=1)
        self.tfidf.fit(joined_X)        
        return self

    def transform(self, X):
        joined_X = X.apply(lambda x: ' '.join(x), axis=1)

        return self.tfidf.transform(joined_X)        

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.compose import ColumnTransformer
dataset = pd.DataFrame({"a":["word gone wild","word gone with wind"],
                        "b":[" gone fhgf wild","gone with wind"],
                        "c":[1,2]})
tfidf = TfidfVectorizer(min_df=0)

clmn = ColumnTransformer([("tfidf", custom_tfidf(tfidf), ['a','b'])],remainder="passthrough")
clmn.fit_transform(dataset)

#
array([[0.36439074, 0.51853403, 0.72878149, 0.        , 0.        ,
        0.25926702, 1.        ],
       [0.        , 0.438501  , 0.        , 0.61629785, 0.61629785,
        0.2192505 , 2.        ]])

PS: Может быть, вы захотите создать векторизатор tfidf для каждого столбца, а затем создать словарь с ключом в качестве имени столбца и значением в качестве подогнанного векторизатора.Этот словарь можно использовать при преобразовании соответствующих столбцов

0 голосов
/ 15 февраля 2019

Это потому, что вы предоставляете ["a"] вместо "a" в ColumnTransformer.Согласно документации:

Следует использовать скалярную строку или int, если преобразователь ожидает, что X будет 1-мерным массивом (вектором), в противном случае 2d-массив будет передан в преобразователь.

Теперь для TfidfVectorizer требуется один итератор строк для ввода (таким образом, 1-й массив строк).Но поскольку вы отправляете список имен столбцов в ColumnTransformer (даже если этот список содержит только один столбец), это будет 2-й массив, который будет передан в TfidfVectorizer.И, следовательно, ошибка.

Измените это на:

clmn = ColumnTransformer([("tfidf", tfidf, "a")],
                         remainder="passthrough")

Для большего понимания попробуйте использовать перечисленные выше вещи для выбора данных в панде DataFrame.Проверьте формат (dtype, shape) возвращаемых данных, когда вы делаете:

dataset['a']

vs 

dataset[['a']]

Обновление : @SergeyBushmanov, Что касается вашего комментария к другому ответу, я думаю, что вы неправильно интерпретируетедокументация.Если вы хотите выполнить tfidf для двух столбцов, вам нужно передать два преобразователя.Примерно так:

tfidf_1 = TfidfVectorizer(min_df=0)
tfidf_2 = TfidfVectorizer(min_df=0)
clmn = ColumnTransformer([("tfidf_1", tfidf_1, "a"), 
                          ("tfidf_2", tfidf_2, "b")
                         ],
                         remainder="passthrough")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...