one hot编码:又称独热编码,一位有效编码。其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有它独立寄存器,并且在任意时候,其中只有一位有效。
one hot在特征提取上属于词袋模型(bag of words)。
优点:1.解决了分类器不好处理离散数据的问题;
2.在一定程度上也起了扩充特征的作用
缺点:1、不考虑词与词之间的顺序
2、假设词与词相互独立
3、得到的特征是离散稀疏的
Word2vec:是词的一种表示,他将词以固定维数的向量表示出来。
Word2Vec包含了两种词训练模型:CBOW模型、Skip-gram模型,其中CBOW模型根据中心词W(t)周围的词来预测中心词;Skip-gram模型则根据中心词W(t)来预测周围词
优势:word2vec充分利用上下文信息,对上下文进行训练。每个词不在是只有一个位置为1,其余位置为0的稀疏向量。而是一个稠密的固定维度向量。
fastText:是一种Facebook AI Research在16年开源的一个文本分类器。提供简单而高效的文本分类和表征学习的方法,性能比深度学习而且速度更快,大大缩短了训练时间。
模型架构:
该方法包含三部分:模型架构、层次N-gram和 Softmax 特征。
模型架构:类似于CBOW,两种模型都是基于Hierarchical Softmax,都是三层架构:输入层、 隐藏层、输出层。
层次N-gram:考虑到词之间的顺序,将单词的字符级别的n-gram向量作为特征。
层次 Softmax :建立在哈弗曼编码的基础上,对标签进行编码,能够极大地缩小模型预测目标的数量,改善了运行时间。其结构如图:
优点:效果好,速度快,适合大型数据,大大降低了 模型训练时间,适用与分类类别非常大而且数据集足够多的情况。
缺点:当分类类别比较小或者数据集比较少的话,很容易过拟合。
文本分类代码:
from BaseUtil.BaseModel import BaseModel
import tensorflow as tf
class fastTextModel(BaseModel):
""" A simple implementation of fasttext for text classification """
def __init__(self, sequence_length, num_classes, vocab_size,
embedding_size, learning_rate, decay_steps, decay_rate,
l2_reg_lambda, is_training=True,
initializer=tf.random_normal_initializer(stddev=0.1)):
self.vocab_size = vocab_size
self.embedding_size = embedding_size
self.num_classes = num_classes
self.sequence_length = sequence_length
self.learning_rate = learning_rate
self.decay_steps = decay_steps
self.decay_rate = decay_rate
self.is_training = is_training
self.l2_reg_lambda = l2_reg_lambda
self.initializer = initializer
self.input_x = tf.placeholder(tf.int32, [None, self.sequence_length], name='input_x')
self.input_y = tf.placeholder(tf.int32, [None, self.num_classes], name='input_y')
self.global_step = tf.Variable(0, trainable=False, name='global_step')
self.instantiate_weight()
self.logits = self.inference()
self.loss_val = self.loss()
self.train_op = self.train()
self.predictions = tf.argmax(self.logits, axis=1, name='predictions')
correct_prediction = tf.equal(self.predictions, tf.argmax(self.input_y, 1))
self.accuracy = tf.reduce_mean(tf.cast(correct_prediction, 'float'), name='accuracy')
def instantiate_weight(self):
with tf.name_scope('weights'):
self.Embedding = tf.get_variable('Embedding', shape=[self.vocab_size, self.embedding_size],
initializer=self.initializer)
self.W_projection = tf.get_variable('W_projection', shape=[self.embedding_size, self.num_classes],
initializer=self.initializer)
self.b_projection = tf.get_variable('b_projection', shape=[self.num_classes])
def inference(self):
"""
1. word embedding
2. average embedding
3. linear classifier
:return:
"""
# embedding layer
with tf.name_scope('embedding'):
words_embedding = tf.nn.embedding_lookup(self.Embedding, self.input_x)
self.average_embedding = tf.reduce_mean(words_embedding, axis=1)
logits = tf.matmul(self.average_embedding, self.W_projection) +self.b_projection
return logits
def loss(self):
# loss
with tf.name_scope('loss'):
losses = tf.nn.softmax_cross_entropy_with_logits(labels=self.input_y, logits=self.logits)
data_loss = tf.reduce_mean(losses)
l2_loss = tf.add_n([tf.nn.l2_loss(cand_var) for cand_var in tf.trainable_variables()
if 'bias' not in cand_var.name]) * self.l2_reg_lambda
data_loss += l2_loss * self.l2_reg_lambda
return data_loss
def train(self):
with tf.name_scope('train'):
learning_rate = tf.train.exponential_decay(self.learning_rate, self.global_step,
self.decay_steps, self.decay_rate,
staircase=True)
train_op = tf.contrib.layers.optimize_loss(self.loss_val, global_step=self.global_step,
learning_rate=learning_rate, optimizer='Adam')
return train_op