dnn文本分类

简介

文本分类任务根据给定一条文本的内容,判断该文本所属的类别,是自然语言处理领域的一项重要的基础任务。具体的,本任务是对文本quey进行分类,任务流程如下:

  1. 收集用户query数据。
  2. 清洗,标记。
  3. 模型设计。
  4. 模型学习效果评估。

运行

训练: sh +x train.sh

预测: python infer.py

输入/输出

输入样本:

label text(分词后)

0 龙脉温泉 住宿 1 龙马 机场 飞机 2 龙里 旅游 其中,label 0,1和2分别代表:酒店,票务和住宿。

预估样本:

2 0.0002 0.0001 0.9997 港澳 7 日 自助游 label prob text 其中,label为概率最大的类别,即2旅游,中间三个数值为每个类别的概率。

DNN 模型

DNN 模型结构入下图所示:

图1. 本例中的 DNN 文本分类模型

在 PaddlePaddle 实现该 DNN 结构的代码见 network_conf.py 中的 fc_net 函数,模型主要分为如下几个部分:

  • 词向量层:为了更好地表示不同词之间语义上的关系,首先将词语转化为固定维度的向量。训练完成后,词与词语义上的相似程度可以用它们的词向量之间的距离来表示,语义上越相似,距离越近。关于词向量的更多信息请参考PaddleBook中的词向量一节。
  • 最大池化层:最大池化在时间序列上进行,池化过程消除了不同语料样本在单词数量多少上的差异,并提炼出词向量中每一下标位置上的最大值。经过池化后,词向量层输出的向量序列被转化为一条固定维度的向量。例如,假设最大池化前向量的序列为[[2,3,5],[7,3,6],[1,4,0]],则最大池化的结果为:[7,4,6]。
  • 全连接隐层:经过最大池化后的向量被送入两个连续的隐层,隐层之间为全连接结构。
  • 输出层:输出层的神经元数量和样本的类别数一致,例如在二分类问题中,输出层会有2个神经元。通过Softmax激活函数,输出结果是一个归一化的概率分布,和为1,因此第$i$个神经元的输出就可以认为是样本属于第$i$类的预测概率。

  该 DNN 模型默认对输入的语料进行二分类(class_dim=3),embedding(词向量)维度默认为28(emd_dim=28),两个隐层均使用Tanh激活函数(act=paddle.activation.Tanh())。需要注意的是,该模型的输入数据为整数序列,而不是原始的单词序列。事实上,为了处理方便,我们一般会事先将单词根据词频顺序进行 id 化,即将词语转化成在字典中的序号。

源码:

import sys
import math
import gzip

from paddle.v2.layer import parse_network
import paddle.v2 as paddle

__all__ = ["fc_net", "convolution_net"]

def fc_net(dict_dim,
           class_num,
           emb_dim=28,
           hidden_layer_sizes=[28, 8],
           is_infer=False):
    """
    define the topology of the dnn network
    :param dict_dim: size of word dictionary
    :type input_dim: int
    :params class_num: number of instance class
    :type class_num: int
    :params emb_dim: embedding vector dimension
    :type emb_dim: int
    """

    # define the input layers
    data = paddle.layer.data("word",
                             paddle.data_type.integer_value_sequence(dict_dim))
    if not is_infer:
        lbl = paddle.layer.data("label",
                                paddle.data_type.integer_value(class_num))

    # define the embedding layer
    emb = paddle.layer.embedding(input=data, size=emb_dim)
    # max pooling to reduce the input sequence into a vector (non-sequence)
    seq_pool = paddle.layer.pooling(
        input=emb, pooling_type=paddle.pooling.Max())

    for idx, hidden_size in enumerate(hidden_layer_sizes):
        hidden_init_std = 1.0 / math.sqrt(hidden_size)
        hidden = paddle.layer.fc(
            input=hidden if idx else seq_pool,
            size=hidden_size,
            act=paddle.activation.Tanh(),
            param_attr=paddle.attr.Param(initial_std=hidden_init_std))

    prob = paddle.layer.fc(
        input=hidden,
        size=class_num,
        act=paddle.activation.Softmax(),
        param_attr=paddle.attr.Param(initial_std=1.0 / math.sqrt(class_num)))

    if is_infer:
        return prob
    else:
        return paddle.layer.classification_cost(
            input=prob, label=lbl), prob, lbl

def convolution_net(dict_dim,
                    class_dim=2,
                    emb_dim=28,
                    hid_dim=128,
                    is_infer=False):
    """
    cnn network definition
    :param dict_dim: size of word dictionary
    :type input_dim: int
    :params class_dim: number of instance class
    :type class_dim: int
    :params emb_dim: embedding vector dimension
    :type emb_dim: int
    :params hid_dim: number of same size convolution kernels
    :type hid_dim: int
    """

    # input layers
    data = paddle.layer.data("word",
                             paddle.data_type.integer_value_sequence(dict_dim))
    lbl = paddle.layer.data("label", paddle.data_type.integer_value(class_dim))

    # embedding layer
    emb = paddle.layer.embedding(input=data, size=emb_dim)

    # convolution layers with max pooling
    conv_3 = paddle.networks.sequence_conv_pool(
        input=emb, context_len=3, hidden_size=hid_dim)
    conv_4 = paddle.networks.sequence_conv_pool(
        input=emb, context_len=4, hidden_size=hid_dim)

    # fc and output layer
    prob = paddle.layer.fc(
        input=[conv_3, conv_4], size=class_dim, act=paddle.activation.Softmax())

    if is_infer:
        return prob
    else:
        cost = paddle.layer.classification_cost(input=prob, label=lbl)

return cost, prob, lbl

运行结果如下图:

时间: 2024-10-10 13:58:53

dnn文本分类的相关文章

文本分类实战

文本分类实战 分类任务 算法流程 数据标注 特征抽取 特征选择 分类器 训练与评估 坑 分词 特征重要度 有偏训练集 模型大小优化 One More Thing… term 扩展 Distributed Representation 分类任务 其实工程上对于文本分类的需求还是挺多的,主要可以分为下面两类,并对每类给了两个例子. 二分类   色情新闻分类 这是一个非平衡数据集的二分类问题,因为色情新闻数是远小于非色情新闻数的.   判断是否医疗Query 这个就关系到搜索变现了,还记得莆田系”事件

Spark ML下实现的多分类adaboost+naivebayes算法在文本分类上的应用

1. Naive Bayes算法 朴素贝叶斯算法算是生成模型中一个最经典的分类算法之一了,常用的有Bernoulli和Multinomial两种.在文本分类上经常会用到这两种方法.在词袋模型中,对于一篇文档$d$中出现的词$w_0,w_1,...,w_n$, 这篇文章被分类为$c$的概率为$$p(c|w_0,w_1,...,w_n) = \frac{p(c,w_0,w_1,...,w_n)}{p(w_0,w_1,...,w_n)} = \frac{p(w_0,w_1,...,w_n|c)*p(c

LingPipe-TextClassification(文本分类)

What is Text Classification? Text classification typically involves assigning a document to a category by automated or human means. LingPipe provides a classification facility that takes examples of text classifications--typically generated by a huma

使用libsvm实现文本分类

文本分类,首先它是分类问题,应该对应着分类过程的两个重要的步骤,一个是使用训练数据集训练分类器,另一个就是使用测试数据集来评价分类器的分类精度.然而,作为文本分类,它还具有文本这样的约束,所以对于文本来说,需要额外的处理过程,我们结合使用libsvm从宏观上总结一下,基于libsvm实现文本分类实现的基本过程,如下所示: 选择文本训练数据集和测试数据集:训练集和测试集都是类标签已知的: 训练集文本预处理:这里主要包括分词.去停用词.建立词袋模型(倒排表): 选择文本分类使用的特征向量(词向量):

文本分类--多分类

文本分类算是自然语言处理领域最最常见的问题了,开源的工具也很好用,但是苦于训练速度缓慢,需要引进多核的版本,开源提供的多核支持参数有限,而同事提供的又有语言障碍,觉得自己探索下多分类器. 分类算法有很多,但是效果较好的基本就是LR和SVM,而这两个算法业内著名的开源代码应该就是liblinear和libsvm,libsvm支不支持多核暂时还未了解,但是liblinear支持的多核版本也就三组(0.2.11),正好避开了我需要用的那组参数,于是就摸索下liblinear的train代码. 一.先说

基于weka的文本分类实现

weka介绍 参见 1)百度百科:http://baike.baidu.com/link?url=V9GKiFxiAoFkaUvPULJ7gK_xoEDnSfUNR1woed0YTmo20Wjo0wYo7uff4mq_wg3WzKhTZx4Ok0JFgtiYY19U4q 2)weka官网: http://www.cs.waikato.ac.nz/ml/weka/ 简单文本分类实现: 此处文本为已处理好的文本向量空间模型,关于文本特征提取主要是基于TF-IDF算法对已分词文档进行特征抽取,然后基于

统计学习方法文本分类

一个文本分类问题就是将一篇文档归入预先定义的几个类别中的一个或几个,而文本的自动分类则是使用计算机程序来实现这样的分类.通俗点说,就好比你拿一篇文章,问计算机这文章要说的究竟是体育,经济还是教育,计算机答不上,说明计算机弱爆了就打它的屁屁. 注意这个定义当中着重强调的两个事实. 第一,用于分类所需要的类别体系是预先确定的.例如新浪新闻的分类体系,Yahoo!网页导航的分类层次.这种分类层次一旦确定,在相当长的时间内都是不可变的,或者即使要变更,也要付出相当大的代价(基本不亚于推倒并重建一个分类系

机器学习经典算法详解及Python实现---朴素贝叶斯分类及其在文本分类、垃圾邮件检测中的应用

摘要: 朴素贝叶斯分类是贝叶斯分类器的一种,贝叶斯分类算法是统计学的一种分类方法,利用概率统计知识进行分类,其分类原理就是利用贝叶斯公式根据某对象的先验概率计算出其后验概率(即该对象属于某一类的概率),然后选择具有最大后验概率的类作为该对象所属的类.总的来说:当样本特征个数较多或者特征之间相关性较大时,朴素贝叶斯分类效率比不上决策树模型:当各特征相关性较小时,朴素贝叶斯分类性能最为良好.另外朴素贝叶斯的计算过程类条件概率等计算彼此是独立的,因此特别适于分布式计算.本文详述了朴素贝叶斯分类的统计学

如何用机器学习对文本分类

需求 使用监督学习对历史数据训练生成模型,用于预测文本的类别. 样本清洗 主要将重复的数据删除掉,将错误无效的数据纠正或删除,并检查数据的一致性等.比如我认为长度小于少于13的数据是无效的遂将之删掉. def writeFile(text): file_object = open('result.txt','w') file_object.write(text) file_object.close() def clear(): text = "" file_obj = open(&qu