如何使用FeatureUnion转换PipeLine中的多个特征?

2024-05-27

我有一个 pandas 数据框,其中包含有关用户发送的消息的信息。 对于我的模型,我感兴趣的是预测消息的缺失收件人,即给定消息的收件人 A、B、C,我想预测还有谁应该成为收件人的一部分。

我正在使用 OneVsRestClassifier 和 LinearSVC 进行多标签分类。 对于功能,我想使用消息的收件人。主题和主体。

由于收件人是用户列表,我想使用 MultiLabelBinarizer 转换该列。对于主题和正文,我想使用 TFIDF

我的输入 pickle 文件的数据如下: 除收件人之外的所有值都是字符串,这是一个 set()

[[message_id,sent_time,subject,body,set(recipients),message_type, is_sender]]

我在管道中使用功能联合和自定义转换器来实现此目的,如下所示。

from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.base import TransformerMixin, BaseEstimator
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.multiclass import OneVsRestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.multiclass import OneVsRestClassifier
from sklearn.linear_model import SGDClassifier
from sklearn.svm import SVC, LinearSVC
import pickle
import pandas as pd
import numpy as np

if __name__ == "__main__":
class ColumnSelector(BaseEstimator, TransformerMixin):
    def __init__(self, column):
        self.column = column

    def fit(self, X, y=None, **fit_params):
        return self

    def transform(self, X, y=None, **fit_params):
        return X[self.column]

class MultiLabelTransformer(BaseEstimator, TransformerMixin):

    def __init__(self, column):
        self.column = column

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

    def transform(self, X):
        mlb = MultiLabelBinarizer()
        return mlb.fit_transform(X[self.column])

pipeline = Pipeline([
    ('features', FeatureUnion([
        ('subject_tfidf', Pipeline([
                    ('selector', ColumnSelector(column='Subject')),
                    ('tfidf', TfidfVectorizer(min_df=0.0025, ngram_range=(1, 4)))
                    ])),
        ('body_tfidf', Pipeline([
            ('selector', ColumnSelector(column='Body')),
            ('tfidf', TfidfVectorizer(min_df=0.0025, ngram_range=(1, 4)))
        ])),
        ('recipients_binarizer', Pipeline([
            ('multi_label', MultiLabelTransformer(column='CoRecipients'))
        ])),
    ])),
    ('classifier', OneVsRestClassifier(LinearSVC(), n_jobs=-1))
])

top_recips = ['A', 'B', 'C, 'D]
corpus_data = pickle.load(
    open("E:\\Data\\messages_items.pkl", "rb"))
df = pd.DataFrame(corpus_data, columns=[
    'MessageId', 'SentTime', 'Subject', 'Body', 'Recipients', 'MessageType', 'IsSender'])

df = df.dropna()

# add co recipients and top recipients columns
df['CoRecipients'] = df['Recipients'].apply(
    lambda r: [x for x in r if x not in top_recips])
df['TopRecipients'] = df['Recipients'].apply(
    lambda r: [x for x in top_recips if x in r])

# drop rows where top recipients = 0
df = df.loc[df['TopRecipients'].str.len() > 0]
df_train = df.loc[df['SentTime'] <= '2017-10-15']
df_test = df.loc[(df['SentTime'] > '2017-10-15') & (df['MessageType'] == 'Meeting')]

mlb = MultiLabelBinarizer(classes=top_recips)

train_x = df_train[['Subject', 'Body', 'CoRecipients']]
train_y = mlb.fit_transform(df_train['TopRecipients'])

test_x = df_train[['Subject', 'Body', 'CoRecipients']]
test_y = mlb.fit_transform(df_train['TopRecipients'])

print "train"
pipeline.fit(train_x, train_y)

print "predict"
predictions = pipeline.predict(test_x)

print "done"

我不确定我是否正确地对 CoRecipients 列进行了特征化。因为结果看起来不正确。有什么线索吗?

UPDATE 1

将MLB变压器的代码更改如下:

class MultiLabelTransformer(BaseEstimator, TransformerMixin):
        def __init__(self, column):
            self.column = column

        def fit(self, X, y=None):
            self.mlb = MultiLabelBinarizer()
            self.mlb.fit(X[self.column])
            return self

        def transform(self, X):
            return self.mlb.transform(X[self.column])

并将测试集修复为使用 df_test

mlb = MultiLabelBinarizer(classes=top_recips)

train_x = df_train[['Subject', 'Body', 'CoRecipients']]
train_y = mlb.fit_transform(df_train['TopRecipients'])

test_x = df_test[['Subject', 'Body', 'CoRecipients']]
test_y = mlb.transform(df_test['TopRecipients'])

看到下面的KeyError

Traceback (most recent call last):
  File "E:\Projects\NLP\FeatureUnion.py", line 99, in <module>
    predictions = pipeline.predict(test_x)
  File "C:\Python27\lib\site-packages\sklearn\utils\metaestimators.py", line 115, in <lambda>
    out = lambda *args, **kwargs: self.fn(obj, *args, **kwargs)
  File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 306, in predict
    Xt = transform.transform(Xt)
  File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 768, in transform
    for name, trans, weight in self._iter())
  File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 779, in __call__
    while self.dispatch_one_batch(iterator):
  File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 625, in dispatch_one_batch
    self._dispatch(tasks)
  File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 588, in _dispatch
    job = self._backend.apply_async(batch, callback=cb)
  File "C:\Python27\lib\site-packages\sklearn\externals\joblib\_parallel_backends.py", line 111, in apply_async
    result = ImmediateResult(func)
  File "C:\Python27\lib\site-packages\sklearn\externals\joblib\_parallel_backends.py", line 332, in __init__
    self.results = batch()
  File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 131, in __call__
    return [func(*args, **kwargs) for func, args, kwargs in self.items]
  File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 571, in _transform_one
    res = transformer.transform(X)
  File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 426, in _transform
    Xt = transform.transform(Xt)
  File "E:\Projects\NLP\FeatureUnion.py", line 37, in transform
    return self.mlb.transform(X[self.column])
  File "C:\Python27\lib\site-packages\sklearn\preprocessing\label.py", line 765, in transform
    yt = self._transform(y, class_to_index)
  File "C:\Python27\lib\site-packages\sklearn\preprocessing\label.py", line 789, in _transform
    indices.extend(set(class_mapping[label] for label in labels))
  File "C:\Python27\lib\site-packages\sklearn\preprocessing\label.py", line 789, in <genexpr>
    indices.extend(set(class_mapping[label] for label in labels))
KeyError: u'[email protected] /cdn-cgi/l/email-protection'

> 更新2

工作代码

 class MultiLabelTransformer(BaseEstimator, TransformerMixin):
        def __init__(self, column, classes):
            self.column = column
            self.classes = classes
    def fit(self, X, y=None):
        self.mlb = MultiLabelBinarizer(classes=self.classes)
        self.mlb.fit(X[self.column])
        return self

    def transform(self, X):
        return self.mlb.transform(X[self.column])

# drop rows where top recipients = 0
df = df.loc[df['TopRecipients'].str.len() > 0]
df_train = df.loc[df['SentTime'] <= '2017-10-15']
df_test = df.loc[(df['SentTime'] > '2017-10-15') &
                 (df['MessageType'] == 'Meeting')]

mlb = MultiLabelBinarizer(classes=top_recips)

train_x = df_train[['Subject', 'Body', 'CoRecipients']]
train_y = mlb.fit_transform(df_train['TopRecipients'])

test_x = df_test[['Subject', 'Body', 'CoRecipients']]
test_y = mlb.transform(df_test['TopRecipients'])

# get all unique co-recipients
co_recips = list(set([a for b in df.CoRecipients.tolist() for a in b]))

# create pipeline
pipeline = Pipeline([
    ('features', FeatureUnion(
        # list of features
        transformer_list=[
            ('subject_tfidf', Pipeline([
                    ('selector', ColumnSelector(column='Subject')),
                    ('tfidf', TfidfVectorizer(min_df=0.0025, ngram_range=(1, 4)))
                    ])),
            ('body_tfidf', Pipeline([
                ('selector', ColumnSelector(column='Body')),
                ('tfidf', TfidfVectorizer(min_df=0.0025, ngram_range=(1, 4)))
            ])),
            ('recipients_binarizer', Pipeline([
                ('multi_label', MultiLabelTransformer(column='CoRecipients', classes=co_recips))
            ]))
        ],
        # weight components in FeatureUnion
        transformer_weights={
            'subject_tfidf': 3.0,
            'body_tfidf': 1.0,
            'recipients_binarizer': 1.0,
        }
    )),
    ('classifier', OneVsRestClassifier(LinearSVC(), n_jobs=-1))
])

print "train"
pipeline.fit(train_x, train_y)

print "predict"
predictions = pipeline.predict(test_x)

您对 MultiLabelBinarizer 的转换是错误的。您适合训练和测试数据。那不是正确的方法。

您应该始终只适合训练数据并对测试数据使用转换。

这个错误你已经犯过两次了:

  • 在 MultiLabelTransformer 中,您可以在其中转换“共同接收者”
  • 在转换 test_y 期间,您可以转换“TopRecipients”

问题是,当测试数据在“Co-recipients”或“TopRecipients”中具有不同(或新)值时,返回的数组将具有与训练期间不同的形状。这会导致错误的结果。

像这样更改您的代码:

class MultiLabelTransformer(BaseEstimator, TransformerMixin):

    #Updated
    def __init__(self, column, classes):
        self.column = column
        self.classes = classes

    def fit(self, X, y=None):
        # Updated
        self.mlb = MultiLabelBinarizer(classes = self.classes)
        self.mlb.fit(X[self.column])
        return self

    def transform(self, X):
        return self.mlb.transform(X[self.column])

And

test_y = mlb.transform(df_train['TopRecipients'])

在管道内部:

....
....
('multi_label', MultiLabelTransformer(column='CoRecipients',
                                      classes=set([a for b in df.CoRecipients.tolist() for a in b]))
....
....

虽然最后的改变test_y不会影响返回的数组,因为您已经使用指定了类top_recips during mlb = MultiLabelBinarizer(classes=top_recips),但最好只对测试数据进行变换(而不是 fit 或 fit_transform )。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用FeatureUnion转换PipeLine中的多个特征? 的相关文章

  • 如何将 sklearn.naive_bayes 与(多个)分类特征一起使用? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想学习朴素贝叶斯模型来解决类为布尔值的问题 有些特征是布尔型的 但其他特征是分类型的 并且可以采用少量值 5 如果我所有的功能都是布尔值
  • Python 谷歌语音

    我正在使用 google voice APIhere https pypi python org pypi pygooglevoice 0 5 并尝试从 Python 发送短信 但是 每当我尝试使用此代码登录时 我都会得到一些意想不到的信息
  • 多索引上的 pandas dataframe groupby

    我正在使用 Pandas dataframe 来读取 Excel 文件并对其进行一些操作 我有一个包含多行的标题 现在我想按几个列值进行分组 但是我无法找到解决方案 Excel 示例 name address contact info fi
  • 将字符转换为日期时间 odoo 9

    我有两个字符字段 从 odoo 中的 excel 或 csv 导入数据 time 1 fields Char string Time 1 time 2 fields Char string Time 2 result fields Floa
  • 使用 Python 2.7 中的修饰方法调用进行模拟

    这段代码 import mock from functools import wraps def dec f wraps f def f 2 args kwargs pass return f 2 class Example object
  • 语法错误可以处理吗?

    考虑以下代码 try if True a 1 It s missing a colon So it s a SyntaxError except SyntaxError print hey 你会期望它打印出来hey然而它提出了一个Synta
  • 为什么 scikit learn 的平均精度分数返回 nan?

    我的 Keras 模型旨在接收两个输入时间序列 将它们连接起来 通过 LSTM 提供它们 并在下一个时间步骤中进行多标签预测 有 50 个训练样本 每个样本有 24 个时间步 每个样本有 5625 个标签 有 12 个验证样本 每个样本有
  • 使用 lxml 和 xpath 解析 xml 文件时如何保留 &

    我试图从输入 xml 文件中提取一些信息 并使用 lxml 和 xpath 指令将其打印到输出文件中 我在读取如下所示的 xml 标签时遇到问题
  • 池化与随时间池化

    我从概念上理解最大 总和池中发生的情况作为 CNN 层操作 但我看到这个术语 随时间变化的最大池 或 随时间变化的总和池 例如 用于句子分类的卷积神经网络 https arxiv org pdf 1408 5882 pdfYoon Kim
  • 有什么方法可以让一个进程拥有写锁,而其他进程则只能并行读取?

    假设我有一个包含键值的字典 其中值是带锁的对象 每个进程都需要获得锁来修改特定的对象 但字典中的键是稳定的 现在 正如我之前所说 如果要使用新对象添加新密钥 不是很经常 是否有一种方法可以使用锁来排除其他进程在我将密钥添加到字典时访问对象
  • 如何使用 python 标准库 zipfile 检查 zip 文件是否已加密?

    我正在使用 python 的标准库 zipfile 来测试存档 zf zipfile ZipFile archive name if zf testzip None checksum OK True 我收到这个运行时异常 File pack
  • os.listdir 和 os.path.isdir 混淆,isdir 是随机的吗?

    我有下面这个简单的过程来列出文件夹的内容 def some process self dir3 os listdir Users somepath programming somepathanother Data samples for d
  • numpy.polyfit 给出有用的拟合,但协方差矩阵无限

    我正在尝试将多项式拟合到一组数据 有时可能会出现以下情况 返回的协方差矩阵numpy ployfit仅由inf 尽管拟合似乎很有用 没有numpy inf或数据中的 numpy nan Example import numpy as np
  • PyCharm 调试模式下的键盘中断

    在调试模式下 有什么方法可以在 PyCharm IDE 3 1 中发送键盘中断事件吗 不幸的是 没有简单的方法可以做到这一点 您将需要使用psutil和signal模块 为此 您需要安装psutil最好的方法是通过pip pip insta
  • 如何限制 sympy FiniteSet 包含符号

    我对 sympy 还很陌生 我尝试使用 linsolve 求解线性方程组 这产生了一个可以用以下两行重现的解决方案 d symbols d solution sets FiniteSet d 1 d 4 d 5 d 我的解决方案遵循限制 即
  • 为 Anaconda Python 安装 psycopg2

    我有 Anaconda Python 3 4 但是每当我运行旧代码时 我都会通过输入 source activate python2 切换到 Anaconda Python 2 7 我的问题是我为 Anaconda Python 3 4 安
  • 使用 scala 在 Flink 中进行实时流预测

    弗林克版本 1 2 0斯卡拉版本 2 11 8 我想使用 DataStream 来使用 scala 中的 flink 模型进行预测 我在使用 scala 的 flink 中有一个 DataStream String 其中包含来自 kafka
  • PyUSB 1.0:NotImplementedError:此平台不支持或未实现操作

    我刚刚开始使用 pyusb 基本上我正在玩示例代码here https github com walac pyusb blob master docs tutorial rst 我使用的是 Windows 7 64 位 并从以下地址下载 z
  • 绘制与Fig.show()内联的IPython Notebook图形?

    我正在使用 IPython Notebook 调用内联模式 pylab inline 以下代码立即在单元格处绘制一个图形 fig plt figure axes fig add axes 0 0 1 1 不过 我想在一个单元格中创建绘图 轴
  • 从列表指向字典变量

    假设你有一个清单 a 3 4 1 我想用这些信息来指向字典 b 3 4 1 现在 我需要的是一个常规 看到该值后 在 b 的位置内读写一个值 我不喜欢复制变量 我想直接改变变量b的内容 假设b是一个嵌套字典 你可以这样做 reduce di

随机推荐