Scikit - 学习列变换器

Machine LearningMachine LearningBeginner
立即练习

This tutorial is from open-source community. Access the source code

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在本实验中,我们将学习如何在包含不同类型特征的数据集上使用 Scikit-Learn 的 ColumnTransformer。当数据集包含需要不同特征提取和处理管道的组件时,此技术非常有用。

虚拟机提示

虚拟机启动完成后,点击左上角切换到“笔记本”标签,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作验证无法自动化。

如果你在学习过程中遇到问题,请随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills ml/sklearn -.-> lab-49087{{"Scikit - 学习列变换器"}} end

数据集

我们将使用20个新闻组数据集,该数据集由20个主题的新闻组帖子组成。根据特定日期之前和之后发布的消息,数据集被分为训练集和测试子集。为了加快运行速度,我们将只使用来自2个类别的帖子。

categories = ["sci.med", "sci.space"]
X_train, y_train = fetch_20newsgroups(
    random_state=1,
    subset="train",
    categories=categories,
    remove=("footers", "quotes"),
    return_X_y=True,
)
X_test, y_test = fetch_20newsgroups(
    random_state=1,
    subset="test",
    categories=categories,
    remove=("footers", "quotes"),
    return_X_y=True,
)

创建转换器

我们将创建从数据集中提取特征的转换器。我们将定义两个执行数据转换的函数,然后使用 Scikit-Learn 的 FunctionTransformer 创建转换器。

def subject_body_extractor(posts):
    ## 构造一个具有两列的对象数据类型数组
    ## 第一列 ='subject',第二列 = 'body'
    features = np.empty(shape=(len(posts), 2), dtype=object)
    for i, text in enumerate(posts):
        ## 临时变量 `_` 存储 '\n\n'
        headers, _, body = text.partition("\n\n")
        ## 将正文文本存储在第二列
        features[i, 1] = body

        prefix = "Subject:"
        sub = ""
        ## 将 'Subject:' 之后的文本保存在第一列
        for line in headers.split("\n"):
            if line.startswith(prefix):
                sub = line[len(prefix) :]
                break
        features[i, 0] = sub

    return features

subject_body_transformer = FunctionTransformer(subject_body_extractor)

def text_stats(posts):
    return [{"length": len(text), "num_sentences": text.count(".")} for text in posts]

text_stats_transformer = FunctionTransformer(text_stats)

分类管道

我们将创建一个管道,该管道从数据集中提取特征,将它们组合起来,并在组合后的特征集上训练一个分类器。我们将使用 Scikit-Learn 的 PipelineColumnTransformer 来实现这一点。

pipeline = Pipeline(
    [
        ## 提取主题和正文
        ("subjectbody", subject_body_transformer),
        ## 使用ColumnTransformer组合主题和正文特征
        (
            "union",
            ColumnTransformer(
                [
                    ## 主题(第0列)的词袋模型
                    ("subject", TfidfVectorizer(min_df=50), 0),
                    ## 正文(第1列)的带分解的词袋模型
                    (
                        "body_bow",
                        Pipeline(
                            [
                                ("tfidf", TfidfVectorizer()),
                                ("best", TruncatedSVD(n_components=50)),
                            ]
                        ),
                        1,
                    ),
                    ## 从帖子正文中提取文本统计信息的管道
                    (
                        "body_stats",
                        Pipeline(
                            [
                                (
                                    "stats",
                                    text_stats_transformer,
                                ),  ## 返回一个字典列表
                                (
                                    "vect",
                                    DictVectorizer(),
                                ),  ## 字典列表 -> 特征矩阵
                            ]
                        ),
                        1,
                    ),
                ],
                ## 上述ColumnTransformer特征的权重
                transformer_weights={
                    "subject": 0.8,
                    "body_bow": 0.5,
                    "body_stats": 1.0,
                },
            ),
        ),
        ## 在组合特征上使用SVC分类器
        ("svc", LinearSVC(dual=False)),
    ],
    verbose=True,
)

训练与测试

我们将在训练数据上拟合我们的管道,并使用它来预测 X_test 的主题。然后打印我们管道的性能指标。

pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
print("Classification report:\n\n{}".format(classification_report(y_test, y_pred)))

总结

在本实验中,我们学习了如何在包含不同类型特征的数据集上使用 Scikit-Learn 的 ColumnTransformer。我们创建了从数据集中提取特征的转换器,并使用它们在组合后的特征集上训练分类器。ColumnTransformer 使我们能够在单个管道中处理不同类型的特征。