在 scikit-learn 中使用 Featureunion 为 tfidf 组合两个 pandas 列
use Featureunion in scikit-learn to combine two pandas columns for tfidf
在使用 this 作为垃圾邮件分类模型时,我想添加主题和正文的附加功能。
我的所有功能都在 pandas 数据框中。例如主题为df['Subject'],正文为df['body_text'],spam/ham标签为df['ham/spam']
我收到以下错误:
类型错误:'FeatureUnion' 对象不可迭代
我怎样才能同时使用 df['Subject'] 和 df['body_text'] 作为特征,同时 运行 它们通过管道函数?
from sklearn.pipeline import FeatureUnion
features = df[['Subject', 'body_text']].values
combined_2 = FeatureUnion(list(features))
pipeline = Pipeline([
('count_vectorizer', CountVectorizer(ngram_range=(1, 2))),
('tfidf_transformer', TfidfTransformer()),
('classifier', MultinomialNB())])
pipeline.fit(combined_2, df['ham/spam'])
k_fold = KFold(n=len(df), n_folds=6)
scores = []
confusion = numpy.array([[0, 0], [0, 0]])
for train_indices, test_indices in k_fold:
train_text = combined_2.iloc[train_indices]
train_y = df.iloc[test_indices]['ham/spam'].values
test_text = combined_2.iloc[test_indices]
test_y = df.iloc[test_indices]['ham/spam'].values
pipeline.fit(train_text, train_y)
predictions = pipeline.predict(test_text)
prediction_prob = pipeline.predict_proba(test_text)
confusion += confusion_matrix(test_y, predictions)
score = f1_score(test_y, predictions, pos_label='spam')
scores.append(score)
FeatureUnion
不应该以这种方式使用。相反,它采用两个特征提取器/向量化器并将它们应用于输入。它不会按照显示的方式在构造函数中获取数据。
CountVectorizer
需要一个字符串序列。提供它的最简单方法是将字符串连接在一起。这会将两列中的文本都传递给相同的 CountVectorizer
.
combined_2 = df['Subject'] + ' ' + df['body_text']
另一种方法是 运行 CountVectorizer
和可选的 TfidfTransformer
分别在每一列上,然后堆叠结果。
import scipy.sparse as sp
subject_vectorizer = CountVectorizer(...)
subject_vectors = subject_vectorizer.fit_transform(df['Subject'])
body_vectorizer = CountVectorizer(...)
body_vectors = body_vectorizer.fit_transform(df['body_text'])
combined_2 = sp.hstack([subject_vectors, body_vectors], format='csr')
第三种选择是实现您自己的转换器,以提取数据框列。
class DataFrameColumnExtracter(TransformerMixin):
def __init__(self, column):
self.column = column
def fit(self, X, y=None):
return self
def transform(self, X, y=None):
return X[self.column]
在这种情况下,您可以在两个管道上使用 FeatureUnion
,每个管道都包含您的自定义转换器,然后 CountVectorizer
。
subj_pipe = make_pipeline(
DataFrameColumnExtracter('Subject'),
CountVectorizer()
)
body_pipe = make_pipeline(
DataFrameColumnExtracter('body_text'),
CountVectorizer()
)
feature_union = make_union(subj_pipe, body_pipe)
管道的这个特征联合将采用数据框,每个管道将处理其列。它将根据给定的两列生成词条计数矩阵的串联。
sparse_matrix_of_counts = feature_union.fit_transform(df)
这个特征联合也可以作为更大管道中的第一步添加。
在使用 this 作为垃圾邮件分类模型时,我想添加主题和正文的附加功能。
我的所有功能都在 pandas 数据框中。例如主题为df['Subject'],正文为df['body_text'],spam/ham标签为df['ham/spam']
我收到以下错误: 类型错误:'FeatureUnion' 对象不可迭代
我怎样才能同时使用 df['Subject'] 和 df['body_text'] 作为特征,同时 运行 它们通过管道函数?
from sklearn.pipeline import FeatureUnion
features = df[['Subject', 'body_text']].values
combined_2 = FeatureUnion(list(features))
pipeline = Pipeline([
('count_vectorizer', CountVectorizer(ngram_range=(1, 2))),
('tfidf_transformer', TfidfTransformer()),
('classifier', MultinomialNB())])
pipeline.fit(combined_2, df['ham/spam'])
k_fold = KFold(n=len(df), n_folds=6)
scores = []
confusion = numpy.array([[0, 0], [0, 0]])
for train_indices, test_indices in k_fold:
train_text = combined_2.iloc[train_indices]
train_y = df.iloc[test_indices]['ham/spam'].values
test_text = combined_2.iloc[test_indices]
test_y = df.iloc[test_indices]['ham/spam'].values
pipeline.fit(train_text, train_y)
predictions = pipeline.predict(test_text)
prediction_prob = pipeline.predict_proba(test_text)
confusion += confusion_matrix(test_y, predictions)
score = f1_score(test_y, predictions, pos_label='spam')
scores.append(score)
FeatureUnion
不应该以这种方式使用。相反,它采用两个特征提取器/向量化器并将它们应用于输入。它不会按照显示的方式在构造函数中获取数据。
CountVectorizer
需要一个字符串序列。提供它的最简单方法是将字符串连接在一起。这会将两列中的文本都传递给相同的 CountVectorizer
.
combined_2 = df['Subject'] + ' ' + df['body_text']
另一种方法是 运行 CountVectorizer
和可选的 TfidfTransformer
分别在每一列上,然后堆叠结果。
import scipy.sparse as sp
subject_vectorizer = CountVectorizer(...)
subject_vectors = subject_vectorizer.fit_transform(df['Subject'])
body_vectorizer = CountVectorizer(...)
body_vectors = body_vectorizer.fit_transform(df['body_text'])
combined_2 = sp.hstack([subject_vectors, body_vectors], format='csr')
第三种选择是实现您自己的转换器,以提取数据框列。
class DataFrameColumnExtracter(TransformerMixin):
def __init__(self, column):
self.column = column
def fit(self, X, y=None):
return self
def transform(self, X, y=None):
return X[self.column]
在这种情况下,您可以在两个管道上使用 FeatureUnion
,每个管道都包含您的自定义转换器,然后 CountVectorizer
。
subj_pipe = make_pipeline(
DataFrameColumnExtracter('Subject'),
CountVectorizer()
)
body_pipe = make_pipeline(
DataFrameColumnExtracter('body_text'),
CountVectorizer()
)
feature_union = make_union(subj_pipe, body_pipe)
管道的这个特征联合将采用数据框,每个管道将处理其列。它将根据给定的两列生成词条计数矩阵的串联。
sparse_matrix_of_counts = feature_union.fit_transform(df)
这个特征联合也可以作为更大管道中的第一步添加。