FastText学习笔记

目标

  • 了解fasttext
  • 使用fasttext进行分类

分类问题

首先介绍分类问题,以二分类问题为例。目前具有人工标注的数据集,数据集分为2类标签,正例和反例。数据示例如下:

  • 正例: 印度药企对中国市场充满期待
  • 反例: 中国驻维也纳代表团举办改革开放40周年活动

预测新样例的类别

我国东部第一口干热岩钻井获得成功 => [正例?/反例?]

FastText简介

fasttext结构

  • xi x i : 一个句子的特征,初始值为随机生成(也可以采用预训练的词向量)
  • hidden: xi x i 的平均值
  • output: 样本标签

目标函数

  • N N : 样本个数
  • yn: 第n个样本对应的类别
  • f f : 损失函数 softmax/ns(negative sampling)/hs(hierarchical softmax)
  • xn: 第n个样本的归一化特征
  • A A : 权重矩阵(构建词,embedding层)
  • B: 权重矩阵(隐层到输出层)

词向量初始化

一个句子的embedding为 [iw1,iw2,...,iwn,ow1,ow2,...,ows] [ i w 1 , i w 2 , . . . , i w n , o w 1 , o w 2 , . . . , o w s ]

  • iwi i w i : 语料中出现的词,排在数组的前面
  • owi o w i : n-gram或n-char特征
  • 初始化为随机数, 如果提供预训练的词向量,对应的词采用预训练的词向量

hierarchical Softmax

图片来源参考1

图片来源 https://blog.youkuaiyun.com/itplus/article/details/37969519

  • 当语料类别较多时,使用hierarchical Softmax(hs)减轻计算量
  • hs利用Huffman 树实现,词(生成词向量)或label(分类问题)作为叶子节点
  • 根据词或label的count构建Huffman 树,则叶子到root一定存在一条路径
  • 利用逻辑回归二分类计算loss

n-gram和n-char

fasttext方法不同与word2vec方法,引入了两类特征并进行embedding。其中n-gram颗粒度是词与词之间,n-char是单个词之间。两类特征的存储均通过计算hash值的方法实现。

n-gram

示例: who am I? n-gram设置为2

n-gram特征有,who, who am, am, am I, I

n-char
  • 示例: where, n=3, 设置起止符<, >
  • n-char特征有,<wh, whe, her, ere, er>

模型压缩

为了减小模型大小和内存占用量,fasttext针对分类问题的模型提供了模型压缩的方法,采用的模型压缩方法,模型压缩之后可能会造成准确率和召回率的下降。

训练词向量模型

fasttext作为训练词向量任务,有2种类型的模型,一是根据周围词语预测自身的cbow(continuous bag-of-words)模型,另一个是根据自身预测周围词的skip-gram(continuous skip-gram)模型。2种类型的示例图如下:

FastText分类(python)

语料准备

语料示例
\__label__1 印度 药企 中国市场 充满 期待
  • __label__: 类别前缀,涉及fasttext参数-label,两者需保持一致,构造词典时根据前缀判断是词还是label
  • 1: 类别id,用来区分不同类,可自定义
  • “印度 药企 中国市场 充满 期待”: 分词结果

API介绍

为使用fasttext的python版,前提安装fasttext,从github下载最新代码并安装,并

from fastText import train_supervised, load_model
  • 分类问题模型训练

    def train_supervised(input, lr=0.1, dim=100, 
                       ws=5, epoch=5, minCount=1, 
                       minCountLabel=0, minn=0, 
                       maxn=0, neg=5, wordNgrams=1, 
                       loss="softmax", bucket=2000000, 
                       thread=12, lrUpdateRate=100,
                       t=1e-4, label="__label__", 
                       verbose=2, pretrainedVectors=""):
      """
      训练一个监督模型, 返回一个模型对象
    
      @param input: 训练数据文件路径
      @param lr:              学习率
      @param dim:             向量维度
      @param ws:              cbow模型时使用
      @param epoch:           次数
      @param minCount:        词频阈值, 小于该值在初始化时会过滤掉
      @param minCountLabel:   类别阈值,类别小于该值初始化时会过滤掉
      @param minn:            构造subword时最小char个数
      @param maxn:            构造subword时最大char个数
      @param neg:             负采样
      @param wordNgrams:      n-gram个数
      @param loss:            损失函数类型, softmax, ns: 负采样, hs: 分层softmax
      @param bucket:          词扩充大小, [A, B]: A语料中包含的词向量, B不在语料中的词向量
      @param thread:          线程个数, 每个线程处理输入数据的一段, 0号线程负责loss输出
      @param lrUpdateRate:    学习率更新
      @param t:               负采样阈值
      @param label:           类别前缀
      @param verbose:         ??
      @param pretrainedVectors: 预训练的词向量文件路径, 如果word出现在文件夹中初始化不再随机
      @return model object
    
      """
      pass
  • 词向量训练

    fasttext不仅可以进行文本分类,也可以训练词向量,准备语料时,只需要去掉原始数据中的label标签即可。

    def train_unsupervised(input, model="skipgram", lr=0.05, dim=100, 
                       ws=5, epoch=5, minCount=5, 
                       minCountLabel=0, minn=3, 
                       maxn=6, neg=5, wordNgrams=1, 
                       loss="ns", bucket=2000000, 
                       thread=12, lrUpdateRate=100,
                       t=1e-4, label="__label__", 
                       verbose=2, pretrainedVectors=""):
      """
      训练词向量,返回模型对象
      输入数据不要包含任何标签和使用标签前缀
    
      @param model: 模型类型, cbow/skipgram两种
      其他参数参考train_supervised()方法
      @return model
      """
      pass

  • 模型压缩

    def model.quantize(self, input=None, qout=False, cutoff=0,
                     retrain=False, epoch=None, lr=None, thread=None,
                     verbose=None, dsub=2, qnorm=False):
      """
      减小模型大小和内存占用
    
      @param input:   训练数据文件路径
      @param qout:    是否修剪输出层
      @param cutoff:  重新训练的词和n-gram的个数
      @param retrain: 是否重新训练
      @param epoch:   次数
      @param lr:      学习率
      @param thread:  线程个数
      @param verbose: ?
      @param dsub:    压缩方法将向量分成几块, 每块大小
      @param qnorm:   是否归一化(l2范数)
    
      """
      pass
  • 模型存储

    def model.save_model(self, path):
      """
      把模型存储到给定的路径
    
      @param path: 模型路径
      """
      pass
  • 模型单例预测

    def model.predict(self, text, k=1, threshold=0.0):
      """
      模型预测,给定文本预测分类
    
      @param text:       字符串, 需要utf-8
      @param k:          返回标签的个数
      @param threshold   概率阈值, 大于该值才返回
      @return 标签列表, 概率列表
      """
      pass
  • 模型批量预测

    def model.test(self, path, k=1):
      """
      根据给定的测试数据进行模型评价
    
      @param path: 测试数据路径
      @param k:    返回标签的个数
      @return [样本个数, 准确率, 召回率]
      """
      pass
  • 模型加载

    def load_model(path):
      """
      从给定的路径加载模型, 返回一个模型对象
    
      @param path: 模型路径
      @return model object
      """
      pass

分类评测

根据precision, recall, f1值进行评测算法性能

参考文献

  1. word2vec详解 https://blog.youkuaiyun.com/itplus/article/details/37969519
  2. fastText源码 https://github.com/facebookresearch/fastText
  3. 分层softmax和n-gram https://arxiv.org/abs/1607.01759
  4. N-gram https://arxiv.org/abs/1607.04606
  5. 模型压缩 https://arxiv.org/abs/1612.03651
### 深度学习与自然语言处理中的文本向量化 #### ### 1. 文本向量化的基础概念 在自然语言处理(NLP)领域,文本向量化是将文本数据转换为数值形式的过程,以便机器能够理解和处理这些数据。早期的方法包括独热编码(One-Hot Encoding),但这种方法会导致维度灾难,即当词汇表规模较大时,生成的向量维度会非常高,计算和存储成本显著增加[^1]。 为了解决这一问题,研究者提出了词嵌入(Word Embedding)技术,它将高维的独热向量映射到低维的稠密向量空间中。这种低维表示不仅减少了维度,还能够捕捉词语之间的语义关系[^2]。 #### ### 2. 常见的文本向量化方法 以下是几种常见的文本向量化方法及其特点: - **独热编码**:每个词用一个唯一的向量表示,向量的长度等于词汇表的大小,仅有一个位置为1,其余位置为0。虽然简单直接,但存在维度灾难的问题。 - **词袋模型(Bag of Words, BoW)**:统计文档中每个词的出现频率,并将其作为特征向量。BoW 忽略了词序信息,可能丢失上下文含义[^4]。 - **TF-IDF**:基于词频(Term Frequency, TF)和逆文档频率(Inverse Document Frequency, IDF)来衡量词的重要性。相比 BoW,TF-IDF 更加注重区分性特征[^4]。 - **词嵌入(Word Embedding)**:通过训练神经网络模型得到的低维稠密向量表示,能够有效捕捉词语间的语义关系。常用的词嵌入方法包括 Word2Vec、GloVe 和 FastText 等[^3]。 #### ### 3. 基于深度学习的文本向量化方法 随着深度学习的发展,越来越多的模型被应用于文本向量化任务中。以下是一些典型的深度学习模型: - **循环神经网络(RNN)**:RNN 能够处理序列数据,适用于建模句子或文档等具有顺序结构的文本数据。然而,标准 RNN 存在梯度消失和梯度爆炸的问题。 - **长短时记忆网络(LSTM)**:LSTM 是一种改进版的 RNN,通过引入门控机制解决了长期依赖问题,能够更好地捕捉长距离依赖关系。 - **卷积神经网络(CNN)**:尽管 CNN 最初用于图像处理,但在 NLP 中也表现出色。通过滑动窗口提取局部特征,CNN 可以快速捕获短语级别的模式[^1]。 - **Transformer 模型**:Transformer 使用自注意力机制(Self-Attention Mechanism)代替传统的 RNN 结构,能够在并行化训练的同时有效建模全局上下文信息。BERT、GPT 等预训练模型均基于 Transformer 架构[^3]。 #### ### 4. 实现文本向量化的代码示例 以下是一个使用 `gensim` 库实现 Word2Vec 的代码示例: ```python from gensim.models import Word2Vec # 示例句子 sentences = [["我", "喜欢", "自然", "语言", "处理"], ["深度", "学习", "很", "有用"]] # 训练 Word2Vec 模型 model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4) # 获取词向量 vector = model.wv["自然"] print(vector) ``` #### ### 5. 预训练模型的应用 近年来,预训练模型如 BERT、GPT 等在 NLP 领域取得了显著成果。这些模型通过在大规模语料库上进行无监督学习,获得了丰富的语言知识。在具体任务中,可以通过微调预训练模型来快速适应特定场景,从而减少对标注数据的需求[^3]。 以下是一个使用 Hugging Face 的 `transformers` 库加载并微调 BERT 模型的示例: ```python from transformers import BertTokenizer, TFBertForSequenceClassification import tensorflow as tf # 示例文本和标签 texts = ["我喜欢这部电影", "这部电影很无聊"] labels = [1, 0] # 加载 tokenizer 和预训练模型 tokenizer = BertTokenizer.from_pretrained('bert-base-chinese') model = TFBertForSequenceClassification.from_pretrained('bert-base-chinese') # 对文本进行编码 inputs = tokenizer(texts, return_tensors="tf", padding=True, truncation=True, max_length=128) # 创建数据集 dataset = tf.data.Dataset.from_tensor_slices((dict(inputs), labels)).batch(2) # 编译模型 model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=5e-5), loss=model.compute_loss, metrics=['accuracy']) # 训练模型 model.fit(dataset, epochs=3) ``` ####
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值