我正在使用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>
这种错误的原因可能是什么,以及如何纠正该错误?
答案 0 :(得分:1)
那是因为您要提供["a"]
中的"a"
而不是ColumnTransformer
。根据文档:
如果转换器期望X为一维数组(矢量),则应使用标量字符串或整数,否则会将二维数组传递给转换器。
现在,TfidfVectorizer
需要使用单个字符串迭代器进行输入(因此是一维字符串数组)。但是由于您正在发送ColumnTransformer
中的列名列表(即使该列表仅包含单个列),所以它将是二维数组,并将传递给TfidfVectorizer
。因此是错误。
将其更改为:
clmn = ColumnTransformer([("tfidf", tfidf, "a")],
remainder="passthrough")
为进一步了解,请尝试使用以上内容从pandas DataFrame中选择数据。在执行以下操作时,请检查返回数据的格式(dtype,形状):
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")
答案 1 :(得分:0)
我们可以创建一个自定义的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. ]])
P.S。 :可能是您可能想为每列创建一个tfidf矢量化器,然后创建一个字典,键为列名,值作为拟合的矢量化器。该字典可用于相应列的转换