精华内容
下载资源
问答
  • BERT模型实战之多文本分类(附源码)

    万次阅读 多人点赞 2019-03-21 11:00:36
    写在前面 BERT模型也出来很久了,之前看了论文学习...这篇文章的内容还是以比较简单文本分类任务入手,数据集选取的是新浪新闻cnews,包括了[‘体育’, ‘财经’, ‘房产’, ‘家居’, ‘教育’, ‘科技’, ‘时尚’...

    BERT模型也出来很久了,之前看了论文学习过它的大致模型(可以参考前些日子写的笔记NLP大杀器BERT模型解读),但是一直有杂七杂八的事拖着没有具体去实现过真实效果如何。今天就趁机来动手写一写实战,顺便复现一下之前的内容。这篇文章的内容还是以比较简单文本分类任务入手,数据集选取的是新浪新闻cnews,包括了[‘体育’, ‘财经’, ‘房产’, ‘家居’, ‘教育’, ‘科技’, ‘时尚’, ‘时政’, ‘游戏’, ‘娱乐’]总共十个主题的新闻数据。那么我们就开始吧!

    Transformer模型

    BERT模型就是以Transformer基础上训练出来的嘛,所以在开始之前我们首先复习一下目前NLP领域可以说是最高效的‘变形金刚’Transformer。由于网上Transformer介绍解读文章满天飞了都,这里就不浪费太多时间了。

    本质上来说,Transformer就是一个只由attention机制形成的encoder-decoder结构。关于attention的具体介绍可以参考之前这篇理解Attention机制原理及模型。理解Transformer模型可以将其进行解剖,分成几个组成部分:

    1. Embedding (word + position)
    2. Attention mechanism (scaled dot-product + multi-head)
    3. Feed-Forward network
    4. ADD(类似于Resnet里的残差操作)
    5. Norm(加快收敛)
    6. Softmax
    7. Fine-tuning

    前期准备

    1.下载BERT

    我们要使用BERT模型的话,首先要去github上下载相关源码:

    git clone  https://github.com/google-research/bert.git
    

    下载成功以后我们现在的文件大概就是这样的
    在这里插入图片描述

    2.下载bert预训练模型

    Google提供了多种预训练好的bert模型,有针对不同语言的和不同模型大小的。Uncased参数指的是将数据全都转成小写的(大多数任务使用Uncased模型效果会比较好,当然对于一些大小写影响严重的任务比如NER等就可以选择Cased)
    在这里插入图片描述
    对于中文模型,我们使用Bert-Base, Chinese。下载后的文件包括五个文件:

    bert_model.ckpt:有三个,包含预训练的参数
    vocab.txt:词表
    bert_config.json:保存模型超参数的文件

    3. 数据集准备

    前面有提到过数据使用的是新浪新闻分类数据集,每一行组成是 【标签+ TAB + 文本内容】
    在这里插入图片描述

    Start Working

    BERT非常友好的一点就是对于NLP任务,我们只需要对最后一层进行微调便可以用于我们的项目需求。我们只需要将我们的数据输入处理成标准的结构进行输入就可以了。

    DataProcessor基类

    首先在run_classifier.py文件中有一个基类DataProcessor类:

    class DataProcessor(object):
      """Base class for data converters for sequence classification data sets."""
    
      def get_train_examples(self, data_dir):
        """Gets a collection of `InputExample`s for the train set."""
        raise NotImplementedError()
    
      def get_dev_examples(self, data_dir):
        """Gets a collection of `InputExample`s for the dev set."""
        raise NotImplementedError()
    
      def get_test_examples(self, data_dir):
        """Gets a collection of `InputExample`s for prediction."""
        raise NotImplementedError()
    
      def get_labels(self):
        """Gets the list of labels for this data set."""
        raise NotImplementedError()
    
      @classmethod
      def _read_tsv(cls, input_file, quotechar=None):
        """Reads a tab separated value file."""
        with tf.gfile.Open(input_file, "r") as f:
          reader = csv.reader(f, delimiter="\t", quotechar=quotechar)
          lines = []
          for line in reader:
            lines.append(line)
          return lines
    

    在这个基类中定义了一个读取文件的静态方法_read_tsv,四个分别获取训练集,验证集,测试集和标签的方法。接下来我们要定义自己的数据处理的类,我们将我们的类命名为MyTaskProcessor

    编写MyTaskProcessor

    MyTaskProcessor继承DataProcessor,用于定义我们自己的任务

    class MyTaskProcessor(DataProcessor):
      """Processor for my task-news classification """
      def __init__(self):
        self.labels = ['体育', '财经', '房产', '家居', '教育', '科技', '时尚', '时政', '游戏', '娱乐']
    
      def get_train_examples(self, data_dir):
        return self._create_examples(
          self._read_tsv(os.path.join(data_dir, 'cnews.train.txt')), 'train')
    
      def get_dev_examples(self, data_dir):
        return self._create_examples(
          self._read_tsv(os.path.join(data_dir, 'cnews.val.txt')), 'val')
    
      def get_test_examples(self, data_dir):
        return self._create_examples(
          self._read_tsv(os.path.join(data_dir, 'cnews.test.txt')), 'test')
    
      def get_labels(self):
        return self.labels
    
      def _create_examples(self, lines, set_type):
        """create examples for the training and val sets"""
        examples = []
        for (i, line) in enumerate(lines):
          guid = '%s-%s' %(set_type, i)
          text_a = tokenization.convert_to_unicode(line[1])
          label = tokenization.convert_to_unicode(line[0])
          examples.append(InputExample(guid=guid, text_a=text_a, label=label))
        return examples
    

    注意这里有一个self._read_tsv()方法,规定读取的数据是使用TAB分割的,如果你的数据集不是这种形式组织的,需要重写一个读取数据的方法,更改“_create_examples()”的实现。

    编写main以及训练

    至此我们就完成了对我们的数据加工成BERT所需要的格式,就可以进行模型训练了。

    def main(_):
      tf.logging.set_verbosity(tf.logging.INFO)
    
      processors = {
          "cola": ColaProcessor,
          "mnli": MnliProcessor,
          "mrpc": MrpcProcessor,
          "xnli": XnliProcessor,
          "mytask": MyTaskProcessor,
      }
    
    python run_classifier.py \
    
     --task_name=mytask \
    
     --do_train=true \
    
     --do_eval=true \
    
     --data_dir=$DATA_DIR/ \
    
     --vocab_file=$BERT_BASE_DIR/vocab.txt \
    
     --bert_config_file=$BERT_BASE_DIR/bert_config.json \
    
     --init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \
    
     --max_seq_length=128 \
    
     --train_batch_size=32 \
    
     --learning_rate=2e-5 \
    
     --num_train_epochs=3.0 \
    
     --output_dir=mytask_output
    

    其中DATA_DIR是你的要训练的文本的数据所在的文件夹,BERT_BASE_DIR是你的bert预训练模型存放的地址。task_name要求和你的DataProcessor类中的名称一致。下面的几个参数,do_train代表是否进行fine tune,do_eval代表是否进行evaluation,还有未出现的参数do_predict代表是否进行预测。如果不需要进行fine tune,或者显卡配置太低的话,可以将do_trian去掉。max_seq_length代表了句子的最长长度,当显存不足时,可以适当降低max_seq_length。
    在这里插入图片描述

    BERT prediction

    上面一节主要就是介绍了怎么去根据我们实际的任务(多文本分类)去fine-tune bert模型,那么训练好适用于我们特定的任务的模型后,接下来就是使用这个模型去做相应地预测任务。预测阶段唯一需要做的就是修改 – do_predict=true。你需要将测试样本命名为test.csv,输出会保存在输出文件夹的test_result.csv,其中每一行代表一个测试样本对应的预测输出,每一列代表对应于不同类别的概率。

    export BERT_BASE_DIR=/path/to/bert/uncased_L-12_H-768_A-12
    export GLUE_DIR=/path/to/glue
    export TRAINED_CLASSIFIER=/path/to/fine/tuned/classifier
    
    python run_classifier.py \
      --task_name=MRPC \
      --do_predict=true \
      --data_dir=$GLUE_DIR/MRPC \
      --vocab_file=$BERT_BASE_DIR/vocab.txt \
      --bert_config_file=$BERT_BASE_DIR/bert_config.json \
      --init_checkpoint=$TRAINED_CLASSIFIER \
      --max_seq_length=128 \
      --output_dir=/tmp/mrpc_output/
    

    有趣的优化

    指定训练时输出loss

    bert自带代码中是这样的,在run_classifier.py文件中,训练模型,验证模型都是用的tensorflow中的estimator接口,因此我们无法实现在训练迭代100步就用验证集验证一次,在run_classifier.py文件中提供的方法是先运行完所有的epochs之后,再加载模型进行验证。训练模型时的代码:

    train_input_fn = file_based_input_fn_builder(
            input_file=train_file,
            seq_length=FLAGS.max_seq_length,
            is_training=True,
            drop_remainder=True)
        estimator.train(input_fn=train_input_fn, max_steps=num_train_steps)
    

    想要实现在训练过程中输出loss日志,我们可以使用hooks参数:

    train_input_fn = file_based_input_fn_builder(
            input_file=train_file,
            seq_length=FLAGS.max_seq_length,
            is_training=True,
            drop_remainder=True)
        tensors_to_log = {'train loss': 'loss/Mean:0'}
        logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=100)
        estimator.train(input_fn=train_input_fn, hooks=[logging_hook], max_steps=num_train_steps)
    
    增加验证集输出的指标值

    原生BERT代码中验证集的输出指标值只有loss和accuracy,

    def metric_fn(per_example_loss, label_ids, logits, is_real_example):
            predictions = tf.argmax(logits, axis=-1, output_type=tf.int32)
            accuracy = tf.metrics.accuracy(
                labels=label_ids, predictions=predictions, weights=is_real_example)
            loss = tf.metrics.mean(values=per_example_loss, weights=is_real_example)
            return {
                "eval_accuracy": accuracy,
                "eval_loss": loss,
            }
    

    但是在分类时,我们可能还需要分析auc,recall,precision等的值。

    def metric_fn(per_example_loss, label_ids, logits, is_real_example):
            predictions = tf.argmax(logits, axis=-1, output_type=tf.int32)
            accuracy = tf.metrics.accuracy(
                labels=label_ids, predictions=predictions, weights=is_real_example)
            loss = tf.metrics.mean(values=per_example_loss, weights=is_real_example)
            auc = tf.metrics.auc(labels=label_ids, predictions=predictions, weights=is_real_example)
            precision = tf.metrics.precision(labels=label_ids, predictions=predictions, weights=is_real_example)
            recall = tf.metrics.recall(labels=label_ids, predictions=predictions, weights=is_real_example)
    
            return {
                "eval_accuracy": accuracy,
                "eval_loss": loss,
                'eval_auc': auc,
                'eval_precision': precision,
                'eval_recall': recall,
            }
    


    以上~
    2019.03.21

    展开全文
  • 一、摘要: (该论文的模型创新点在于词向量那里,所以全文的重心偏向于词向量部分) 传统的机器学习方法主要用词袋...所以现在所提出的词向量,作为神经网络的输入使得文本分类等任务有了更好的效果。 本文提出CNN...

    在这里插入图片描述
    一、摘要
    (该论文的模型创新点在于词向量那里,所以全文的重心偏向于词向量部分)
    传统的机器学习方法主要用词袋以及ngram去生成特征向量作为文本表示,从而完成很多任务。但是对于短文本来说,比如tweet,由于短文本字数的限制,传统机器学习如果继续使用词袋和ngram,则可能会存在数据稀疏以及维度问题。
    所以现在所提出的词向量,作为神经网络的输入使得文本分类等任务有了更好的效果。
    本文提出CNN架构的一种模型。

    二、introduction
    先指出CBOW、TFIDF、ngram等传统方法,并且传统机器学习使用这些方法不能够表示词的语义,并且存在数据稀疏问题等。所以分布式词向量表示逐渐火热,并且非常有效。
    接下来就长篇大论的提word2vec、glove、pudmed等方法,也是更加偏向于去介绍词向量。并且传统的方法不够好,而神经网络的效果很好。所以他们使用了glove和pubmed的embedding,基于这两种embedding,提出了4个CNN模型,分别为CNN-PubMed,CNN-Glove,CNN-PGConcat 和 CNN-PGaverage。

    三、related work
    也是分两个大的模块来说,第一个模块是说传统文本分类方法,机器学习方法不好;第二个模块是说现在的神经网络所使用的词向量部分的内容。(内容过于简单,不多叙述)

    四、方法
    在这里插入图片描述
    还是很简单一目了然的,主要创新点在于词向量上做了两个手脚,这个点还是很创新的,这也是为什么全文重点在词向量上,但因为做nlp的对词向量比较熟悉,所以文章干货也不是很多。

    五、实验
    实验评价指标有问题,文章只是草草的说将输出层矩阵和数据集的矩阵进行了比较得出准确率,但是具体公示等等都没有。

    baseline模型有:
    SVM
    朴素贝叶斯
    随机森林
    决策树
    本文的两个模型。

    六、总结一下
    主要还是和传统模型进行对比。并且文章很大篇幅在说词向量的问题。实验部分的内容还是丰富的,但是模型的准确率的评价指标没有明确指出。与当前很多深度学习模型之间还是没有很多的对比。


    在这里插入图片描述
    一、introduction
    这是篇针对长文本的多标签文本分类问题。

    Binary relevance (BR) 方法是最早的一个方法,把多标签文本分类任务看作是由多个单分类文本分类任务的组合,其忽略标签与标签之间的依赖关系。
    Classifier chain (CC) 方法则包含了标签与标签间的依赖关系,其先把该任务看作是一系列的二分类问题,再通过模型来摸你标签与标签间的依赖关系。
    条件随机场CRF 方法和 conditional Bernoulli mixtures (CBF) 方法都是在处理标签依赖关系。
    但是上述方法只使用于小尺度的数据集,而非大尺度数据集。

    随后出现了CNN、RNN、DNN,以及叫做 Canonical Correlated AutoEncoder (C2AE) 等深度学习方法。
    但是其对标签中的依赖考虑还是不足,同时可解释性也不足。

    还有一些方法,比如seq2seq模型,LSTM,包括LSTM和seq2seq结合的方法,并加上注意力机制等方法。(该论文提出的模型即是基于seq2seq的,所以作者会有意识的去往seq2seq去引,并表现其优点)。

    论文中还提到了一个观点,对于多标签文本分类任务,之前有论文提到过,注意力机制不能够很好的在该任务中发挥作用。但是此论文作者指出,对于多标签文本分类任务,如果使用LSTM加上注意力,效果会没有别的模型好而已

    论文中又指出,局部信息是非常重要的(而他的模型即使用了局部信息)

    二、related work
    当前解决多标签文本分类任务,主要有三种:
    1.问题转化方法
    2.算法改进方法
    3.神经网络方法

    BR、label powerset(LP) 、CC方法都属于1
    ML-DT、Rank-SVM、KNN、CRF、CBM方法等都属于2
    CNN RNN LSTM seq2seq 包括一些结合的方法都属于3

    三、方法
    在这里插入图片描述
    非常清晰简单,直接看图。

    四、实验
    用了3个数据集进行了实验,其中一个数据集就是我之前项目中的知乎数据集,但是这里他对数据集进行了预处理,甚至说是进行了些挑选,这里我是很有疑惑的。

    评价指标真的非常赞!非常的清晰,可以算是一个范例了:
    Hamming Loss
    Micro-F1
    Micro-precision
    Micro-recall

    baseline模型既有传统的,也有ML的,也有NN的:
    BR
    CC
    LP
    CNN
    CNN-RNN
    S2S + Attn
    SGM
    MDC

    五、总结一下
    该论文的实验部分内容看起来怪少的,没有对实验内容进行了细致的分析。实际上,作者单独写了一个章节去进行更深入的分析,这是论文的精髓之处

    整篇论文对于相关工作等等方面的,叙述还是比较详细的。整个用神经网络去做多标签文本分类的各个方法以及类别等等分得比还是比较明确的同时实验部分的baseline以及整个实验设计,还是非常详细的,同时,对于数据所用的评价指标,也有详细的描述。对于实验部分的具体数据的分析,以及原理包括模型的挖掘,还是比较详细和深入的。但是整个有问题的话就是在知乎数据机上的数据使用问题,感觉有点问题。


    由于这两篇都是比较传统意义上的多标签文本分类,所以在此进行一些对比:
    在这里插入图片描述


    在这里插入图片描述
    这篇论文是19年CIKM上的一篇论文,刚刚的两篇论文对多标签文本分类任务的处理其实是比较传统,甚至说是easy点的,而多标签文本分类任务的痛点其实是在于层级标签的处理,这篇论文就是真正意义上的去处理层级多标签文本分类任务。

    摘要
    Hierarchical multi-label text classification (HMTC) 任务
    先前的很多方法都是直接处理所有的标签,或者是扁平化处理多标签文本分类问题,而忽略了标签的层级关系等,比如刚刚所提到的两篇论文。

    该论文的工作注意到 文本与层级结构之间的关系。
    首先对不同层级结构,自上而下的建模每一个level之间的依赖关系。
    然后提出了一个层级注意力策略去表示 文本与层级结构之间的关系(正如上面所提到的一样)
    最后提出了一个混合方法能够精准预测层级结构的每一个level。

    一、introduction
    扁平化的方法比如朴素贝叶斯被提出,但是该方法忽略了层级信息。

    为了考虑到层级结构,后续的方法大概可以分为两类:1.训练多个分类器,各负责各的层级分类任务。2.训练一个分类器,对全局进行分类预测。

    HMTC的挑战原因的具体分析主要有三点:
    1.文本与层级结构之间是有关联的
    2.层级结构中层与层之间也是有关联的
    3.不仅要关注局部信息,也要关注整个结构的信息。

    二、related work
    扁平化处理标签的方法比如决策树、朴素贝叶斯,但忽略了层级信息。
    还有些方法比如SVM等方法。
    然后是全局型的方法。
    最近则出现了很多神经网络的方法,比如HMC-LMLP方法
    还有一些混合方法。
    但论文指出,这些方法没有考虑到文本与层级结构之间的关联性。

    三、剩余内容没有多看了,和我目前任务有点偏离,所以做下总结:
    该论文的确是层级多标签文本分类,提出的模型也极其复杂,所用的baseline和平常见到的模型也不太一样,所以主要对我个人的帮助就在于相关工作部分的内容,但是相关工作部分的内容描述的也不是很清楚,所以就直接后面就都没看了。换了一篇更好的层级标签论文,并提出了一个新的小领域,下次组会再和大家分享。在这里插入图片描述
    上述PPT图片来自于天科大AI学院NLP组 组会PPT。

    展开全文
  • 基于LSTM的中文文本多分类实战

    万次阅读 多人点赞 2019-05-06 00:30:42
    在我之前的博客中我们介绍了文本多分类的方法,我们还尝试了各种分类模型,比如朴素贝叶斯、逻辑回归、支持向量机和随机森林等并且都取得了非常不错的效果。今天我们使用深度学习中的LSTM(Long Short-Term Memory)...

    在我之前的博客中我们介绍了文本的多分类的方法,我们还尝试了各种分类模型,比如朴素贝叶斯、逻辑回归、支持向量机和随机森林等并且都取得了非常不错的效果。今天我们使用深度学习中的LSTM(Long Short-Term Memory)长短期记忆网络,来尝试一下中文文本多分类,LSTM它是一种时间循环神经网络,适合于处理和预测时间序列中间隔和延迟相对较长的重要事件。
    LSTM 已经在科技领域有了多种应用。基于 LSTM 的系统可以学习翻译语言、控制机器人、图像分析、文档摘要、语音识别图像识别、手写识别、控制聊天机器人、预测疾病、点击率和股票、合成音乐等等任务。今天我们用它来实现一下文本多分类,相信会取得较好的效果。

    数据

    我们的数据来自于互联网,你可以在这里下载,数据中包含了10 个类别(书籍、平板、手机、水果、洗发水、热水器、蒙牛、衣服、计算机、酒店),共 6 万多条评论数据 首先查看一下我们的数据,这些数据都是来自于电商网站的用户评价数据,我们想要把不同评价数据分到不同的分类中去,且每条数据只能对应10个类中的一个类。

    df = pd.read_csv('./data/online_shopping_10_cats.csv')
    df=df[['cat','review']]
    print("数据总量: %d ." % len(df))
    df.sample(10)

    我们的数据有两个字段,其中cat字段表示类别,review表示用户的评价信息,数据总量为62774,且评价内容全部为中文。接下来我们要清洗掉数据中的空值。

    print("在 cat 列中总共有 %d 个空值." % df['cat'].isnull().sum())
    print("在 review 列中总共有 %d 个空值." % df['review'].isnull().sum())
    df[df.isnull().values==True]
    df = df[pd.notnull(df['review'])]
    

    还好只有一个空值,接下来我们统计一下各个类别的数据量

    d = {'cat':df['cat'].value_counts().index, 'count': df['cat'].value_counts()}
    df_cat = pd.DataFrame(data=d).reset_index(drop=True)
    df_cat

    我们看到各个类别的数据量不一致,洗发水、衣服、酒店、水果、平板的数据量最多各有1万条,而热水器的数据量最少只有574条,分布很不均匀,接下来我们用图形化的方式再查看一下各个类别的分布。

    df_cat.plot(x='cat', y='count', kind='bar', legend=False,  figsize=(8, 5))
    plt.title("类目分布")
    plt.ylabel('数量', fontsize=18)
    plt.xlabel('类目', fontsize=18)

    数据预处理 

     接下来我们要将cat类转换成id,这样便于以后的分类模型的训练。

    df['cat_id'] = df['cat'].factorize()[0]
    cat_id_df = df[['cat', 'cat_id']].drop_duplicates().sort_values('cat_id').reset_index(drop=True)
    cat_to_id = dict(cat_id_df.values)
    id_to_cat = dict(cat_id_df[['cat_id', 'cat']].values)
    df.sample(10)

    我们将cat转换成了Id(0到9),由于我们的评价内容都是中文,所以要对中文进行一些预处理工作,这包括删除文本中的标点符号,特殊符号,还要删除一些无意义的常用词(stopword),因为这些词和符号对系统分析预测文本的内容没有任何帮助,反而会增加计算的复杂度和增加系统开销,所有在使用这些文本数据之前必须要将它们清理干净。

    #定义删除除字母,数字,汉字以外的所有符号的函数
    def remove_punctuation(line):
        line = str(line)
        if line.strip()=='':
            return ''
        rule = re.compile(u"[^a-zA-Z0-9\u4E00-\u9FA5]")
        line = rule.sub('',line)
        return line
     
    def stopwordslist(filepath):  
        stopwords = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]  
        return stopwords  
    
    #加载停用词
    stopwords = stopwordslist("./data/chineseStopWords.txt")

     中文停用词包含了很多日常使用频率很高的常用词,如 吧,吗,呢,啥等一些感叹词等,这些高频常用词无法反应出文本的主要意思,所以要被过滤掉。可以在这里下载中文停用词。

    #删除除字母,数字,汉字以外的所有符号
    df['clean_review'] = df['review'].apply(remove_punctuation)
    df.sample(10)

     

     

    我们过滤掉了review中的标点符号和一些特殊符号,并生成了一个新的字段 clean_review。接下来我们要在clean_review的基础上进行分词,把每个评论内容分成由空格隔开的一个一个单独的词语。

    #分词,并过滤停用词
    df['cut_review'] = df['clean_review'].apply(lambda x: " ".join([w for w in list(jb.cut(x)) if w not in stopwords]))
    df.head()

    LSTM建模 

    数据预处理完成以后,接下来我们要开始进行LSTM的建模工作:

    • 我们要将cut_review数据进行向量化处理,我们要将每条cut_review转换成一个整数序列的向量
    • 设置最频繁使用的50000个词
    • 设置每条 cut_review最大的词语数为250个(超过的将会被截去,不足的将会被补0)
    # 设置最频繁使用的50000个词
    MAX_NB_WORDS = 50000
    # 每条cut_review最大的长度
    MAX_SEQUENCE_LENGTH = 250
    # 设置Embeddingceng层的维度
    EMBEDDING_DIM = 100
    
    tokenizer = Tokenizer(num_words=MAX_NB_WORDS, filters='!"#$%&()*+,-./:;<=>?@[\]^_`{|}~', lower=True)
    tokenizer.fit_on_texts(df['cut_review'].values)
    word_index = tokenizer.word_index
    print('共有 %s 个不相同的词语.' % len(word_index)

     

    X = tokenizer.texts_to_sequences(df['cut_review'].values)
    #填充X,让X的各个列的长度统一
    X = pad_sequences(X, maxlen=MAX_SEQUENCE_LENGTH)
    
    #多类标签的onehot展开
    Y = pd.get_dummies(df['cat_id']).values
    
    print(X.shape)
    print(Y.shape)

    下面我们要拆分训练集和测试集:

    #拆分训练集和测试集
    X_train, X_test, Y_train, Y_test = train_test_split(X,Y, test_size = 0.10, random_state = 42)
    print(X_train.shape,Y_train.shape)
    print(X_test.shape,Y_test.shape)

     

    训练和测试的数据集都准备好以后,接下来我们要定义一个LSTM的序列模型:

    • 模型的第一次是嵌入层(Embedding),它使用长度为100的向量来表示每一个词语
    • SpatialDropout1D层在训练中每次更新时, 将输入单元的按比率随机设置为 0, 这有助于防止过拟合
    • LSTM层包含100个记忆单元
    • 输出层为包含10个分类的全连接层
    • 由于是多分类,所以激活函数设置为'softmax'
    • 由于是多分类, 所以损失函数为分类交叉熵categorical_crossentropy
    #定义模型
    model = Sequential()
    model.add(Embedding(MAX_NB_WORDS, EMBEDDING_DIM, input_length=X.shape[1]))
    model.add(SpatialDropout1D(0.2))
    model.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))
    model.add(Dense(10, activation='softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    print(model.summary())

     定义好LSTM模型以后,我们要开始训练数据:

    • 设置5个训练周期
    • batch_size为64
    epochs = 5
    batch_size = 64
    
    history = model.fit(X_train, Y_train, epochs=epochs, batch_size=batch_size,validation_split=0.1,
                        callbacks=[EarlyStopping(monitor='val_loss', patience=3, min_delta=0.0001)])

     下面我们画损失函数趋势图和准确率趋势图:

    plt.title('Loss')
    plt.plot(history.history['loss'], label='train')
    plt.plot(history.history['val_loss'], label='test')
    plt.legend()
    plt.show();

    从上图中我们可以看见,随着训练周期的增加,模型在训练集中损失越来越小,这是典型的过拟合现象,而在测试集中, 损失随着训练周期的增加由一开始的从大逐步变小,再逐步变大。

    plt.title('Accuracy')
    plt.plot(history.history['acc'], label='train')
    plt.plot(history.history['val_acc'], label='test')
    plt.legend()
    plt.show();

    从上图中我们可以看见,随着训练周期的增加,模型在训练集中准确率越来越高,这是典型的过拟合现象,而在测试集中, 准确率随着训练周期的增加由一开始的从小逐步变大,再逐步变小。 

    LSTM模型的评估 

    接下来我们通过画混淆矩阵和求F1分数来评估我们模型的表现

    import seaborn as sns
    from sklearn.metrics import accuracy_score, confusion_matrix
    
    y_pred = model.predict(X_test)
    y_pred = y_pred.argmax(axis = 1)
    Y_test = Y_test.argmax(axis = 1)
    
    #生成混淆矩阵
    conf_mat = confusion_matrix(Y_test, y_pred)
    fig, ax = plt.subplots(figsize=(10,8))
    sns.heatmap(conf_mat, annot=True, fmt='d',
                xticklabels=cat_id_df.cat.values, yticklabels=cat_id_df.cat.values)
    plt.ylabel('实际结果',fontsize=18)
    plt.xlabel('预测结果',fontsize=18)

     

    混淆矩阵的主对角线表示预测正确的数量,除主对角线外其余都是预测错误的数量.从上面的混淆矩阵可以看出"蒙牛"类预测最准确,为100%。“平板”和“衣服”预测的错误数量教多。

     多分类模型一般不使用准确率(accuracy)来评估模型的质量,因为accuracy不能反应出每一个分类的准确性,因为当训练数据不平衡(有的类数据很多,有的类数据很少)时,accuracy不能反映出模型的实际预测精度,这时候我们就需要借助于F1分数、ROC等指标来评估模型。

    下面我们将查看各个类的F1分数.

    from  sklearn.metrics import classification_report
     
    print('accuracy %s' % accuracy_score(y_pred, Y_test))
    print(classification_report(Y_test, y_pred,target_names=cat_id_df['cat'].values))

     

    从以上F1分数上看,"蒙牛"类的F1分数最大(100%),“热水器”类F1分数最差只有67%,究其原因可能是因为“热水器”分类的训练数据最少只有574条,使得模型学习的不够充分,导致预测失误较多吧。

     总体而言,LSTM模型比之前我们使用支持向量机(LinearSVC)模型的效果要好一些,准确率提高了差不多2个百分点。不过LSTM模型的训练时间要比支持向量机模型要长一些,究竟孰好孰坏,请读者们亲身尝试一下吧。

    自定义预测

    首先我们定义一个预测函数:通过输入一段评语,来预测它的类目

    def predict(text):
        txt = remove_punctuation(text)
        txt = [" ".join([w for w in list(jb.cut(txt)) if w not in stopwords])]
        seq = tokenizer.texts_to_sequences(txt)
        padded = pad_sequences(seq, maxlen=MAX_SEQUENCE_LENGTH)
        pred = model.predict(padded)
        cat_id= pred.argmax(axis=1)[0]
        return cat_id_df[cat_id_df.cat_id==cat_id]['cat'].values[0]

    您可以在这里下载完整代码

    https://github.com/tongzm/ml-python/blob/master/%E5%9F%BA%E4%BA%8ELSTM%E7%9A%84%E4%B8%AD%E6%96%87%E6%96%87%E6%9C%AC%E5%A4%9A%E5%88%86%E7%B1%BB%E5%AE%9E%E6%88%98.ipynb

    如果喜欢我的博客,请朋友们点赞+关注我的博客,下面是我的微信,如果想交流数据科学相关问题,请加微信。

     

     

    展开全文
  • 文本分类标签分类

    千次阅读 2020-02-19 11:30:12
    标签分类综述 意义 网络新闻往往含有丰富的语义,一篇文章既可以属于“经济”也可以属于“文化”。给网络新闻打标签可以更好地反应文章的真实意义,方便日后的分类和使用。 难点 类标数量不确定,有些样本...

    多标签分类综述

    意义

    • 网络新闻往往含有丰富的语义,一篇文章既可以属于“经济”也可以属于“文化”。给网络新闻打多标签可以更好地反应文章的真实意义,方便日后的分类和使用。

    难点

    • 类标数量不确定,有些样本可能只有一个类标,有些样本的类标可能高达几十甚至上百个。 
    • 类标之间相互依赖,例如包含蓝天类标的样本很大概率上包含白云,如何解决类标之间的依赖性问题也是一大难点。
    • 多标签的训练集比较难以获取。

    如下方法来解决这个问题:

    1.在传统机器学习的模型中对每一类标签做二分类,可以使用SVM、DT、Naïve Bayes、DT、Xgboost等算法;在深度学习中,对每一类训练一个文本分类模型(如:textCNN、textRNN等)

    以上这种方法不能解决标签之间有关联的问题

    2.考虑多标签的相关性时候可以将上一个输出的标签当成是下一个标签分类器的输入。在传统机器学习模型中可以使用分类器链,在这种情况下,第一个分类器只在输入数据上进行训练,然后每个分类器都在输入空间和链上的所有之前的分类器上进行训练

    就是说训练第二个标签的分类模型时候,使用第一个分类模型的结果加入到特征之中

    3.重新定义类别,两个样本都有同样的标签例如(都是类别1和类别3)那么这两个样本就可以归为统一一个类别(一个新的类别)。

    4.深度学习输出层对每一个标签的输出值使用sigmod函数进行2分类,然后就可以进行多分类学习。

    开源fast-bert多标签文本分类算法

    kaggle多标签分类比赛开源代码

    多标签形象解释介绍

    讲解第四种方法

    展开全文
  • 文本分类(一) | (6) 多层双向LSTM

    千次阅读 2019-12-21 22:16:48
    对于输入文本序列,在LSTM的每个时间步输入序列中一个单词的嵌入表示,计算当前时间步的隐藏状态,用于当前时间步的输出以及传递给下一个时间步和下一 个单词的词向量一起作为LSTM单元输入,然后再计算下一个时间步...
  • 最近在重温bert,对bert的中文文本多分类的效果很好奇,并将其与传统的非pre-train模型进行对比,除此之外,由于选用的是12层的base版的bert,还从第0层开始到12层,对每一层的输出进行了校验和测试。想看看每一层的...
  • TextCNN进行文本分类多标签分类

    千次阅读 2020-03-20 17:32:59
    TextCNN ...提取码:zygc TextCNN是卷积神经网络的一种(其实就是一个简单的神经网络)。 卷积神经网络是指-至少在网络的...• 稀疏交互:不是每个输出单元与输入单元都产生交互 • 参数共享:个函数相同参数 • 等变表...
  • fastText原理和文本分类实战,看这一篇就够了

    万次阅读 多人点赞 2019-03-19 11:19:48
    fastText是一个快速文本分类算法,与基于神经网络的分类算法相比有两大优点: 1、fastText在保持高精度的情况下加快了训练速度和测试速度 2、fastText不需要预训练好的词向量,fastText会自己训练词向量 3、fastText...
  • 多标签文本分类多标签文本分类简介三种神经网络结构网络模型文本分类网络模型多标签文本分类网络模型 多标签文本分类简介 NLP(自然语言处理),即让计算机去理解人类的自然语言(文本、语音等),进而完成各种各样...
  • 文本分类概述(nlp)

    万次阅读 多人点赞 2018-06-22 23:28:27
    文本分类问题:给定文档p(可能含有标题t),将文档分类为n个类别中的一个或文本分类应用:常见的有垃圾邮件识别,情感分析 文本分类方向:主要有二分类多分类标签分类 文本分类方法:传统机器学习...
  • python 中文文本分类

    万次阅读 多人点赞 2017-02-06 11:31:21
    写这篇博文用了很时间和精力,如果这篇博文对你有帮助,希望您可以打赏给博主相国大人。哪怕只捐1毛钱,也是一种心意。通过这样的方式,也可以培养整个行业的知识产权意识。我可以和您建立更的联系,并且在相关...
  • CNN文本分类

    千次阅读 2018-09-20 08:33:46
    文本分类是NLP领域的一个重要的子任务,文本分类的目标是自动的将文本打上已经定义好的标签,常见的文本分类任务有:垃圾邮件过滤、情感分析、新闻分类等等。 代码是来自 ... 大家可以自行下载阅读,下面仅仅是自己对...
  • 文本分类

    千次阅读 2018-09-07 16:56:06
    一、传统文本分类方法  文本分类问题算是自然语言处理领域中一个非常经典的问题了,相关研究最早可以追溯到上世纪50年代,当时是通过专家规则(Pattern)进行分类,甚至在80年代初一度发展到利用知识工程建立专家...
  • TextCNN文本分类(keras实现)

    万次阅读 多人点赞 2019-03-26 19:23:46
    2、将文字转换成数字特征 3、将每条文本转换为数字列表 4、将每条文本设置为相同长度 5、将每个词编码转换为词向量 6、Keras文本预处理代码实现 三、基于keras的TextCNN模型的构建、训练与测试 1、基础版CNN...
  • # in_channels:输入的channel,文字都是1 # out_channels:输出的channel维度 # fs:每次滑动窗口计算用到几个单词,相当于n-gram中的n # for fs in filter_sizes用好几个卷积模型最后concate起来看效果。 ...
  • NLP之文本分类

    万次阅读 2018-09-26 15:08:07
    文本自动分类简称文本分类(text categorization),是模式识别与自然语言处理密切结合的研究课题。传统的文本分类是基于文本内容的,研究如何将文本自动划分成政治的、经济的、军事的、体育的、娱乐的等各种类型。 ...
  • 使用Pytorch和BERT进行标签文本分类

    千次阅读 2021-04-02 09:23:27
    NLP解决了分类、主题建模、文本生成、问答、推荐等业务问题。虽然TF/IDF矢量化或其他高级词嵌入(如GLOVE和Word2Vec)在此类NLP业务问题上表现出了良好的性能,但这些模型存在局限性就是使用一个向量对词进行编码而不...
  • 怎么将二分类模型应用到多分类问题 二分类模型数量众多,但实际应用中往往待预测类别数量不只有2个,于是有了一些将二分类模型应用到多分类的方法。 常见二分类模型 One-vs-Rest One-vs-One Directed Acyclic ...
  • 我们将开发一个文本分类模型,该模型可分析文本注释并预测与该注释关联的个标签。标签分类问题实际上是个输出模型的子集。在本文结尾,您将能够对数据执行标签文本分类。 数据集 数据集包含来自...
  • BERT文本分类实战

    千次阅读 2019-07-25 22:07:44
    本文介绍了基于Bert对文本分类任务进行了Fine-tune,详细介绍了如何使用bert对文本进行训练,完成了文本分类任务,从训练到预测的全教程。欢迎转载,转载请注明出处。
  • TensorFlow使用CNN实现中文文本分类

    万次阅读 多人点赞 2018-11-14 19:23:21
     读研期间使用过TensorFlow实现过简单的CNN情感分析(分类),当然这是比较low的二分类情况,后来进行多分类情况。但之前的学习基本上都是在英文词库上训练的。断断续续,想整理一下手头的项目资料,于是就拾起读研...
  • 本文提出的模型在一系列文本分类任务(如情感分析)中实现了良好的分类性能,并已成为新文本分类体系结构的标准基线。 我假设您已经熟悉应用于NLP的卷积神经网络的基础知识。如果没有,我建议首先阅读了解NLP的卷积...
  • 卷积神经网络文本分类

    万次阅读 2018-03-24 10:14:23
    前言 卷积神经网络(CNN)在图像...但 NLP 领域很方面使用 CNN 取得了出色的效果,比如语义分析、查询检索、文本分类等任务。这篇文章看看如何用 CNN 进行文本分类。 模型结构 模型结构可以通过下图一层层...
  • 用深度学习(CNN RNN Attention)解决大规模文本分类问题 - 综述和实践 近来在同时做一个应用深度学习解决淘宝商品的类目预测问题的项目,恰好硕士毕业时论文题目便是文本分类问题,趁此机会总结下文本分类领域特别...
  • 文本分类入门

    千次阅读 热门讨论 2012-03-04 02:08:57
    最近要做文本分类相关的课程project,因此上网找了一下文本分类的资料,下面这个感觉比较通俗易懂,收录在这里。 来源 http://www.blogjava.net/zhenandaci/category/31868.html?Show=All 文本分类入 门(一)文本...
  • 一、本文目的 关于如何训练词向量,如何将文本数据组织成Keras的要求,...而网上流传的利用Keras构建CNN文本分类模型中,filter size是固定的,因此本文就是要解决filter size变化的情况下的CNN文本分类模型。 二、...
  • 文本分类器设计

    千次阅读 2018-06-08 21:30:11
    文本分类的目的是将文本文档分为不同的类,这是NLP中非常重要的分析手段。这里将使用一种技术,它基于一种叫作tf-idf的统计数据,它表示词频逆文档频率(term frequency—inversedocument frequency)。这个统计...
  • 文本分类方向: 主要有二分类多分类标签分类 文本分类方法: 传统机器学习方法(贝叶斯,svm等),深度学习方法(fastText,TextCNN等) 文本分类的处理大致分为文本预处理、文本特征提取、分类模型构建等。.....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 209,439
精华内容 83,775
关键字:

多输入文本分类