FastText相对于word2vec,对于问题的预测更直接。word2vec主要是通过上下文信息来学习词语的向量(含有语义特征)表示,fasttext则是在此基础上直接输出目标label。对于文本分类任务,fasttext引入了n-gram特征,可以更好获得句子的语义特征。另外fasttext对于类别数较多时,也采用Hierarchical softmax来降低计算复杂度。
对于fasttext而言,需要考虑以下几个问题:
(1)embedding的长度取多少合适?
实践中embedding为300时在遍历完一遍数据时acc就达到0.9433,embedding为200时遍历完一遍数据acc达到0.9400,可见embedding大些可以更好的学习模型,但是整体效果提升较小。
可见embedding大些可以更好的学习模型,但是数据集太小容易过拟合。
(2)n-gram中的n取多少合适?
实践中采用A:jieba的分词结果,B:A+unigram, C:jieba全模式的分词结果+unigram结果表明B比A略好,C表现最差。
此外实验还验证了仅用unigram作为文本输入,其效果也还可以(90%+),比基于词的差了几个百分点。
可见引入n-gram特征需要根据具体样本集进行设置。
基于tensorflow的实现(由于实践中的类别共61类,类别较少,模型设计就没采用分层的softmax):
# -*- coding:utf-8 -*-
import os
import numpy as np
import tensorflow as tf
from tensorflow.contrib import slim
from nlp_utils import *
class FastText():
def __init__(self,
num_classes,
seq_length,
vocab_size,
embedding_dim,
learning_rate,
learning_decay_rate,
learning_decay_steps,
epoch
self.num_classes = num_classes
self.seq_length = seq_length
self.vocab_size = vocab_size
self.embedding_dim = embedding_dim
self.learning_rate = learning_rate
self.learning_decay_rate = learning_decay_rate
self.learning_decay_steps = learning_decay_steps
self.epoch = epoch
self.input_x = tf.placeholder(tf.int32, [None, self.seq_length], name='input_x')
self.input_y = tf.placeholder(tf.float32, [None, self.num_classes], name='input_y')
self.dropout_keep_prob = tf.placeholder(tf.float32, name='keep_prob')
self.model()
def model(self):
# 词向量映射
with tf.name_scope("embedding"):
self.embedding = tf.get_variable("embedding", [self.vocab_size, self.embedding_dim])
embedding_inputs = tf.nn.embedding_lookup(self.embedding, self.input_x) # batch_zie * seq_length * embedding_dim
with tf.name_scope("dropout"):
dropout_output = tf.nn.dropout(embedding_inputs, self.dropout_keep_prob)
# 对词向量进行平均
with tf.name_scope("average"):
mean_sentence = tf.reduce_mean(dropout_output, axis=1) # batch_zie * embedding_dim
# 输出层
with tf.name_scope("score"):
self.logits = tf.layers.dense(mean_sentence, self.num_classes, name='dense_layer')
# 损失函数,交叉熵
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=self.logits, labels=self.input_y)
# l2_loss = tf.losses.get_regularization_loss()
self.loss = tf.reduce_mean(cross_entropy, name="loss")
# 优化函数
self.global_step = tf.train.get_or_create_global_step()
learning_rate = tf.train.exponential_decay(self.learning_rate, self.global_step,
self.learning_decay_steps, self.learning_decay_rate,
staircase=True)
optimizer = tf.train.AdamOptimizer(learning_rate)
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
self.optim = slim.learning.create_train_op(total_loss=self.loss, optimizer=optimizer, update_ops=update_ops)
# 准确率
self.y_pred_cls = tf.argmax(tf.nn.softmax(self.logits), 1, name="pred")
correct_pred = tf.equal(tf.argmax(self.input_y, 1), self.y_pred_cls)
self.acc = tf.reduce_mean(tf.cast(correct_pred, tf.float32), name="acc")
def fit(self, train_x, train_y, val_x, val_y, batch_size, keep_prob):
# 创建模型保存路径
if not os.path.exists('./saves/fasttext'): os.makedirs('./saves/fasttext')
if not os.path.exists('./train_logs/fasttext'): os.makedirs('./train_logs/fasttext')
# 开始训练
train_steps = 0
best_val_acc = 0
# summary
tf.summary.scalar('val_loss', self.loss)
tf.summary.scalar('val_acc', self.acc)
merged = tf.summary.merge_all()
# 初始化变量
sess = tf.Session()
writer = tf.summary.FileWriter('./train_logs/fasttext', sess.graph)
saver = tf.train.Saver(max_to_keep=10)
sess.run(tf.global_variables_initializer())
for i in range(self.epoch):
batch_train = self.batch_iter(train_x, train_y, batch_size)
for batch_x, batch_y in batch_train:
train_steps += 1
feed_dict = { self.input_x:batch_x, self.input_y:batch_y, self.dropout_keep_prob:keep_prob }
_, train_loss, train_acc = sess.run([self.optim,self.loss,self.acc], feed_dict=feed_dict)
if train_steps % 1000 == 0:
#feed_dict = { self.input_x:val_x, self.input_y:val_y, self.dropout_keep_prob:1}
#val_loss, val_acc = sess.run([self.loss,self.acc], feed_dict=feed_dict)
val_loss, val_acc = self.evaluate(sess, val_x, val_y)
summary = sess.run(merged, feed_dict=feed_dict)
writer.add_summary(summary, global_step=train_steps)
if val_acc >= best_val_acc:
best_val_acc = val_acc
saver.save(sess, "./saves/fasttext/", global_step=train_steps)
msg = 'epoch:%d/%d,train_steps:%d,train_loss:%.4f,train_acc:%.4f,val_loss:%.4f,val_acc:%.4f'
print(msg % (i+1, self.epoch, train_steps, train_loss, train_acc, val_loss, val_acc))
def batch_iter(self, x, y, batch_size=32, shuffle=True):
生成batch数据
:param x: 训练集特征变量
:param y: 训练集标签
:param batch_size: 每个batch的大小
:param shuffle: 是否在每个epoch时打乱数据
:return:
data_len = len(x)
num_batch = int((data_len - 1) / batch_size) + 1
if shuffle:
shuffle_indices = np.random.permutation(np.arange(data_len))
x_shuffle = x[shuffle_indices]
y_shuffle = y[shuffle_indices]
else:
x_shuffle = x
y_shuffle = y
for i in range(num_batch):
start_index = i * batch_size
end_index = min((i + 1) * batch_size, data_len)
yield (x_shuffle[start_index:end_index], y_shuffle[start_index:end_index])
def evaluate(self, sess, x_, y_):
评估 val data 的准确率和损失
data_len = len(x_)
# 用到loader.py
batch_eval = self.batch_iter(x_, y_, 64)
total_loss = 0.0
total_acc = 0.0
for x_batch, y_batch in batch_eval:
batch_len = len(x_batch)
feed_dict = { self.input_x: x_batch, self.input_y: y_batch,
self.dropout_keep_prob: 1}
loss, acc = sess.run([self.loss, self.acc], feed_dict=feed_dict)
total_loss += loss * batch_len
total_acc += acc * batch_len
return total_loss / data_len, total_acc / data_len
def predict(self, x):
sess = tf.Session()
sess.run(tf.global_variables_initializer())
saver = tf.train.Saver(tf.global_variables())
ckpt = tf.train.get_checkpoint_state('./saves/fasttext/')
saver.restore(sess, ckpt.model_checkpoint_path)
feed_dict = {self.input_x: x}
logits = sess.run(self.logits, feed_dict=feed_dict)
y_pred = np.argmax(logits, 1)
return y_pred
if __name__ == "__main__":
train_file = "./train.txt"
val_file = "./val.txt"
data_set_train = load_data2(train_file) # 加载数据
data_set_val = load_data2(val_file) # 加载数据
word2id_dict, label2id_dict = build_dict(data_set_train) # 构建dict
save_dict(word2id_dict, "word2id_dict.txt")
save_dict(label2id_dict, "label2id_dict.txt")
batch_size = 64
max_seq_len = 32
num_classes = len(label2id_dict)
vocab_size = len(word2id_dict)
embedding_dim = 300
learning_rate = 0.01
learning_decay_rate = 0.95
learning_decay_steps = 100
epoch = 5
dropout_keep_prob = 0.5
train_x, train_y = convert_corpus_to_id_with_padding(data_set_train, word2id_dict, label2id_dict, max_seq_len, num_classes)
val_x, val_y = convert_corpus_to_id_with_padding(data_set_val, word2id_dict, label2id_dict, max_seq_len, num_classes)
fast_text = FastText(num_classes, max_seq_len, vocab_size, embedding_dim, learning_rate, learning_decay_rate, learning_decay_steps, epoch)
fast_text.fit(train_x, train_y, val_x, val_y, batch_size, dropout_keep_prob)
代码如下:# -*- coding:utf-8 -*-import osimport numpy as npimport tensorflow as tffrom tensorflow.contrib import slimfrom nlp_utils import *class FastText(): def __init__(self, num_classes, seq_length,
fast
text
-serving [OPTIONS] --model < model>
FLAGS:
--grpc Serving gRPC API instead of HTTP API
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-a, --addr
文章目录
fast
Text
原理及
实践
预备知识Softmax回归分层Softmaxn-gram特征
fast
Text
分类字符级别的n-gram模型架构核心思想关于分类效果keras构建
fast
Text
参考资料
fast
Text
原理及
实践
Softmax回归
Softmax回归(Softmax Regression)又被称作多项逻辑回归(multinomial logistic regressi...
目录0、内容介绍1、
Fast
Text
是什么?1.1 安装1.2 如何使用?A:单词表达模型B:文本分类模型C:使用量化压缩模型2、使用
fast
Text
训练文本分类模型2.1 训练数据准备2.2 训练模型2.3 模型保存与测试
0、内容介绍
本文主要介绍如何使用利用
fast
Text
进行文本分类任务,包括如何准备、处理数据,训练及测试过程。
最近用到
fast
Text
进行文本分类任务,其不用训练好的词向...
文章目录简要原理
fast
Text
的两个任务是分类和训练词向量,传统的word2vec把语料库的每个单词当作原子的,为每个单词生成一个词向量,而
fast
Text
是对每个字符进行处理的,也就是字符级别的n_gram:参考:https://www.zhihu.com/search?type=content&q=
fast
text
上图表示
fast
Text
的模型架构.
fast
Text
...
数据抽取:
获取主诉信息(主诉是医生对病人的症状及发展情况描述)、病人性别、年龄、科室信息
fast
text
官网:https://
fast
text
.cc/docs/en/supervised-tutorial.html
fast
text
介绍
Fast
Text
是Facebook研究团队创建的一个库,用于高效计算word representation和执行文本分类,可以在几秒内完成其他算法几天才可以完成的任务。
实践
注意事项
数据预处理:
由于有些主诉相同时,挂的科室也不一样,需要进一步处理,如删除某个类别的
1、python中,类中方法定义的第一个参数始终是
self
,表示引用方法的对象自身(如a.py中的obj对象),定义方法的语句形如a.py中的Tprint(
self
, value);在java中也有类似的表示对象自身的参数,但定义时不会明确写出来,所以叫做隐含参数,定义方法的语句形如public void Tprint(value)。
2、注意Tprint中的
global
修饰符,通过将变量va声明为全局变量,使得Tprint()能够访问其上层的命名空间的变量。反之,如果这里va不声明为全局变量,则va =
model_name = "
fast
text
"
saver = tf.train.Saver(max_to_keep=10)
saver.save(sess, model_path + model_name,
global
_step=train_steps)
保存模型时会在model_path路径下得到3个名为model_name的文件和一个checkpoint文件,如下所示:
.data-00000-of-00001和.index
fast
Text
是一个用于文本分类和情感分析的库,由Facebook AI研发并开源。它的优势在于快速高效的训练速度和在大规模数据上的表现。
在使用
fast
Text
进行实战之前,首先需要准备训练数据。训练数据应该是一个文本文件,每行包含一个句子和其对应的标签。接着,可以使用
fast
Text
提供的命令行工具来训练模型。
训练模型的命令如下:
fast
text
supervised -input train.txt -output model
其中,train.txt是训练数据文件的路径,model是输出模型文件的路径。
训练完成后,可以使用训练好的模型来进行文本分类或情感分析。可以使用如下命令:
fast
text
predict model.bin test.txt
其中,model.bin是之前训练好的模型文件的路径,test.txt是测试数据文件的路径。
fast
Text
还支持多种参数的调整,以优化模型性能。例如,可以调整n-gram的大小、词向量维度和学习率等。可以通过命令行参数来指定这些参数的值。
fast
Text
还可以用于文本的表示学习。通过训练一个无监督的模型,可以得到文本的词向量表示。这些词向量可以用于很多自然语言处理任务,如文本聚类、文本相似度等。
总结来说,
fast
Text
是一个强大的文本分类和情感分析工具,能够快速高效地处理大规模数据。通过调整参数和使用无监督学习,可以进一步提升模型的性能。
降级0.20.3时报错error: legacy-install-failure
× Encountered error while trying to install package.
╰─> scikit-learn 是为啥呀