目标
- 了解fasttext
- 使用fasttext进行分类
分类问题
首先介绍分类问题,以二分类问题为例。目前具有人工标注的数据集,数据集分为2类标签,正例和反例。数据示例如下:
- 正例: 印度药企对中国市场充满期待
- 反例: 中国驻维也纳代表团举办改革开放40周年活动
预测新样例的类别
我国东部第一口干热岩钻井获得成功 => [正例?/反例?]
FastText简介
fasttext结构
- xi x i : 一个句子的特征,初始值为随机生成(也可以采用预训练的词向量)
- hidden: xi x i 的平均值
- output: 样本标签
目标函数
- N N : 样本个数
- : 第n个样本对应的类别
- f f : 损失函数 softmax/ns(negative sampling)/hs(hierarchical softmax)
- : 第n个样本的归一化特征
- A A : 权重矩阵(构建词,embedding层)
- : 权重矩阵(隐层到输出层)
词向量初始化
一个句子的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
- 当语料类别较多时,使用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种类型的示例图如下:
cbow
- skipgram
图片来源 https://blog.csdn.net/itplus/article/details/37969519
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值进行评测算法性能
参考文献
- word2vec详解 https://blog.csdn.net/itplus/article/details/37969519
- fastText源码 https://github.com/facebookresearch/fastText
- 分层softmax和n-gram https://arxiv.org/abs/1607.01759
- N-gram https://arxiv.org/abs/1607.04606
- 模型压缩 https://arxiv.org/abs/1612.03651