文档向量化算法综述

文档向量化算法综述

  • 文档向量化
    • 方法:
    • 算法简介
      • One-Hoe 算法
      • 词袋模型算法
      • Bi-gram、N-gram 算法简介
      • TF-IDF 算法
      • 共现矩阵算法简介
      • word2vec 简介
    • 方法的优劣性:
      • One-hot 的优、缺点
        • 代码:
      • 词袋模型优缺点
      • Bi-gram、N-gram 优缺点
        • 代码
      • TF-IDF 优缺点
      • word2vec 优点
    • 步骤

文档向量化

方法:

  • 文本向量化的方法有很多:

    • 离散词向量表示

      • 基于规则、统计

        • 词集模型(Set of Word)

          • One-Hot encoding,只要单个文本中单词出现在字典中,就将其置为 1,不管出现多少次
          • 统计各词在句子中是否出现
        • 词袋模型(Bag of Word)

          • 统计各词在句子中出现的次数
          • 只要单个文本中单词出现在字典中,就将其向量值加 1,出现多少次就加多少次
        • Bi-gram、N-gram

        • TF-IDF

          • 统计各词在文档中的 TF-IDF 值(词袋模型 + IDF 值)
        • 共现矩阵

    • 分布式词向量表示

      • 基于神经网络的词嵌入

        • word2vec
        • doc2vec
        • str2vec

算法简介

One-Hoe 算法

one-hot 词汇表征方法最后形成的结果是一种稀疏编码结果,在深度学习应用于 NLP 任务之前, 这种表征方法在传统的 NLP 模型中已经取得了很好的效果。但是这种表征方法有两个缺陷: 一是容易造成维数灾难,10000 个单词的词汇表不算多,但对于百万级、千万级的词汇表简直无法忍受。

词袋模型算法

  • 对于句子、篇章,常用的离散表示方法是词袋模型,词袋模型以 One-Hot 为基础,忽略词表中词的顺序和语法关系, 通过记录词表中的每一个词在该文本中出现的频次来表示该词在文本中的重要程度,解决了 One-Hot 未能考虑词频的问题
  • 词袋(Bag Of Word) 模型是最早的以词语为基本单元的文本向量化方法。词袋模型,也称为计数向量表示(Count Vectors). 文档的向量表示可以直接使用单词的向量进行求和得到

Bi-gram、N-gram 算法简介

  • 与词袋模型原理类似,Bi-gram 将相邻两个词编上索引,N-gram 将相邻 N 个词编上索引

TF-IDF 算法

  • TF-IDF(词频-逆文档频率法,Term Frequency-Inverse Document Frequency) 作为一种加权方法, TF-IDF 在词袋模型的基础上对次出现的频次赋予 TF-IDF 权值,对词袋模型进行修正,进而表示该词在文档集合中的重要程度

    • 统计各词在文档中的 TF-IDF 值(词袋模型 + IDF 值)
    • 词袋模型、Bi-gram、N-gram 都是基于计数得到的,而 TF-IDF 则是基于频率统计得到的
    • 在利用 TF-IDF 进行特征提取时,若词 α 在某篇文档中出现频率较高且在其他文档中出现频率较低时, 则认为α可以代表该文档的特征,具有较好的分类能力,那么α作为特征被提取出来
  • TF-IDF 的分数代表了词语在当前文档和整个语料库中的相对重要性。TF-IDF 分数由两部分组成

    • TF(Term Frequency):词语频率

      TF(t)=词语在当前文档出现的次数/当前文档中词语的总数TF(t)

      • TF 判断的是该字/词语是否是当前文档的重要词语,但是如果只用词语出现频率来判断其是否重要可能会出现一个问题, 就是有些通用词可能也会出现很多次,如:a、the、at、in 等,当然一般我们会对文本进行预处理时去掉这些所谓的停用词(stopwords), 但是仍然会有很多通用词无法避免地出现在很多文档中,而其实它们不是那么重要
    • IDF(Inverse Document Frequency):逆文档频率

      IDF(t)=loge(文档总数/出现该词语的文档总数)

      • IDF 用于判断是否在很多文档中都出现了词词语,即很多文档或所有文档中都出现的就是通用词。 出现该词语的文档越多,IDF 越小,其作用是抑制通用词的重要性
    • 将上述求出的 TF 和 IDF 相乘得到的分数 TF-IDF,就是词语在当前文档和整个语料库中的相对重要性

    • TF-IDF 与一个词在当前文档中出现次数成正比,与该词在整个语料库中的出现次数成反比

共现矩阵算法简介

  • 共现:即共同实现,比如:一句话中共同出现,或一篇文章中共同出现

  • 共现矩阵构造时需要给出共同出现的距离一个规范– 窗口

    • 如果窗口宽度是 2,那就是在当前词的前后各 2 个词的范围内共同出现, 可以想象,其实是一个总长为 5 的窗口依次扫过所有文本,同时出现在其中的词就说它们共现
  • 当前词与自身不存在共现,共现矩阵实际上是对角矩阵

word2vec 简介

word2vec 通常有两个版本的语言模型:

  • 一种是给定上下文词,需要我们来预测中间目标词,这种模型叫做连续词袋模型(Continuous Bag-of-Wods Model,CBOW)
  • 另一种是给定一个词语,我们来根据这个词预测它的上下文,这种模型叫做 skip-gram 模型。而且每个模型都有两种策略

方法的优劣性:

One-hot 的优、缺点

  • 优点:简单快捷

  • 缺点:数据稀疏、耗时耗空间、不能很好地展示词与词之间的相似关系,且还未考虑到词出现的频率,因而无法区别词的重要性

    • One-hot 的第一个问题是:One-hot 的基本假设是词之间的语义和语法关系是相互独立的,仅仅从两个向量是无法看出两个词汇之间的关系的,这种独立性不适合词汇语义的运算;
    • One-hot 的第二个问题是:维度爆炸问题,随着词典规模的增大,句子构成的词袋模型的维度变得越来越大,矩阵也变得超稀疏,这种维度的爆增,会大大耗费计算资源。

代码:

import os
import numpy as np
import pandas as pd
import jieba

def doc2onthot_matrix(file_path):
   """
   文本向量化 One-Hot
      1.文本分词
   """
   # (1)读取待编码的文件
   with open(file_path, encoding = "utf-8") as f:
      docs = f.readlines()

   # (2)将文件每行分词,分词后的词语放入 words 中
   words = []
   for i in range(len(docs)):
      docs[i] = jieba.lcut(docs[i].strip("\n"))
      words += docs[i]

   # (3)找出分词后不重复的词语,作为词袋,是后续 onehot 编码的维度, 放入 vocab 中
   vocab = sorted(set(words), key = words.index)

   # (4)建立一个 M 行 V 列的全 0 矩阵,M 是文档样本数,这里是行数,V 为不重复词语数,即编码维度
   M = len(docs)
   V = len(vocab)
   onehot = np.zeros((M, V))
   for i, doc in enumerate(docs):
      for word in doc:
         if word in vocab:
            pos = vocab.index(word)
            onehot[i][pos] = 1
   onehot = pd.DataFrame(onehot, columns = vocab)
   return onehot


if __name__ == "__main__":
   data_dir = ""
   corpus = os.path.join(data_dir, "aaa.txt")
   onehot = doc2onthot_matrix(corpus)
   print(onehot)

词袋模型优缺点

  • 优点:

    • 方法简单,当语料充足时,处理简单的问题如文本分类,其效果比较好
  • 缺点:

    • 数据稀疏、维度大
    • 无法保留词序信息
    • 存在语义鸿沟的问题

Bi-gram、N-gram 优缺点

优点:

  • 考虑了词的顺序

缺点:

  • 词向量急剧膨胀

代码

def ngrams(input_list, n):
    return [input_list[i:i+n] for i in range(len(input_list)-n+1)]

# 定义文档
document = "This is a sentence for n-gram example."

# 分词
words = document.lower().split()

# 生成 bi-gram
bigrams = ngrams(words, 2)
print("Bi-grams:", bigrams)

# 生成 tri-gram
trigrams = ngrams(words, 3)
print("Tri-grams:", trigrams)

# 生成 4-gram
fourgrams = ngrams(words, 4)
print("Four-grams:", fourgrams)

#Bi-grams: [['this', 'is'], ['is', 'a'], ['a', 'sentence'], ['sentence', 'for'], ['for', 'n-gram'], ['n-gram', 'example.']]
#Tri-grams: [['this', 'is', 'a'], ['is', 'a', 'sentence'], ['a', 'sentence', 'for'], ['sentence', 'for', 'n-gram'], ['for', 'n-gram', 'example.']]
#Four-grams: [['this', 'is', 'a', 'sentence'], ['is', 'a', 'sentence', 'for'], ['a', 'sentence', 'for', 'n-gram'], ['sentence', 'for', 'n-gram', 'example.']]

TF-IDF 优缺点

  • 优点:

    • 简单快速,结果比较符合实际情况
  • 缺点:

    • 单纯以”词频”衡量一个词的重要性,不够全面,有时重要的词可能出现次数并不多
    • 无法体现词的位置信息,出现位置靠前的词与出现位置靠后的词,都被视为重要性相同,这是不正确的

word2vec 优点

  • 高效,Mikolov 在论文中指出一个优化的单机版本一天可以训练上千亿个词

步骤

文档向量化可以使用如下步骤实现:

  1. 分词:将文档分成词语。
  2. 建立词典:将文档中出现的所有词语建立词典。
  3. 构建词频向量:统计每个词语在文档中的词频,并创建词频向量。
  4. 词向量转换:使用预训练的词向量模型将词频向量转换为对应的词向量。
  5. 文档向量计算:对词向量进行求和或平均,得到文档向量。

你可能感兴趣的:(算法,自然语言处理,文档向量化,词袋模型)