我有一个DataFrame,如:
text_data worker_dicts outcomes
0 "Some string" {"Sector":"Finance", 0
"State: NJ"}
1 "Another string" {"Sector":"Programming", 1
"State: NY"}
它既包含文本信息,也包含字典列。 (真实worker_dicts
还有更多字段)。我对二进制结果列很感兴趣。
我最初尝试做的是将text_data
和worker_dict
结合起来,粗略地连接两列,然后运行Multinomial NB:
df['stacked_features']=df['text_data'].astype(str)+'_'+df['worker_dicts']
stacked_features = np.array(df['stacked_features'])
outcomes = np.array(df['outcomes'])
text_clf = Pipeline([('vect', TfidfVectorizer(stop_words='english'), ngram_range = (1,3)),
('clf', MultinomialNB())])
text_clf = text_clf.fit(stacked_features, outcomes)
但是我的准确性非常差,而且我认为拟合两个独立模型比使用一个模型在两种类型的特征上更好地使用数据(就像我在堆叠时那样)。
我如何使用功能联盟? worker_dicts
有点奇怪,因为它是一本字典,所以我对如何解析它感到非常困惑。
答案 0 :(得分:1)
如果您的字典条目与您的示例中的字典条目类似,那么我会在进行其他处理之前从字典条目中创建不同的列。
new_features = pd.DataFrame(df['worker_dicts'].values.tolist())
然后new_features
将是其自己的数据框,其中包含Sector
和State
列,除了TFIDF或其他功能提取之外,您还可以根据需要对其进行热编码。{{1} }列。为了在管道中使用它,你需要创建一个新的转换器类,所以我可能建议单独应用字典解析和TFIDF,然后堆叠结果,并将OneHotEncoding添加到管道中允许您指定要应用变换器的列。 (由于您要编码的类别是字符串,您可能希望使用LabelBinarizer类而不是OneHotEncoder类进行编码转换。)
如果您想在管道上单独对所有列使用TFIDF,则需要使用嵌套的Pipeline和FeatureUnion设置来提取here所述的列。
如果您在数据帧X1和X2中拥有一个热编码功能(如下所述)和X3中的文本功能,则可以执行以下操作来创建管道。 (还有很多其他选择,这只是一种方式)
text_data
(MultinomialNB不会在管道中工作,因为它没有X = pd.concat([X1, X2, X3], axis=1)
def select_text_data(X):
return X['text_data']
def select_remaining_data(X):
return X.drop('text_data', axis=1)
# pipeline to get all tfidf and word count for first column
text_pipeline = Pipeline([
('column_selection', FunctionTransformer(select_text_data, validate=False)),
('tfidf', TfidfVectorizer())
])
final_pipeline = Pipeline([('feature-union', FeatureUnion([('text-features', text_pipeline),
('other-features', FunctionTransformer(select_remaining_data))
])),
('clf', LogisticRegression())
])
和fit
方法)