精华内容
下载资源
问答
  • TextCNN进行文本分类标签分类

    千次阅读 2020-03-20 17:32:59
    • 深层次抽取信息丰富 但是也存在如下缺点: • 数据量有要求 • 需要大量计算资源 : gpu • 难以直观解释 ** TextCNN与文本分类 ** 上图是TextCNN的结构模型,对于输入层来说可以有以下几种: • CNN-rand 设计...

    TextCNN

    数据集下载:链接:https://pan.baidu.com/s/14qRe9cxtSS51anKOcpy6dA
    提取码:zygc
    TextCNN是卷积神经网络的一种(其实就是一个简单的神经网络)。
    卷积神经网络是指-至少在网络的一层中使用了卷积运算代替矩阵乘法运算。其具有以下三个优点:
    • 稀疏交互:不是每个输出单元与输入单元都产生交互
    • 参数共享:多个函数相同参数
    • 等变表示:平移

    使用卷积神经网络进行自然语言处理有以下三个优点:
    • 共享卷积核 优化计算量
    • 无需手动选择特征
    • 深层次抽取信息丰富

    但是也存在如下缺点:
    • 对数据量有要求
    • 需要大量计算资源 : gpu
    • 难以直观解释
    **

    TextCNN与文本分类

    **
    在这里插入图片描述
    上图是TextCNN的结构模型,对于输入层来说可以有以下几种:
    • CNN-rand
    设计好 embedding_size 这个超参数后, 对不同单词的向量作随机初始化, 后续BP的时候作调整
    • CNN-Static
    拿 pre-trained vectors from word2vec, FastText or GloVe 直接用, 训练过程中不再调整词向量. 这也算是迁移学习的一种思想
    • CNN-non-static
    pre-trained vectors + fine tuning , 即拿word2vec训练好的词向量初始化, 训练过程中再对它们微调
    • CNN-multiple channel
    类比于图像中的RGB通道, 这里也可以用 static 与 non-static 搭两个通道来搞.
    在这里插入图片描述
    中间隐藏层一般都是选用不同size的卷积核(用来模拟单词之间的关系)然后接上全局平均池化,最后再接全连接层softmax进行分类。
    具体如下:
    Embedding:第一层是图中最左边的7乘5的句子矩阵,每行是词向量,维度=5,这个可以类比为图像中的原始像素点。
    Convolution:然后经过 kernel_sizes=(2,3,4) 的一维卷积层,每个kernel_size 有两个输出 channel。
    MaxPolling:第三层是一个1-max pooling层,这样不同长度句子经过pooling层之后都能变成定长的表示。
    FullConnection and Softmax:最后接一层全连接的 softmax 层,输出每个类别的概率。

    图像中可以利用 (R, G, B) 作为不同channel;
    文本的输入的channel通常是不同方式的embedding方式(比如 word2vec或Glove),实践中也有利用静态词向量和fine-tunning词向量作为不同channel的做法

    图像是二维数据;
    文本是一维数据,因此在TextCNN卷积用的是一维卷积(在word-level上是一维卷积;虽然文本经过词向量表达后是二维数据,但是在embedding-level上的二维卷积没有意义)。一维卷积带来的问题是需要通过设计不同 kernel_size 的 filter 获取不同宽度的视野。

    特征:这里用的是词向量表示方式
    数据量较大:可以直接随机初始化embeddings,然后基于语料通过训练模型网络来对embeddings进行更新和学习。
    数据量较小:可以利用外部语料来预训练(pre-train)词向量,然后输入到Embedding层,用预训练的词向量矩阵初始化embeddings。(通过设置weights=[embedding_matrix])。
    静态(static)方式:训练过程中不再更新embeddings。实质上属于迁移学习,特别是在目标领域数据量比较小的情况下,采用静态的词向量效果也不错。(通过设置trainable=False)
    非静态(non-static)方式:在训练过程中对embeddings进行更新和微调(fine tune),能加速收敛。(通过设置trainable=True)

    import os
    import re
    import sys
    import jieba
    import pandas as pd
    import numpy as np
    import tensorflow as tf
    root='路径'
    df = pd.read_csv(root,header=None).rename(columns={0:'label',1:'content'})
    def load_stop_words(stop_word_path):
        '''
        加载停用词
        :param stop_word_path:停用词路径
        :return: 停用词表 list
        '''
        # 打开文件
        file = open(stop_word_path, 'r', encoding='utf-8')
        # 读取所有行
        stop_words = file.readlines()
        # 去除每一个停用词前后 空格 换行符
        stop_words = [stop_word.strip() for stop_word in stop_words]
        return stop_words
    def clean_sentence(line):
        line = re.sub(
                "[a-zA-Z0-9]|[\s+\-\|\!\/\[\]\{\}_,.$%^*(+\"\')]+|[::+——()?【】《》“”!,。?、~@#¥%……&*()]+|题目", '',line)
        words = jieba.cut(line, cut_all=False)
        return words
    stopwords_path='路径'
    stop_words=load_stop_words(stopwords_path)
    
    def sentence_proc(sentence):
        '''
        预处理模块
        :param sentence:待处理字符串
        :return: 处理后的字符串
        '''
        # 清除无用词
        words = clean_sentence(sentence)
        # 过滤停用词
        words = [word for word in words if word not in stop_words]
        # 拼接成一个字符串,按空格分隔
        return ' '.join(words)
    
    def proc(df):
        df['content']=df['content'].apply(sentence_proc)
        return df
    df=proc(df)
    ***#Vocab***
    from tensorflow.keras.preprocessing.text import Tokenizer
    from tensorflow.keras.preprocessing.sequence import pad_sequences
    from sklearn.preprocessing import MultiLabelBinarizer
    vocab_size=30000
    padding_size=200
    text_preprocesser = Tokenizer(num_words=vocab_size, oov_token="<UNK>")
    text_preprocesser.fit_on_texts(df['content'])
    x = text_preprocesser.texts_to_sequences(df['content'])
    word_dict = text_preprocesser.word_index
    x = pad_sequences(x, maxlen=padding_size,padding='post', truncating='post')
    #多分类
    df['subject']=df['label'].apply(lambda x:x.split()[1])
    #进行one-hot编码
    from sklearn.preprocessing import LabelBinarizer
    lb=LabelBinarizer()
    lb.fit(df['subject'])
    y=lb.transform(df['subject'])
    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test=train_test_split(x,y,test_size=0.2,random_state=42)
    #构建模型
    import logging
    from tensorflow.keras import Input
    from tensorflow.keras.layers import Conv1D, MaxPool1D, Dense, Flatten, concatenate, Embedding
    from tensorflow.keras.models import Model
    from tensorflow.keras.utils import plot_model
    from tensorflow.keras.callbacks import EarlyStopping
    from pprint import pprint
    # from utils.metrics import micro_f1,macro_f1
    
    def TextCNN(max_sequence_length, max_token_num, embedding_dim, output_dim, model_img_path=None, embedding_matrix=None):
        """
        TextCNN: 
        1.embedding layers, 
        2.convolution layer, 
        3.max-pooling, 
        4.softmax layer. 
        """
        
        x_input = Input(shape=(max_sequence_length,))
        logging.info("x_input.shape: %s" % str(x_input.shape))  # (?, 60)
    
        if embedding_matrix is None:
            x_emb = Embedding(input_dim=max_token_num, output_dim=embedding_dim, input_length=max_sequence_length)(x_input)
        else:
            x_emb = Embedding(input_dim=max_token_num, output_dim=embedding_dim, input_length=max_sequence_length,
                              weights=[embedding_matrix], trainable=True)(x_input)
        
        logging.info("x_emb.shape: %s" % str(x_emb.shape))  # (?, 60, 300)
    
        pool_output = []
        kernel_sizes = [2, 3, 4] 
        for kernel_size in kernel_sizes:
            c = Conv1D(filters=2, kernel_size=kernel_size, strides=1)(x_emb)
            p = MaxPool1D(pool_size=int(c.shape[1]))(c)
            pool_output.append(p)
            logging.info("kernel_size: %s \t c.shape: %s \t p.shape: %s" % (kernel_size, str(c.shape), str(p.shape)))
        
        pool_output = concatenate([p for p in pool_output])
        logging.info("pool_output.shape: %s" % str(pool_output.shape))  # (?, 1, 6)
    
        x_flatten = Flatten()(pool_output)  # (?, 6)
        y = Dense(output_dim, activation='softmax')(x_flatten)  # (?, 2)
        
        logging.info("y.shape: %s \n" % str(y.shape))
    
        model = Model([x_input], outputs=[y])
        
        if model_img_path:
            plot_model(model, to_file=model_img_path, show_shapes=True, show_layer_names=False)
        model.summary()
        
        return model
     #设置参数
    feature_size=padding_size
    embed_size=300
    num_classes=len(y[0])
    filter_sizes='3,4,5'
    dropout_rate=0.5
    regularizers_lambda=0.01
    learning_rate=0.01
    batch_size=512
    epochs=5
    model=TextCNN(max_sequence_length=feature_size, max_token_num=vocab_size, embedding_dim=embed_size, output_dim=num_classes)
    model.compile(tf.optimizers.Adam(learning_rate=learning_rate), 
                  loss='categorical_crossentropy',
                  metrics=[micro_f1, macro_f1])
    
    #训练
    early_stopping = EarlyStopping(monitor='val_micro_f1', patience=10, mode='max')
    
    history = model.fit(X_train, y_train,
              batch_size=batch_size,
              epochs=epochs,
              workers=32,
              use_multiprocessing=True,
              callbacks=[early_stopping],
              validation_data=(X_test, y_test))
    
    #预测
    y_pred=model.predict(X_test)
    y_pred=np.argmax(y_pred,axis=1)
    y_true=np.argmax(y_test,axis=1)
    print(classification_report(y_true,y_pred))
    
    

    所得到的结果如下图所示:
    在这里插入图片描述
    在这里插入图片描述
    #训练的结果还不错,但这只是四分类,比较简单。。
    在这里插入图片描述
    在这里插入图片描述
    如果进行多标签分类,需要修改上面的one-hot编码形式(改成多标签的形式),主干不变,将分类数改成你想分类的个数就可以了。

    展开全文
  • 使用Pytorch和BERT进行标签文本分类

    千次阅读 2021-04-02 09:23:27
    虽然TF/IDF矢量化或其他高级词嵌入(如GLOVE和Word2Vec)在此类NLP业务问题上表现出了良好的性能,但这些模型存在局限性就是使用一个向量进行编码而不考虑上下文的不同含义。因此,当试图解决理解用户意图所需的...

    介绍

    自然语言处理(NLP)是一种将非结构化文本处理成有意义的知识的人工智能技术。NLP解决了分类、主题建模、文本生成、问答、推荐等业务问题。虽然TF/IDF矢量化或其他高级词嵌入(如GLOVE和Word2Vec)在此类NLP业务问题上表现出了良好的性能,但这些模型存在局限性就是使用一个向量对词进行编码而不考虑上下文的不同含义。因此,当试图解决理解用户意图所需的问题时,这些模型可能不能很好地执行。一个例子是,当用户与自动聊天机器人交互时,它试图理解用户查询的意图并准确地提供响应。

    对于这种情况,NLP中的另一个例子是从下面两个句子中解码上下文意义。

    1. A thieve robbed a bank.

    2. He went to river bank.

    从以上两种表述中,人们很容易就能看出“bank”有两种不同的含义;然而,机器不能区分,因为上面提到的词嵌入使用相同的标记“bank”,而不管他们的上下文意义。为了克服这一挑战,谷歌从Transformers (BERT)模型开发了最先进的双向编码器表示。

    BERT是什么?

    BERT是在8亿单词的图书语料库和2500万单词的英语维基百科上训练的预训练模型。在BERT中,“bank”将有两个不同的含义,因为它们的上下文差异。在保持NLP任务的高性能的同时并不会降低模型构建的训练时间。并且可以从BERT中提取新的语言特征用于模型预测。与RNN、LSTM、CNN等深度学习模型相比,BERT的发展速度要快得多。作为高层次的理解,BERT有两种不同的架构变体:BERT base和BERT large。第一个变型有12个Transformers 块,12个注意头,1.1亿参数,后一个变型有24个Transformers ,16个注意头,3.4亿参数。它在使用过程中完成了两个NLP的任务:遮蔽语言建模和下一句预测。

    数据集

    从此处(https://datahack.analyticsvidhya.com/contest/janatahack-independence-day-2020-ml-hackathon/#ProblemStatement)获取数据集,该数据集可用于研究论文的主题建模的多标签分类对比。 对比的目的是从大型的科学文章在线存档中尽可能地容易找到相关的文章。 我选择此数据集的原因是,尽管有许多关于二进制分类的Twitter情绪讨论BERT和Pytorch的文章,但很少找到有关处理多类问题的。 并且有很多共享代码可能无法正常工作。

    查看如下的代码我建议具备python,NLP,深度学习和Pytorch框架的基础知识。 必须使用Google帐户才能使用Google Colab帐户。

    处理数据的方法

    在传统的NLP机器学习问题中,我们倾向于清除不需要的文本,例如删除停用词,标点符号,删除符号和数字等。但是,在BERT中,不需要执行此类预处理任务,因为BERT使用了这些 单词的顺序和位置,以了解用户输入的意图。

    ML / DL工程师应该从不同方面探索数据集,以真正了解他们手中的数据类型,这是一个好习惯。 NLP的典型功能是单词计数,动词计数,形容词计数,数字计数,标点符号计数,双字母组计数,三字组计数等。 为简便起见,我已展示了如何对单词计数列进行计数,其中单个标题中使用的总单词数将被计算在内。 您可能还需要处理类似于TITLE的Abstract列,以及ABSTRACT和TITLE的组合。

    下面的命令创建“ WORD_COUNT”列。

    df_raw['WORD_COUNT'] = df_raw['TITLE'].apply(lambda x: len(x.split())
    

    这将生成“ WORD_COUNT”的分布图,即标题的长度。

    如您所见,文章标题的大部分以10个单词为中心,这是预期的结果,因为TITLE应该简短,简洁且有意义。

    由于我将仅使用“ TITLE”和“ target_list”,因此我创建了一个名为df2的新数据框。 df2.head()命令显示训练数据集中的前五个记录。 如您所见,两个目标标签被标记到最后的记录,这就是为什么这种问题称为多标签分类问题的原因。

    df2 = df_raw[['TITLE', 'target_list']].copy()
    
    df2.head()
    

    同时,设置将用于模型训练的参数。 由于我更喜欢使用2*base数字,因此最大长度设置为16,这涵盖了大部分“ TITLE”长度。 训练和有效批处理大小设置为32。epoch为4,因为它很容易在几个epoch上过度拟合。 我从lr=0.00001开始学习。 您可以随意尝试不同的值以提高准确性。

    # Sections of config
    # Defining some key variables that will be used later on in the training
    MAX_LEN = 16
    TRAIN_BATCH_SIZE = 32
    VALID_BATCH_SIZE = 32
    EPOCHS = 4
    LEARNING_RATE = 1e-05
    tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
    

    让我们创建一个称为“ CustomDataset”的通用类。 Class从我们的原始输入特征生成张量,并且Pytorch张量可以接受class的输出。 它期望具有上面定义的“ TITLE”,“ target_list”,max_len,并使用BERT toknizer.encode_plus函数将输入设置为数字矢量格式,然后转换为张量格式返回。

    class CustomDataset(Dataset):
        def __init__(self, dataframe, tokenizer, max_len):
            self.tokenizer = tokenizer
            self.data = dataframe
            self.title = dataframe['TITLE']
            self.targets = self.data.target_list
            self.max_len = max_len
    
        def __len__(self):
            return len(self.title)
    
    
    
        def __getitem__(self, index):
            title = str(self.title[index])
            title = " ".join(title.split())
    
            inputs = self.tokenizer.encode_plus(
                title,
                None,
                add_special_tokens=True,
                max_length=self.max_len,
                padding='max_length',
                return_token_type_ids=True,
                truncation=True
    
            )
    
            ids = inputs['input_ids']
            mask = inputs['attention_mask']
            token_type_ids = inputs["token_type_ids"]
            return {
                'ids': torch.tensor(ids, dtype=torch.long),
                'mask': torch.tensor(mask, dtype=torch.long),
                'token_type_ids': torch.tensor(token_type_ids, dtype=torch.long),
                'targets': torch.tensor(self.targets[index], dtype=torch.float)
    
            }
    

    数据集的80%用于模型训练,而20%用于验证。 测试数据集完全用于测试目的。

    train_size = 0.8
    train_dataset = df2.sample(frac=train_size,random_state=200)
    valid_dataset = df2.drop(train_dataset.index).reset_index(drop=True)
    train_dataset = train_dataset.reset_index(drop=True)
    
    
    print("FULL Dataset: {}".format(df2.shape))
    print("TRAIN Dataset: {}".format(train_dataset.shape))
    print("TEST Dataset: {}".format(valid_dataset.shape))
    
    
    training_set = CustomDataset(train_dataset, tokenizer, MAX_LEN)
    validation_set = CustomDataset(valid_dataset, tokenizer, MAX_LEN)
    

    我们已经讨论了将张量准备为输入特征的大部分基础工作。 现在,构建BERT模型很容易。 由于来自模型的冗长输出,我已简化为仅显示模型。 我已使用dropout 0.3来随机减少特征,以最大程度地减少第2层的过拟合。第3层采用了768维特征,这些特征是从使用BERT的第2层输出的。 它返回6个特征,这是对目标列表的最终预测。

    class BERTClass(torch.nn.Module):
        def __init__(self):
            super(BERTClass, self).__init__()
            self.l1 = transformers.BertModel.from_pretrained('bert-base-uncased')
            self.l2 = torch.nn.Dropout(0.3)
            self.l3 = torch.nn.Linear(768, 6)
    
        def forward(self, ids, mask, token_type_ids):
            _, output_1= self.l1(ids, attention_mask = mask, token_type_ids = token_type_ids)
            output_2 = self.l2(output_1)
            output = self.l3(output_2)
            return output
    
    model = BERTClass()
    model.to(device)
    

    BCE损失函数用于找出模型预测值与实际目标值之间的误差。 使用Adam优化器。 损失功能请参见下文。

    def loss_fn(outputs, targets):
        return torch.nn.BCEWithLogitsLoss()(outputs, targets)
    
    optimizer = torch.optim.Adam(params =  model.parameters(), lr=LEARNING_RATE)
    

    同时我还创建了检查点,可以在训练期间保存最佳模型。 当需要从停下来的地方继续训练时,这将有助于减少训练时间。 创建检查点可以节省时间,以便从头开始进行重新训练。 如果您对从最佳模型生成的输出感到满意,则不需要进一步的微调,则可以使用模型进行推断。

    def load_ckp(checkpoint_fpath, model, optimizer):
    
        """
        checkpoint_path: path to save checkpoint
        model: model that we want to load checkpoint parameters into       
        optimizer: optimizer we defined in previous training
    
        """
        # load check point
        checkpoint = torch.load(checkpoint_fpath)
        # initialize state_dict from checkpoint to model
        model.load_state_dict(checkpoint['state_dict'])
        # initialize optimizer from checkpoint to optimizer
        optimizer.load_state_dict(checkpoint['optimizer'])
        # initialize valid_loss_min from checkpoint to valid_loss_min
        valid_loss_min = checkpoint['valid_loss_min']
        # return model, optimizer, epoch value, min validation loss 
        return model, optimizer, checkpoint['epoch'], valid_loss_min.item()
    import shutil, sys   
    
    def save_ckp(state, is_best, checkpoint_path, best_model_path):
    
        """
        state: checkpoint we want to save
        is_best: is this the best checkpoint; min validation loss
        checkpoint_path: path to save checkpoint
        best_model_path: path to save best model
        """
        f_path = checkpoint_path
        # save checkpoint data to the path given, checkpoint_path
        torch.save(state, f_path)
        # if it is a best model, min validation loss
        if is_best:
            best_fpath = best_model_path
            # copy that checkpoint file to best path given, best_model_path
            shutil.copyfile(f_path, best_fpath)
    def train_model(start_epochs,  n_epochs, valid_loss_min_input, 
                    training_loader, validation_loader, model, 
                    optimizer, checkpoint_path, best_model_path):
    
      # initialize tracker for minimum validation loss
      valid_loss_min = valid_loss_min_input 
      for epoch in range(start_epochs, n_epochs+1):
        train_loss = 0
        valid_loss = 0
        model.train()
        print('############# Epoch {}: Training Start   #############'.format(epoch))
        for batch_idx, data in enumerate(training_loader):
            #print('yyy epoch', batch_idx)
            ids = data['ids'].to(device, dtype = torch.long)
            mask = data['mask'].to(device, dtype = torch.long)
            token_type_ids = data['token_type_ids'].to(device, dtype = torch.long)
            targets = data['targets'].to(device, dtype = torch.float)
            outputs = model(ids, mask, token_type_ids)
            optimizer.zero_grad()
            loss = loss_fn(outputs, targets)
            #if batch_idx%5000==0:
             #   print(f'Epoch: {epoch}, Training Loss:  {loss.item()}')
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            #print('before loss data in training', loss.item(), train_loss)
            train_loss = train_loss + ((1 / (batch_idx + 1)) * (loss.item() - train_loss))
            #print('after loss data in training', loss.item(), train_loss)
        print('############# Epoch {}: Training End     #############'.format(epoch))
        print('############# Epoch {}: Validation Start   #############'.format(epoch))
        ######################    
        # validate the model #
        ######################
        model.eval()
        with torch.no_grad():
          for batch_idx, data in enumerate(validation_loader, 0):
                ids = data['ids'].to(device, dtype = torch.long)
                mask = data['mask'].to(device, dtype = torch.long)
                token_type_ids = data['token_type_ids'].to(device, dtype = torch.long)
                targets = data['targets'].to(device, dtype = torch.float)
                outputs = model(ids, mask, token_type_ids)
                loss = loss_fn(outputs, targets)
                valid_loss = valid_loss + ((1 / (batch_idx + 1)) * (loss.item() - valid_loss))
                val_targets.extend(targets.cpu().detach().numpy().tolist())
                val_outputs.extend(torch.sigmoid(outputs).cpu().detach().numpy().tolist())
    
          print('############# Epoch {}: Validation End     #############'.format(epoch))
          # calculate average losses
          #print('before cal avg train loss', train_loss)
          train_loss = train_loss/len(training_loader)
          valid_loss = valid_loss/len(validation_loader)
          # print training/validation statistics 
          print('Epoch: {} \tAvgerage Training Loss: {:.6f} \tAverage Validation Loss: {:.6f}'.format(
                epoch, 
                train_loss,
                valid_loss
                ))
          # create checkpoint variable and add important data
          checkpoint = {
                'epoch': epoch + 1,
                'valid_loss_min': valid_loss,
                'state_dict': model.state_dict(),
                'optimizer': optimizer.state_dict()
          }
    
            # save checkpoint
          save_ckp(checkpoint, False, checkpoint_path, best_model_path)
          ## TODO: save the model if validation loss has decreased
          if valid_loss <= valid_loss_min:
            print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(valid_loss_min,valid_loss))
            # save checkpoint as best model
            save_ckp(checkpoint, True, checkpoint_path, best_model_path)
            valid_loss_min = valid_loss
        print('############# Epoch {}  Done   #############\n'.format(epoch))
      return model
    

    “train_model”被创建来训练模型,“checkpoint_path”是训练模型的参数将被保存为每个epoch,“best_model”是最好的模型将被保存的地方。

    checkpoint_path = '/content/drive/My Drive/NLP/ResearchArticlesClassification/checkpoint/current_checkpoint.pt'
    
    best_model = '/content/drive/My Drive/NLP/ResearchArticlesClassification/best_model/best_model.pt'
    
    trained_model = train_model(1, 4, np.Inf, training_loader, validation_loader, model, 
                          optimizer,checkpoint_path,best_model)
    

    训练结果如下:

    ############# Epoch 1: Training Start   #############
    ############# Epoch 1: Training End     #############
    ############# Epoch 1: Validation Start   #############
    ############# Epoch 1: Validation End     #############
    Epoch: 1 	Avgerage Training Loss: 0.000347 	Average Validation Loss: 0.001765
    Validation loss decreased (inf --> 0.001765).  Saving model ...
    ############# Epoch 1  Done   #############
    
    ############# Epoch 2: Training Start   #############
    ############# Epoch 2: Training End     #############
    ############# Epoch 2: Validation Start   #############
    ############# Epoch 2: Validation End     #############
    Epoch: 2 	Avgerage Training Loss: 0.000301 	Average Validation Loss: 0.001831
    ############# Epoch 2  Done   #############
    
    ############# Epoch 3: Training Start   #############
    ############# Epoch 3: Training End     #############
    ############# Epoch 3: Validation Start   #############
    ############# Epoch 3: Validation End     #############
    Epoch: 3 	Avgerage Training Loss: 0.000263 	Average Validation Loss: 0.001896
    ############# Epoch 3  Done   #############
    
    ############# Epoch 4: Training Start   #############
    ############# Epoch 4: Training End     #############
    ############# Epoch 4: Validation Start   #############
    ############# Epoch 4: Validation End     #############
    Epoch: 4 	Avgerage Training Loss: 0.000228 	Average Validation Loss: 0.002048
    ############# Epoch 4  Done   #############
    

    因为我只执行了4个epoch,所以完成得很快,我将threshold设置为0.5。你可以试试这个阈值,看看是否能提高结果。

    val_preds = (np.array(val_outputs) > 0.5).astype(int)
    val_preds
    array([[0, 0, 1, 0, 0, 0],
           [0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 0],
           ...,
           [0, 0, 1, 0, 0, 0],
           [0, 1, 0, 0, 0, 0],
           [1, 0, 0, 0, 0, 0]])
    

    让我们将精确度和F1得分定义为模型性能的指标。F1将被用于评估。

    accuracy = metrics.accuracy_score(val_targets, val_preds)
    f1_score_micro = metrics.f1_score(val_targets, val_preds, average='micro')
    f1_score_macro = metrics.f1_score(val_targets, val_preds, average='macro')
    print(f"Accuracy Score = {accuracy}")
    print(f"F1 Score (Micro) = {f1_score_micro}")
    print(f"F1 Score (Macro) = {f1_score_macro}")
    

    使用混淆矩阵和分类报告,以可视化我们的模型如何正确/不正确地预测每个单独的目标。

    from sklearn.metrics import multilabel_confusion_matrix as mcm, classification_report
    cm_labels = ['Computer Science', 'Physics', 'Mathematics',
           'Statistics', 'Quantitative Biology', 'Quantitative Finance']
    cm = mcm(val_targets, val_preds)
    print(classification_report(val_targets, val_preds))
    

    模型预测的准确率为76%。F1得分低的原因是有六个类的预测,通过结合“TITLE”和“ABSTRACT”或者只使用“ABSTRACT”来训练可以提高它。我对这两个案例都进行了训练,发现“ABSTRACT”特征本身的F1分数比标题和标题与抽象相结合要好得多。在没有进行超参数优化的情况下,我使用测试数据进行推理,并在private score中获得0.82分。

    有一些事情可以做,以提高F1成绩。一个是微调模型的超参数,你可能想要实验改变学习速率,退出率和时代的数量。在对模型微调的结果满意之后,我们可以使用整个训练数据集,而不是分成训练和验证集,因为训练模型已经看到了所有可能的场景,使模型更好地执行。

    你可以在谷歌Colab查看这个项目源代码

    https://colab.research.google.com/drive/1SPxxEW9okgnbMdk1ORlfSQI4rjV2tVW_#scrollTo=EJQRHd7VVMap

    作者:Kyawkhaung

    deephub翻译组

    展开全文
  • 上一篇博客中我们已经总结了文本分类中常用的深度学习模型,因为知乎的本次竞赛是多标签文本分类任务,这也是我第一次接触多标签分类,所以想单独写一篇博客来记录这方面的相关知识。

    上一篇博客中我们已经总结了文本分类中常用的深度学习模型,因为知乎的本次竞赛是多标签的文本分类任务,这也是我第一次接触多标签分类,所以想单独写一篇博客来记录这方面的相关知识。
    在这里首先列出几篇参考的文章:

    1. 基于神经网络的多标签分类可以追溯到周志华在2006年发表的文章: Multi-Label Neural Networks with Applications to Functional Genomics and Text Categorization。其贡献在于提出了BP-MLL(多标签反向传播)以及新的误差函数:
      这里写图片描述

    2. 然后是一篇基于周志华文章改进的论文:Large-scale Multi-label Text Classification Revisiting Neural Networks。这篇文章提出使用Adagrad,dropout等技术,此外还提出使用标准的交叉熵函数作为目标函数效果更好。

    3. 上面的文章还是使用普通的神经网络进行分类,接下来就出现了基于深度学习模型的方法。比如:Large Scale Multi-label Text Classification with Semantic Word Vectors。这篇文章很简单,就是把TextCNN和GRU直接用到多标签文本分类里,最后根据一个阈值alpha来确定样本是否属于某个类别。

    4. Improved Neural Network-based Multi-label Classification with Better Initialization Leveraging Label Co-occurrence。这篇文章提出了一种根据类别标签之间的共现关系来初始化最后输出层参数的方法。其也是基于TextCNN,不同之处是最后一个输出层的权重不使用随机初始化,而是根据标签之间的共现关系进行初始化。据作者说这样可以获得标签之间的关系,这样有一种聚类的效果。相似的样本会标记为相同的标签。此外他还提出了损失函数的计算方法。具体的细节部分可以去看相关论文。
      这里写图片描述这里写图片描述

    5. 模型上的改进:Ensemble Application of Convolutional and Recurrent Neural Networks for Multi-label Text Categorization。这篇论文主要提出了一种CNN和RNN融合的机制,将CNN的输出作为RNN的初始状态然后进行类别的预测。架构图如下所示:
      这里写图片描述

    上面几篇论文是我在做竞赛的过程中阅读的几篇相关论文,每篇都会有一定的特点,但是实际的效果如何其实并不会像论文中提到的那样,也有可能是自己调参跳的不好。但是论文里面提到的创新点还是值得我们学习的。然后我们来总结一下多标签文本分类相关的东西,这里参考上面第三篇论文。首先来讲,多标签分类的算法可以分成下面三种类型:

    1. multi-label classification:将标签分成Y和Y的补集两个分区
    2. label ranking:将标签进行排序,排名靠前的就是预测为相关的类别
    3. multi-label ranking:上述二者的综合,同时产生分区和rank。设置阈值函数进行判断

    此外,我们还可以使用Binary Relevance(BR)算法,将多标签问题转化为L个二分类问题。训练L个模型,每个模型处理一个类别,这样做的好处是可以并行训练L个模型,降低训练复杂度,而且可以方便的增删标签数量。最终只需要把结果合并成一个输出向量就可以了。但是也有一点的缺点,比如说由于分开训练L个模型,所以忽视了标签之间的相关性。而且当当数据集出现类别不均衡等现象时,效果也会变差。

    上面说了几种如何看待多标签分类问题的思路和看法。其实就是将多标签分类进行转化。我感觉比较常用的应该是ranking和BR的方法。再反过来看这次知乎的竞赛,其实我看了前几名的解决方案,大都是只用了深度学习模型的堆砌,比如说CNN,RNN然后再加上模型融合和数据增强的一些手段得到了比较好的分数。但是我之前也采访过知乎机器学习团队的负责人,他当时也明确的表明现在选手使用的方法还都是比较老派,没有什么十分大的创新点出来,而且几乎没怎么利用标签之间的关系等信息。这里我就说一下我在竞赛里面做过的几种尝试。

    1,首先来分析一下知乎所提供的数据都有哪些特点,第一给了1999个标签之间的父子关系,这样我们就可以将其构成一张树状关系图。

    2,其次他给出了每个label的描述信息,我觉得这个信息是最重要的,因为这样我们最简单也可以计算样本和1999个标签之间的相似性然后排名取出前5个就可以粗略地进行类别标注。当然我们在结合深度学习的时候可以将其放在最后一层跟CNN的输出进行结合计算。我当时采用的方法是,将样本和1999个标签的title分别经过CNN进行计算,然后再将得到的文本表示和标签信息进行一个相似性计算得到每个类别的相似性概率表示。但是这种方法的缺点在于速度太慢,我当时训练了一天两夜才跑了2个epoch(CPU),所以中途放弃了,至今也不知道效果如何==

    3,使用上面第四篇文献中所提出的方法,首先对数据进行预处理,得到所有训练数据中所出现的标签共现信息,取共现次数最高的前N个标签对作为初始化的依据。该模型的想法是通过这种自定义初始化网络权重的方法让模型学习到这种标签的共现信息,从而更加准确地进行类别预测。

    4,在查阅文献的过程中,看到了一篇“Multi-Label Classification on Tree- and DAG-Structured Hierarchies”的论文,其提出将标签信息构建成有向无环图或者树状的分层结构。但是该方法是基于传统机器学习模型做的,由于竞赛过程中时间有限,所以并未加以尝试。此外,我还考虑是否可以将标签信息使用类似于word2vec中的分层softmax的机制进行处理。总之是尽量的把标签之间的父子关系图利用起来,以增强分类的准确度。这里也不过是一些自己的想法罢了,还并未进行实践,也希望有懂这方面知识的同学可以指点一二。

    至此,关于多标签文本分类相关的知识就暂时总结到这里,其实也就是看的几篇论文和知乎竞赛中的一些思考。接下来抽时间把自己参加竞赛的一些具体的代码等再整理出一篇博客就将完结这个系列。

    展开全文
  • NLP(二十八)多标签文本分类

    千次阅读 热门讨论 2020-04-10 10:49:43
    标签文本分类之从电影简介预测影片类型

      本文将会讲述如何实现多标签文本分类。

    什么是多标签分类?

      在分类问题中,我们已经接触过二分类和多分类问题了。所谓二(多)分类问题,指的是y值一共有两(多)个类别,每个样本的y值只能属于其中的一个类别。对于多标签问题而言,每个样本的y值可能不仅仅属于一个类别。
      举个简单的例子,我们平时在给新闻贴标签的时候,就有可能把一篇文章分为经济和文化两个类别。因此,多标签问题在我们的日常生活中也是很常见的。
      对于多标签问题,业界还没有很成熟的解决方法,主要是因为标签之间可能会存在复杂的依赖关系,这种依赖关系现阶段还没有成熟的模型来解决。我们在解决多标签问题的时候,一种办法是认为标签之间互相独立,然后把该问题转化为我们熟悉的二(多)分类问题。
      本文以 2020语言与智能技术竞赛:事件抽取任务 中的数据作为多分类标签的样例数据,借助多标签分类模型来解决。
      整个项目的结构如下图所示:
    项目结构图
      首先,让我们来看一下样例数据。

    数据分析

      首先,让我们来看一下样例数据的几个例子:

    司法行为-起诉|组织关系-裁员 最近,一位前便利蜂员工就因公司违规裁员,将便利蜂所在的公司虫极科技(北京)有限公司告上法庭。
    组织关系-裁员 思科上海大规模裁员人均可获赔100万官方澄清事实
    组织关系-裁员 日本巨头面临危机,已裁员1000多人,苹果也救不了它!
    组织关系-裁员|组织关系-解散 在硅谷镀金失败的造车新势力们:蔚来裁员、奇点被偷窃、拜腾解散

    从上面的例子中我们可以看出,同样的描述文本,有可能会属于多个事件类型。比如上面的在硅谷镀金失败的造车新势力们:蔚来裁员、奇点被偷窃、拜腾解散,该句话中包含了组织关系-裁员组织关系-解散两个事件类型。
      该数据集中的训练集一共有11958个样本,65个事件类型,我们对该训练集进行简单的数据分析,来看看多事件类型的个数和占比,以及每个事件类型的数量。数据分析的脚本如下:

    # -*- coding: utf-8 -*-
    # author: Jclian91
    # place: Pudong Shanghai
    # time: 2020-04-09 21:31
    
    from collections import defaultdict
    from pprint import pprint
    
    with open("./data/multi-classification-train.txt", "r", encoding="utf-8") as f:
        content = [_.strip() for _ in f.readlines()]
    
    # 每个事件类型的数量统计
    event_type_count_dict = defaultdict(int)
    
    # 多事件类型数量
    multi_event_type_cnt = 0
    
    for line in content:
        # 事件类型
        event_types = line.split(" ", maxsplit=1)[0]
    
        # 如果|在事件类型中,则为多事件类型
        if "|" in event_types:
            multi_event_type_cnt += 1
    
        # 对应的每个事件类型数量加1
        for event_type in event_types.split("|"):
            event_type_count_dict[event_type] += 1
    
    
    # 输出结果
    print("多事件类型的样本共有%d个,占比为%.4f。" %(multi_event_type_cnt, multi_event_type_cnt/len(content)))
    
    pprint(event_type_count_dict)
    

    输出结果如下:

    多事件类型的样本共有1121个,占比为0.0937。
    defaultdict(<class 'int'>,
                {'交往-会见': 98,
                 '交往-感谢': 63,
                 '交往-探班': 69,
                 '交往-点赞': 95,
                 '交往-道歉': 149,
                 '产品行为-上映': 286,
                 '产品行为-下架': 188,
                 '产品行为-发布': 1196,
                 '产品行为-召回': 287,
                 '产品行为-获奖': 139,
                 '人生-产子/女': 106,
                 '人生-出轨': 32,
                 '人生-分手': 118,
                 '人生-失联': 105,
                 '人生-婚礼': 59,
                 '人生-庆生': 133,
                 '人生-怀孕': 65,
                 '人生-死亡': 811,
                 '人生-求婚': 76,
                 '人生-离婚': 268,
                 '人生-结婚': 294,
                 '人生-订婚': 62,
                 '司法行为-举报': 98,
                 '司法行为-入狱': 155,
                 '司法行为-开庭': 105,
                 '司法行为-拘捕': 712,
                 '司法行为-立案': 82,
                 '司法行为-约谈': 266,
                 '司法行为-罚款': 224,
                 '司法行为-起诉': 174,
                 '灾害/意外-地震': 119,
                 '灾害/意外-坍/垮塌': 80,
                 '灾害/意外-坠机': 104,
                 '灾害/意外-洪灾': 48,
                 '灾害/意外-爆炸': 73,
                 '灾害/意外-袭击': 117,
                 '灾害/意外-起火': 204,
                 '灾害/意外-车祸': 286,
                 '竞赛行为-夺冠': 430,
                 '竞赛行为-晋级': 302,
                 '竞赛行为-禁赛': 135,
                 '竞赛行为-胜负': 1663,
                 '竞赛行为-退役': 95,
                 '竞赛行为-退赛': 141,
                 '组织关系-停职': 87,
                 '组织关系-加盟': 335,
                 '组织关系-裁员': 142,
                 '组织关系-解散': 81,
                 '组织关系-解约': 45,
                 '组织关系-解雇': 93,
                 '组织关系-辞/离职': 580,
                 '组织关系-退出': 183,
                 '组织行为-开幕': 251,
                 '组织行为-游行': 73,
                 '组织行为-罢工': 63,
                 '组织行为-闭幕': 59,
                 '财经/交易-上市': 51,
                 '财经/交易-出售/收购': 181,
                 '财经/交易-加息': 24,
                 '财经/交易-涨价': 58,
                 '财经/交易-涨停': 219,
                 '财经/交易-融资': 116,
                 '财经/交易-跌停': 102,
                 '财经/交易-降价': 78,
                 '财经/交易-降息': 28})
    

    模型训练

      我们利用sklearn模块中的MultiLabelBinarizer进行多标签编码,如果文本所对应的事件类型存在,则将该位置的元素置为1,否则为0。因此,y值为65维的向量,其中1个或多个为1,是该文本(x值)对应一个或多个事件类型。
      我们采用ALBERT对文本进行特征提取,最大文本长度为200,采用的深度学习模型如下:

    深度学习模型
      模型训练的脚本(model_trian.py)的代码如下:

    # -*- coding: utf-8 -*-
    # author: Jclian91
    # place: Pudong Shanghai
    # time: 2020-04-03 18:12
    
    import json
    import numpy as np
    from sklearn.preprocessing import MultiLabelBinarizer
    from keras.models import Model
    from keras.optimizers import Adam
    from keras.layers import Input, Dense
    from att import Attention
    from keras.layers import GRU, Bidirectional
    from tqdm import tqdm
    import matplotlib.pyplot as plt
    
    from albert_zh.extract_feature import BertVector
    
    with open("./data/multi-classification-train.txt", "r", encoding="utf-8") as f:
        train_content = [_.strip() for _ in f.readlines()]
    
    with open("./data/multi-classification-test.txt", "r", encoding="utf-8") as f:
        test_content = [_.strip() for _ in f.readlines()]
    
    # 获取训练集合、测试集的事件类型
    movie_genres = []
    
    for line in train_content+test_content:
        genres = line.split(" ", maxsplit=1)[0].split("|")
        movie_genres.append(genres)
    
    # 利用sklearn中的MultiLabelBinarizer进行多标签编码
    mlb = MultiLabelBinarizer()
    mlb.fit(movie_genres)
    
    print("一共有%d种事件类型。" % len(mlb.classes_))
    
    with open("event_type.json", "w", encoding="utf-8") as h:
        h.write(json.dumps(mlb.classes_.tolist(), ensure_ascii=False, indent=4))
    
    # 对训练集和测试集的数据进行多标签编码
    y_train = []
    y_test = []
    
    for line in train_content:
        genres = line.split(" ", maxsplit=1)[0].split("|")
        y_train.append(mlb.transform([genres])[0])
    
    for line in test_content:
        genres = line.split(" ", maxsplit=1)[0].split("|")
        y_test.append(mlb.transform([genres])[0])
    
    y_train = np.array(y_train)
    y_test = np.array(y_test)
    
    print(y_train.shape)
    print(y_test.shape)
    
    # 利用ALBERT对x值(文本)进行编码
    bert_model = BertVector(pooling_strategy="NONE", max_seq_len=200)
    print('begin encoding')
    f = lambda text: bert_model.encode([text])["encodes"][0]
    
    x_train = []
    x_test = []
    
    process_bar = tqdm(train_content)
    
    for ch, line in zip(process_bar, train_content):
        movie_intro = line.split(" ", maxsplit=1)[1]
        x_train.append(f(movie_intro))
    
    process_bar = tqdm(test_content)
    
    for ch, line in zip(process_bar, test_content):
        movie_intro = line.split(" ", maxsplit=1)[1]
        x_test.append(f(movie_intro))
    
    x_train = np.array(x_train)
    x_test = np.array(x_test)
    
    print("end encoding")
    print(x_train.shape)
    
    
    # 深度学习模型
    # 模型结构:ALBERT + 双向GRU + Attention + FC
    inputs = Input(shape=(200, 312, ), name="input")
    gru = Bidirectional(GRU(128, dropout=0.2, return_sequences=True), name="bi-gru")(inputs)
    attention = Attention(32, name="attention")(gru)
    num_class = len(mlb.classes_)
    output = Dense(num_class, activation='sigmoid', name="dense")(attention)
    model = Model(inputs, output)
    
    # 模型可视化
    # from keras.utils import plot_model
    # plot_model(model, to_file='multi-label-model.png', show_shapes=True)
    
    model.compile(loss='binary_crossentropy',
                  optimizer=Adam(),
                  metrics=['accuracy'])
    
    history = model.fit(x_train, y_train, validation_data=(x_test, y_test), batch_size=128, epochs=10)
    model.save('event_type.h5')
    
    
    # 训练结果可视化
    # 绘制loss和acc图像
    plt.subplot(2, 1, 1)
    epochs = len(history.history['loss'])
    plt.plot(range(epochs), history.history['loss'], label='loss')
    plt.plot(range(epochs), history.history['val_loss'], label='val_loss')
    plt.legend()
    
    plt.subplot(2, 1, 2)
    epochs = len(history.history['accuracy'])
    plt.plot(range(epochs), history.history['accuracy'], label='acc')
    plt.plot(range(epochs), history.history['val_accuracy'], label='val_acc')
    plt.legend()
    plt.savefig("loss_acc.png")
    

    训练过程输出内容如下:

    一共有65种事件类型。
    (11958, 65)
    (1498, 65)
    I:BERT_VEC:[graph:opt:128]:load parameters from checkpoint...
    I:BERT_VEC:[graph:opt:130]:freeze...
    I:BERT_VEC:[graph:opt:133]:optimize...
    I:BERT_VEC:[graph:opt:144]:write graph to a tmp file: ./tmp_graph11
    100%|██████████| 11958/11958 [02:47<00:00, 71.39it/s]
    100%|██████████| 1498/1498 [00:20<00:00, 72.54it/s]
    end encoding
    (11958, 200, 312)
    Train on 11958 samples, validate on 1498 samples
    

    在最终的epoch上,训练集上的acuuracy为0.9966,测试集上的acuuracy为0.9964。训练结果的loss和acc曲线如下:
    模型的训练效果
    从上述结果看,多标签分类的模型效果还是相当不错的。

    模型预测

      我们利用下面的模型预测脚本(model_predict.py)对新的测试集数据进行验证,脚本代码如下:

    # -*- coding: utf-8 -*-
    # author: Jclian91
    # place: Pudong Shanghai
    # time: 2020-04-03 21:50
    
    import json
    import numpy as np
    from keras.models import load_model
    
    from att import Attention
    from albert_zh.extract_feature import BertVector
    load_model = load_model("event_type.h5", custom_objects={"Attention": Attention})
    
    # 预测语句
    text = "北京时间6月7日,中国男足在广州天河体育场与菲律宾进行了一场热身赛,最终国足以2-0击败了对手,里皮也赢得了再度执教国足后的首场比赛胜利!"
    text = text.replace("\n", "").replace("\r", "").replace("\t", "")
    
    labels = []
    
    bert_model = BertVector(pooling_strategy="NONE", max_seq_len=200)
    
    # 将句子转换成向量
    vec = bert_model.encode([text])["encodes"][0]
    x_train = np.array([vec])
    
    # 模型预测
    predicted = load_model.predict(x_train)[0]
    
    indices = [i for i in range(len(predicted)) if predicted[i] > 0.5]
    
    with open("event_type.json", "r", encoding="utf-8") as g:
        movie_genres = json.loads(g.read())
    
    print("预测语句: %s" % text)
    print("预测事件类型: %s" % "|".join([movie_genres[index] for index in indices]))
    

    其中的几个样本的预测结果如下:

    预测语句: 北京时间6月7日,中国男足在广州天河体育场与菲律宾进行了一场热身赛,最终国足以2-0击败了对手,里皮也赢得了再度执教国足后的首场比赛胜利!
    预测事件类型: 竞赛行为-胜负

    预测语句: 巴西亚马孙雨林大火持续多日,引发全球关注。
    预测事件类型: 灾害/意外-起火

    预测语句: 19里加大师赛资格赛前两天战报 中国选手8人晋级6人遭淘汰2人弃赛
    预测事件类型: 竞赛行为-晋级

    预测语句: 日本电车卡车相撞,车头部分脱轨并倾斜,现场起火浓烟滚滚
    预测事件类型: 灾害/意外-车祸

    预测语句: 截止到11日13:30 ,因台风致浙江32人死亡,16人失联。具体如下:永嘉县岩坦镇山早村23死9失联,乐清6死,临安区岛石镇银坑村3死4失联,临海市东塍镇王加山村3失联。
    预测事件类型: 人生-失联|人生-死亡

    预测语句: 定位B端应用,BeBop发布Quest专属版柔性VR手套
    预测事件类型: 产品行为-发布

    预测语句: 8月17日。凌晨3点20分左右,济南消防支队领秀城中队接到指挥中心调度命令,济南市中区中海环宇城往南方向发生车祸,有人员被困。
    预测事件类型: 灾害/意外-车祸

    预测语句: 注意!济南可能有雷电事故|英才学院14.9亿被收购|八里桥蔬菜市场今日拆除,未来将建新的商业综合体
    预测事件类型: 财经/交易-出售/收购

    预测语句: 昨天18:30,陕西宁强县胡家坝镇向家沟村三组发生山体坍塌,5人被埋。当晚,3人被救出,其中1人在医院抢救无效死亡,2人在送医途中死亡。今天凌晨,另外2人被发现,已无生命迹象。
    预测事件类型: 人生-死亡|灾害/意外-坍/垮塌

    总结

      本项目已经上传至Github项目,网址为:https://github.com/percent4/multi-label-classification-4-event-type
      后续有机会再给大家介绍更多多标签分类相关的问题,欢迎大家关注~

    展开全文
  • 需要注意的问题: 1、linux mac 平台 2、标签中的下划线是两个!...测试facebook开源的基于深度学习的对文本分类的fastText模型 fasttext python包的安装: pip install fasttext 第一步获取分...
  • 一、摘要: (该论文的模型创新点在于词向量那里,所以全文的重心偏向于词向量部分) 传统的机器学习方法主要用词袋...所以现在所提出的词向量,作为神经网络的输入使得文本分类等任务有了更好的效果。 本文提出CNN...
  • 文本分类之多标签分类

    千次阅读 2020-02-19 11:30:12
    标签分类综述 意义 网络新闻往往含有丰富的语义,一篇文章既可以属于“经济”也可以属于“文化”。给网络新闻打多标签可以更好地反应文章的真实意义,方便日后的分类和使用。 难点 类标数量不确定,有些样本...
  • 标签文本分类标签文本分类简介三种神经网络结构网络模型文本分类网络模型多标签文本分类网络模型 多标签文本分类简介 NLP(自然语言处理),即让计算机去理解人类的自然语言(文本、语音等),进而完成各种各样...
  • Scikit-learn中使用SVM对文本进行分类

    千次阅读 2017-09-14 20:59:40
      本人最近弄了两个和svm算法有关的大作业,一个是处理手写数字识别的,另外一个是文本分类的。最开始,我用libsvm提供的包进行分类。但是总是会出现分成一类的情况。有时候数据归一化之后,就不会分成一类,能够...
  • 介绍 在本文中,我们将看到如何开发具有多个输出的文本分类模型。...在本文结尾,您将能够数据执行多标签文本分类。 数据集 数据集包含来自Wikipedia对话页编辑的评论。 评论可以属于所有这些类别...
  • pytorch实现用CNN和LSTM对文本进行分类

    万次阅读 2019-05-27 17:00:19
    """文本分类,RNN模型""" def __init__(self): super(TextRNN, self).__init__() # 三个待输入的数据 self.embedding = nn.Embedding(5000, 64) # 进行词嵌入 # self.rnn = nn.LSTM(input_size=64, hidden_...
  • 2. 在数据竞赛中,常用的模型就是CNN和RNN,先调出baseline,然后再进行模型融合(model ensemble)。在以上步骤的约束下,数据竞赛比的就是设备的计算能力和个人的调参能力。 3. 在自然语言处理与NLP实战的...
  • 使用python和sklearn的文本标签分类实战开发

    千次阅读 多人点赞 2019-03-04 20:41:40
    文本分类一般可以分为二分类、多分类、多标签分类三种情况,二分类是指将一组文本分成两个类(0或1),比较常见的应用如垃圾邮件分类、电商网站的用户评价数据的正负面分类等,多分类是指将文本分成若干个类中的某一个类,...
  • BERT FOR SEQUENCE-TO-SEQUENCE MULTI-LABEL TEXT CLASSIFICATION 引言 我们的主要贡献如下: 1. 我们将BERT的结果作为编码器呈现在MLTC数据集...3.我们微调vanilla BERT模型来执行多标签文本分类。据我们所知,这...
  • tensorflow 2.0+ 基于BERT的多标签文本分类 在多标签分类的问题中,模型的训练集由实例组成,每个实例可以被分配多个类别,表示为一组目标标签,最终任务是准确预测测试数据的标签集。例如: 文本可以同时涉及宗教...
  • 使用fastText进行文本分类

    千次阅读 2017-07-10 01:10:26
    fastText文本分类学习笔记文本分类,linux命令行: ./fasttext supervised -input train.txt -output model训练集train.txt的输入格式为: 标签是以字符串label作为前缀的单词,后面的数字对应类别。一旦模型被...
  • 本文将会介绍如何使用keras-bert实现文本标签分类任务,其中BERT进行微调。 项目结构 数据集介绍 模型训练 模型评估 模型预测 总结
  • 论文笔记:https://cloud.tencent.com/developer/news/43321 Semi-supervised Learning with Deep Generative Models-------2014 NIPS ... 1.对于有标签数据 先求重构损失,再加分类损失,要...
  • 本文基于sigmoid做了一个将一段长文本打上多个标签的算法模型,首先声明,我的模型最终的效果不好,因为我的文本很长,而且采用的模型很简单,就一层神经网络,权当练手。 数据集文件的格式为每行一个样本,以制表...
  • 利用朴素贝叶斯进行新闻文本分类

    千次阅读 2018-09-19 15:50:44
    初探文本分类,本文使用的数据是5000条中文新闻文本数据,目的是使用朴素贝叶斯算法,中文新闻文本进行分类预测。流程如下: 文本数据载入及清洗 搜狗新闻数据源:http://www.sogou.com/labs/resource/ca.php ...
  • 在之前已经有使用机器学习方法进行情感分类了,现在是提取各种可能影响评论有用性的特征之后对文本进行分类。 我分析的数据是手机商品评论,看看我提取了些什么特征(特征和情感分类的特征不一样了。情感分类使用的...
  • FastText进行文本分类实践

    千次阅读 2019-07-23 18:44:20
    目录0、内容介绍1、FastText是什么?...本文主要介绍如何使用利用fastText进行文本分类任务,包括如何准备、处理数据,训练及测试过程。 最近用到fastText进行文本分类任务,其不用训练好的词向...
  • NLP-使用CNN进行文本分类

    万次阅读 多人点赞 2018-04-20 22:39:57
    CNN最初用于处理图像问题,但是在自然语言处理中,使用CNN进行文本分类也可以取得不错的效果。 在文本中,每个词都可以用一个行向量表示,一句话就可以用一个矩阵来表示,那么处理文本就与处理图像是类似的了。 ...
  • 标签: def create_model_original(bert_config, is_training, input_ids, input_mask, segment_ids, labels, num_labels, use_one_hot_embeddings): """Creates a classification model.""" model = modeling...
  • 文本分类

    千次阅读 2016-11-01 12:38:39
    文本分类: 预处理 特征选择 DF (Document Frequency) 信息增益 (Information Gain, IG) 熵 (Entropy) 相对熵 (Relative Entropy) χ² 统计量 (Chi-Square) 互信息 (Mutual Information) Robertson & Sparck Jones...
  • 2017知乎看山杯总结(多标签文本分类)

    万次阅读 多人点赞 2017-08-31 21:59:53
    基于:python 2.7, TensorFlow 1.2.1任务描述:参赛者需要根据知乎给出的问题及话题标签的绑定关系的训练数据,训练出未标注数据自动标注的模型。标注数据中包含 300 万个问题,每个问题有 1 个或多个标
  • CNN文本分类

    千次阅读 2018-09-20 08:33:46
    文本分类是NLP领域的一个重要的子任务,文本分类的目标是自动的将文本打上已经定义好的标签,常见的文本分类任务有:垃圾邮件过滤、情感分析、新闻分类等等。 代码是来自 ... 大家可以自行下载阅读,下面仅仅是自己...
  • 这是一个文本分类的问题:目标是“参赛者根据知乎给出的问题及话题标签的绑定关系的训练数据,训练出未标注数据自动标注的模型”。通俗点讲就是:当用户在知乎上提问题时,程序要能够根据问题的内容自动为其添加...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 113,331
精华内容 45,332
关键字:

对没有标签的文本进行分类