【问题标题】:SkLearn: Feature Union with a dictionary and text dataSkLearn:具有字典和文本数据的特征联合
【发布时间】:2017-12-21 23:19:51
【问题描述】:

我有一个像这样的 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_dataworker_dict,粗略地连接两列,然后在其上运行多项式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)

但我的准确率非常差,我认为拟合两个独立模型比在两种类型的特征上拟合一个模型更好地利用数据(就像我对堆叠所做的那样)。

我将如何使用 Feature Union? worker_dicts 有点奇怪,因为它是一本字典,所以我对如何解析它感到非常困惑。

【问题讨论】:

    标签: python-3.x scikit-learn feature-selection


    【解决方案1】:

    如果您的字典条目像您的示例中那样是分类的,那么我会在进行额外处理之前从字典条目创建不同的列。

    new_features = pd.DataFrame(df['worker_dicts'].values.tolist())
    

    然后new_features 将成为它自己的数据框,其中包含SectorState 列,除了 TFIDF 或text_data 列的其他特征提取之外,您还可以根据需要对它们进行热编码。为了在管道中使用它,您需要创建一个新的转换器类,所以我可能建议分别应用字典解析和 TFIDF,然后堆叠结果,并将OneHotEncoding 添加到您的管道中,因为这样可以让您指定要应用转换器的列。 (由于您要编码的类别是字符串,您可能希望使用 LabelBinarizer 类而不是 OneHotEncoder 类进行编码转换。)

    如果您只想通过管道单独对所有列使用 TFIDF,则需要使用嵌套管道和 FeatureUnion 设置来提取列,如 here 所述。

    如果您在数据帧 X1 和 X2 中具有如下所述的一个热编码功能,并且您在 X3 中具有文本功能,则可以执行以下操作来创建管道。 (还有很多其他的选择,这只是一种方式)

    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())
                              ])
    

    (MultinomialNB 无法在管道中工作,因为它没有 fitfit_transform 方法)

    【讨论】:

    • 这是一个非常有用的答案!与此同时,我最终使用 Pandas 来做一些事情:首先,我将每个 worker_dicts 键(SectorState)转换为列,然后我对这些列中的每一列使用 one-hot 编码.然后,对于这两列,我堆叠了作为 one-hot 编码输出的所有稀疏矩阵。令X1X2 分别表示由SectorState 的one-hot 编码组成的堆叠稀疏数组。让X3 表示矢量化的text_data 列。
    • 鉴于对数据的修改——我们现在有X1X2X3——你会对你建议的两种方法进行任何修改吗?
    猜你喜欢
    • 2018-12-25
    • 2019-06-29
    • 2018-05-24
    • 2018-06-08
    • 2015-10-02
    • 2016-10-11
    • 2016-06-07
    • 2017-12-11
    • 2019-05-30
    相关资源
    最近更新 更多