首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何为多个数据列制作管道?

如何为多个数据列制作管道?
EN

Stack Overflow用户
提问于 2017-12-19 21:27:13
回答 3查看 5.4K关注 0票数 5

我有Dataframe,可以简化为:

代码语言:javascript
运行
复制
import pandas as pd

df = pd.DataFrame([{
'title': 'batman',
'text': 'man bat man bat', 
'url': 'batman.com', 
'label':1}, 
{'title': 'spiderman',
'text': 'spiderman man spider', 
'url': 'spiderman.com', 
'label':1},
{'title': 'doctor evil',
 'text': 'a super evil doctor', 
'url': 'evilempyre.com', 
'label':0},])

我也想尝试不同的特征提取方法: TFIDF、word2vec、Coutvectorizer等,但我想尝试不同的组合:一个特征集将包含用TFIDF转换的' text‘数据,而'url’则由Countvectoriser转换而来,第二个特征集将由w2v转换文本数据,以及由TFIDF转换'url‘等等。最后,当然,我想对不同的预处理策略进行比较,并选择最佳的预处理策略。

以下是一些问题:

  1. 有没有办法用标准的滑雪工具,比如管道来做这样的事情?
  2. 我的想法有常识吗?也许有好的想法,如何处理多列的数据数据,这是我错过了?

非常感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-12-20 18:45:44

@elphz答案是一个很好的介绍,您可以使用FeatureUnionFunctionTransformer来完成这一任务,但我认为它需要更多的细节。

首先,我想说,您需要定义您的FunctionTransformer函数,以便它们能够正确地处理和返回您的输入数据。在这种情况下,我假设您只是想传递DataFrame,但要确保返回一个正确形状的数组供下游使用。因此,我建议只传递DataFrame并按列名进行访问。就像这样:

代码语言:javascript
运行
复制
def text(X):
    return X.text.values

def title(X):
    return X.title.values

pipe_text = Pipeline([('col_text', FunctionTransformer(text, validate=False))])

pipe_title = Pipeline([('col_title', FunctionTransformer(title, validate=False))])

现在,测试变压器和分类器的变化。我建议使用一个变压器列表和一个分类器列表,然后简单地迭代它们,就像网格搜索一样。

代码语言:javascript
运行
复制
tfidf = TfidfVectorizer()
cv = CountVectorizer()
lr = LogisticRegression()
rc = RidgeClassifier()

transformers = [('tfidf', tfidf), ('cv', cv)]
clfs = [lr, rc]

best_clf = None
best_score = 0
for tran1 in transformers:
    for tran2 in transformers:
        pipe1 = Pipeline(pipe_text.steps + [tran1])
        pipe2 = Pipeline(pipe_title.steps + [tran2])
        union = FeatureUnion([('text', pipe1), ('title', pipe2)])
        X = union.fit_transform(df)
        X_train, X_test, y_train, y_test = train_test_split(X, df.label)
        for clf in clfs:
            clf.fit(X_train, y_train)
            score = clf.score(X_test, y_test)
            if score > best_score:
                best_score = score
                best_est = clf

这是一个简单的例子,但您可以看到如何以这种方式插入各种转换和分类器。

票数 2
EN

Stack Overflow用户

发布于 2018-10-08 13:36:35

查看以下链接:union.html

代码语言:javascript
运行
复制
class ItemSelector(BaseEstimator, TransformerMixin):
def __init__(self, key):
    self.key = key

def fit(self, x, y=None):
    return self

def transform(self, data_dict):
    return data_dict[self.key]

键值接受熊猫dataframe列标签。在您的管道中使用它时,可以将其应用于:

代码语言:javascript
运行
复制
('tfidf_word', Pipeline([
            ('selector', ItemSelector(key='column_name')),
            ('tfidf', TfidfVectorizer())), 
            ]))
票数 4
EN

Stack Overflow用户

发布于 2017-12-19 22:58:41

我将使用FunctionTransformer的组合只选择特定的列,然后使用FeatureUnion在每一列上组合TFIDF、word计数等特性。可能有一种稍微更干净的方法,但我认为您最终会得到某种FeatureUnion和管道嵌套。

代码语言:javascript
运行
复制
from sklearn.preprocessing import FunctionTransformer
from sklearn.pipeline import FeatureUnion, Pipeline
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer

def first_column(X):
    return X.iloc[:, 0]

def second_column(X):
    return X.iloc[:, 1]

# pipeline to get all tfidf and word count for first column
pipeline_one = Pipeline([
    ('column_selection', FunctionTransformer(first_column, validate=False)),
    ('feature-extractors', FeatureUnion([('tfidf', TfidfVectorizer()),
                                        ('counts', CountVectorizer())

    ]))
])

# Then a second pipeline to do the same for the second column
pipeline_two = Pipeline([
    ('column_selection', FunctionTransformer(second_column, validate=False)),
    ('feature-extractors', FeatureUnion([('tfidf', TfidfVectorizer()),
                                        ('counts', CountVectorizer())

    ]))
])


# Then you would again feature union these pipelines 
# to get different feature selection for each column
final_transformer = FeatureUnion([('first-column-features', pipeline_one),
                                  ('second-column-feature', pipeline_two)])

# Your dataframe has your target as the first column, so make sure to drop first
y = df['label']
df = df.drop('label', axis=1)

# Now fit transform should work
final_transformer.fit_transform(df)

如果您不想将多个转换器应用到每一列(tfidf和计数都可能没有用),那么您可以将嵌套减少一个步骤。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47895434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档