一分为二

PythonPythonBeginner
立即练习

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

简介

在这个项目中,你将学习如何实现一个子词分词器,这是自然语言处理任务中的关键一步。分词是将一串文本分解为更小单元(称为词元)的过程,这些词元可以是单个单词、字符或子词。本项目重点关注子词级别的分词,这在英语和其他基于拉丁字母的语言中很常用。

👀 预览

['I','studied', 'in', 'LabEx', 'for', '1', '0', 'days', 'and', 'completed', 'the', '[UNK]', '[UNK]', 'course', '.']

🎯 任务

在这个项目中,你将学习:

  • 如何使用贪婪最长匹配优先算法实现一个执行字符级分词的子词分词器函数
  • 如何使用提供的示例测试子词分词器并分析输出
  • 如何理解分词算法及其实现

🏆 成果

完成本项目后,你将能够:

  • 理解分词在自然语言处理任务中的重要性
  • 实现自然语言处理管道的一个核心组件
  • 区分字符级和子词级分词
  • 应用贪婪最长匹配优先算法将文本分词为子词

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/DataStructuresGroup(["Data Structures"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/AdvancedTopicsGroup(["Advanced Topics"]) python(("Python")) -.-> python/DataScienceandMachineLearningGroup(["Data Science and Machine Learning"]) python/BasicConceptsGroup -.-> python/strings("Strings") python/DataStructuresGroup -.-> python/lists("Lists") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/AdvancedTopicsGroup -.-> python/regular_expressions("Regular Expressions") python/DataScienceandMachineLearningGroup -.-> python/data_analysis("Data Analysis") python/DataScienceandMachineLearningGroup -.-> python/machine_learning("Machine Learning") subgraph Lab Skills python/strings -.-> lab-300244{{"一分为二"}} python/lists -.-> lab-300244{{"一分为二"}} python/function_definition -.-> lab-300244{{"一分为二"}} python/regular_expressions -.-> lab-300244{{"一分为二"}} python/data_analysis -.-> lab-300244{{"一分为二"}} python/machine_learning -.-> lab-300244{{"一分为二"}} end

理解分词过程

在这一步中,你将了解分词过程及其在自然语言处理任务中的重要性。

分词是将一串文本分解为更小单元(称为词元)的过程。根据所使用的具体分词方法,这些词元可以是单个单词、字符或子词。

在自然语言处理任务中,大多数机器学习模型不直接支持字符串数据。为了使模型能够有效地学习,字符串数据必须进行数字化,这一过程称为分词。分词也是数字化的准备工作,而数字化需要一个映射,该映射由映射表提供。

字符级分词是一种基于语言中最小符号来划分字符串的方法,常用于英语分词。

子词级分词常用于英语和其他基于拉丁字母的语言,是对词级分词的一种改进。

实现子词分词器

在这一步中,你将实现一个子词分词器函数,该函数使用贪婪最长匹配优先算法对英语单词执行字符级分词。此函数还会从输入字符串中删除所有符号,包括空格。

在代码编辑器中打开 subword_tokenizer.py 文件。此文件包含 subword_tokenizer() 函数的框架。你的任务是填写该函数中缺失的部分。

该函数应满足以下要求:

  1. 函数应接受一个字符串作为输入。此函数接收一个包含英语字符、数字和标点符号的字符串。该字符串已提供给你,你不能更改字符串的内容。
  2. 函数应返回分词结果作为一个列表。

以下是 subword_tokenizer() 函数的完整代码:

import re

def subword_tokenizer(text, vocab) -> list:
    """
    根据提供的词汇表将输入文本分词为子词。

    参数:
    - text (str):要分词的输入文本。
    - vocab (list):包含子词的词汇表列表。

    返回:
    - list:子词标记列表。
    """

    def is_in_vocab(word) -> bool:
        """
        检查给定的词是否在词汇表中。

        参数:
        - word (str):要检查的词。

        返回:
        - bool:如果词在词汇表中,则返回 True,否则返回 False。
        """
        return word in vocab

    def find_longest_match(word) -> tuple:
        """
        在词汇表中找到给定词的最长匹配子词。

        参数:
        - word (str):要找到匹配项的词。

        返回:
        - tuple:一个包含最长匹配子词和词的剩余部分的元组。
        """
        for i in range(len(word), 0, -1):
            subword = word[:i]
            if is_in_vocab(subword):
                return subword, word[i:]
        return "[UNK]", ""

    tokens = []
    ## 移除非字母数字字符并将文本拆分为单词
    words = re.findall(r"\b\w+\b", text)

    for word in words:
        while word:
            subword, remaining = find_longest_match(word)
            tokens.append(subword)
            word = remaining

    return tokens


if __name__ == "__main__":
    ## 示例用法:
    vocab = [
        "I",
        "studied",
        "in",
        "LabEx",
        "for",
        "1",
        "0",
        "days",
        "and",
        "completed",
        "the",
        "course",
    ]
    text = "I studied in LabEx for 10 days and completed the TensorFlow Serving course."

    tokenization_result = subword_tokenizer(text, vocab)
    print(tokenization_result)

测试子词分词器

在这一步中,你将使用提供的示例测试 subword_tokenizer() 函数并验证输出。

在终端中运行 subword_tokenizer.py 脚本:

python3 subword_tokenizer.py

输出应类似于以下内容:

['I','studied', 'in', 'LabEx', 'for', '1', '0', 'days', 'and', 'completed', 'the', '[UNK]', '[UNK]', 'course', '.']

观察输出并确保分词过程按预期工作。该函数应将输入文本分词为子词列表,其中未知单词由 [UNK] 标记表示。

理解分词算法

在这一步中,你将更深入地了解 subword_tokenizer() 函数的实现,并理解分词算法。

subword_tokenizer() 函数使用贪婪最长匹配优先算法对输入文本进行分词。该算法的工作原理如下:

  1. 函数首先从输入文本中移除所有非字母数字字符,并将文本拆分为单个单词。
  2. 对于每个单词,函数尝试在提供的词汇表中找到最长匹配的子词。
  3. 如果在词汇表中找到了子词,就将其添加到词元列表中。如果没有找到子词,则将 [UNK] 词元添加到列表中。
  4. 这个过程会一直持续,直到输入文本中的所有单词都被分词。

is_in_vocab() 函数是一个辅助函数,用于检查给定的单词是否存在于提供的词汇表中。

find_longest_match() 函数是分词算法的核心。它从最长可能的子词开始遍历单词,并检查当前子词是否在词汇表中。如果找到匹配项,它将返回子词和单词的剩余部分。如果没有找到匹配项,它将返回 [UNK] 词元和一个空字符串。

理解分词算法将帮助你进一步改进子词分词器,或使其适用于不同的用例。

✨ 查看解决方案并练习

总结

恭喜你!你已经完成了这个项目。你可以在实验(LabEx)中练习更多实验来提升你的技能。