[常见的自然语言处理技术] Bag-of-Words Model:简单直观的统计语言模型

前言

当我们要使用机器学习演算法来解决自然语言的问题,我们首先必须将文字进行量化( quantification )。而透过数字来表示语言的演算法,就称之为语言模型( language model )。

A statistical language model is a probability distribution over sequences of words.

文字出处:Language Model| Wikipedia

词袋模型(Bag-of-Words Model, BoW)

浅谈词「袋」

词袋模型是一个基於单词出现频率来表示文字的方法,它并不考虑单词的排列顺序、或甚至是文法结构。

It is called a “bag” of words, because any information about the order or structure of words in the document is discarded. The model is only concerned with whether known words occur in the document, not where in the document.

文字出处:A Gentle Introduction to the Bag-of-Words Model

图片来源:A Bag of Words: Levels of Language

词袋模型(bag-of-words language model, BoW)在今日的语言模型当中当属最简单、最容易理解的了。虽说如此,其应用却十分广泛,它可被用来找寻新闻标题、过滤诈骗邮件、找出推文的正负向情绪、甚至到建立文字云( word cloud )等等。

脸书文字云
图片来源:https://devilmen.blogspot.com/2012/02/fb.html

文字的向量化

图片来源:Text Encoding: A Review
我们将句子「 Natural language processing is fun. 」当中的每个词条进行小写转换、断词与词形还原的前处理,并排列如下:

这时候我们分别计算以下两个句子中的单词出现在上述参考单词的次数:
Sentence 1: The story was fun.

Sentence 2: I watched a fun movie in a threatre called "FUN TIME".

我们可以藉由特徵出现的频率,将上述句子转换成向量:
Sentence 1: The story was fun. ⟶ (0, 0, 0, 1, 1)
Sentence 2: I watched a fun movie in a threatre called "FUN TIME". ⟶ (0, 0, 0, 0, 2)

我们不难发现,参照的文字资料的选择,会影响向量的表达。因此我们必须找出具有代表文字特徵的字串作为基准,建立特徵词典( features dictionary )。而当我们考虑更多的文字资料,我们就会得到更长的特徵词典,从而将文字表达成更高维度的向量。

如何用Python写一个词袋模型

首先我们定义训练文本:

training_docs = ["Five fantastic fish flew off to find faraway functions.",
                 "Maybe find another five fantastic fish?",
                 "Find my fish with a function please!"]

接着建立 features dictionary

# merge a list of string to a single string
merged = ' '.join(training_docs)
# Stop word removal, tokenisation and lemmatisation
tokens = preprocess_text(merged)

features_dict = dict()
index = 0
for token in tokens:
    print("token: {}".format(token))
    # if not a new word
    if token in features_dict:
        continue
    else:
        features_dict[token] = index
        index += 1

我们不妨将 features dictionary 打印出来,检视编码结果,其长度决定了文字向量化後的维度:

我们写个字串转换为向量的函式:

def text_to_bow_vector(sample_text, features_dict):
    """
    sample_text: string
    """
    bow_vector = [0] * len(features_dict)
    tokens = preprocess_text(sample_text)
    for token in tokens:
        feature_index = features_dictionary[token]
        bow_vector[feature_index] += 1
    return bow_vector

接着,我们欲将以下文句依照 features dictionary 向量化:

text = "My fish found five fish!"
bow_vector = text_to_bow_vector(text, features_dict)

字串「 My fish found five fish! 」透过词袋模型向量化的结果 bow_vector 等於 [1, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0] (维度 = 15)。

结论:

今天我们介绍了透过计算特徵单词出现频率而得出向量的词袋模型,为一个简单的统计语言模型。然而随着训练文本份量的增加,转化後的向量维度往往十分可观,因此容易引发维数灾难( curse of dimenionality )。再者,由於其仅考虑单一词条,以词袋模型建立的机器学习模型(例如用来分类文件的单纯贝氏分类器和文本主题预测的马可夫链等)将很可能对资料有过拟合( overfitting )的现象。下一回我们将介绍词袋模型的衍伸语言模型: n-gram models ,比较其与词袋模型的优缺点。今天的介绍就到此画下句点,我们明天见!

阅读更多

  1. Language Model
  2. Curse of Dimensionality

<<:  安全测试员的职业道德败给贪念

>>:  # Day 7 Supporting PMUs on RISC-V platforms (三)

CPE 一颗星解答 - Java 笔记与心得分享

以下是自己的 CPE 一颗星选集解题纪录,共有 49 题 重点笔记整理如下, https://gre...

档案搜寻+日期+大小+keyword【Delphi 附例】

延续上一篇利用call back function Enumerate搜寻子目录下档案,今天再继续完...

[Day22] 在 Codecademy 学 React ~ 原来 useState 就是 this.state + this.setState 啊!

前言 其实你知道吗? 今天要讲的 this.state this.setState 其实就是之前介绍...

【在厨房想30天的演算法】Day 22 演算法 : 最短路径 Shortest Path Bellman–Ford 演算法

Aloha!我是少女人妻 Uerica!我家狗狗每天六点都会叫我起床,但除非自己很早睡,不然六点起床...

04

本人也是经过了深思熟虑,在每个日日夜夜思考这个问题。编译语言的出现,重写了人生的意义。编译语言可以说...