Advertisement

新闻文本分类-Task4

阅读量:

Task04:基于fasttext的文本分类

fasttext 原理说明

要说fasttext的原理,就不得不谈到word2vec。其实二者本身有着天然的联系。word2vec的主要学习方法有CBOW和Skip-gram,主要优化方法有hierarchical softmax和negative sampling。相关理论可以参考

word2vec主要通过词向量的形式来学习词表征,通常文本分类任务会将相应词向量加和平均。fasttext是一个高效的文本分类的库。
其和word2vec主要的不同点有:
1 加入了n-gram特征,该类特征通过实验可以比较好的特征分类的效果,在使用传统TFIDF+分类器进行文本分类的时候,加入n-gram特征也可以一定程度提升效果。
2 通过hash编码的方式来处理n-gram特征,可以缩减空间。
3 通过词的n-gram形成字词的表示,这里可以比较好的处理未登陆词(OOV)的问题。
fasttext模型架构为:

在这里插入图片描述

与Word2vec相比的一个主要区别在于,在这里使用的输入数据已经被转换为嵌入形式而非基于独热编码的方式。在对这些上游任务(如学习x1,x2…Xn等)的学习过程中已经掌握了嵌入表示法。其输入向量不仅包含了单个词的嵌入信息还整合了n-gram级别的多维特征

使用fasttext库进行文本分类

该文本分类主要依赖于fasttext包。在实际操作中遇到了一些技术难点。首先,在安装过程中遇到了问题。具体来说,在尝试直接运行pip install fasttext命令时发现由于gcc版本较低的原因无法成功安装该库。为此可采取以下两种方案来解决问题:一是升级至更高版本的gcc以满足软件需求;二是选择性地下载适合当前系统配置的老版fasttext资源以规避冲突与兼容性问题。综合考虑后决定采用第二种策略以确保程序能够顺利运行并最终实现了预期的数据分类效果。

在这里插入图片描述

下载了0.9.1版本

在这里插入图片描述
复制代码
    pip install fasttext==0.9.1

安装后就可以直接使用import fasttext啦!

复制代码
    import pandas as pd
    import numpy as np
    import fasttext
    from sklearn.metrics import f1_score
    from sklearn.model_selection import train_test_split
    
    # 转换为FastText需要的格式
    train_df = pd.read_csv('./train_set.csv', sep='\t')
    test_df = pd.read_csv('./test_a.csv')
    
    train_df['label_ft'] = '__label__' + train_df['label'].astype(str)
    train_df[['text','label_ft']].to_csv('train.csv', index=None, header=None, sep='\t')
    
    #print(dir(fasttext))
    model = fasttext.train_supervised('train.csv', lr=0.1, wordNgrams=2, 
                                  verbose=2, minCount=1, epoch=25, loss="hs")
    
    predict = [model.predict(x) for x in test_df['text']]

在训练过程中获得的f1分数约为0.9,在线提交后预测结果获得的分数为0.9167。整体水平相当

使用pytorch实现fasttext
复制代码
    import torch
    import torch.nn as nn
    import torch.optim as optim
    import pandas as pd
    
    
    data = pd.read_csv('./train_set.csv', sep='\t', nrows=100)
    
    #print(train_df.head())
    
    vocab = set(data['text'])
    label = data['label']
    
    class FastText(nn.Module):
    def __init__(self, vocab, w2v_dim, classes, hidden_size):
        super(FastText, self).__init__()
        self.embed = nn.Embedding(len(vocab), w2v_dim)
        self.embed.weight.requires_grad = True
        self.fc = nn.Sequential(
                nn.Linear(w2v_dim,hidden_size),
                nn.BatchNorm1d(hidden_size),
                nn.ReLU(),
                nn.Linear(hidden_size, classes)
        )
    
    def forward(self, x):
        x = self.embed(x)
        out = self.fc(x)
        return out 
    
    def train_model(net, epoch, lr, data, label):
    print("train model......")
    net.train()
    optimizer = optim.Adam(net.parameters(),lr=lr)
    Loss = nn.CrossEntropyLoss()
    for i in range(epoch):
        optimizer.zero_grad()
        output = net(data)
        loss = Loss(output, label)
        loss.backward()
        optimizer.step()
        print("train epoch=" + str(i) + ",loss=" + str(loss.item()))
    print('Finished Training')
    
    def model_test(net, test_data, test_label):
    net.eval()  # 将模型设置为验证模式
    correct = 0
    total = 0
    with torch.no_grad():
        outputs = net(test_data)
        # torch.max()[0]表示最大值的值,troch.max()[1]表示回最大值的每个索引
        _, predicted = torch.max(outputs.data, 1)  # 每个output是一行n列的数据,取一行中最大的值
        total += test_label.size(0)
        correct += (predicted == test_label).sum().item()
        print('Accuracy: %d %%' % (100 * correct / total))
    
    if __name__ == "__main__":
    #这里没有写具体数据的处理方法,毕竟大家所做的任务不一样
    batch_size = 64
    epoch = 10  # 迭代次数
    w2v_dim = 300  # 词向量维度
    lr = 0.001
    hidden_size = 128
    classes = 2
    
    # 定义模型
    net = FastText(vocab=vocab, w2v_dim=w2v_dim, classes=classes, hidden_size=hidden_size)
    
    # 训练
    print("开始训练模型")
    train_model(net, epoch, lr, data, label)
    # 保存模型
    print("开始测试模型")
    model_test(net, test_data, test_label)
fasttext源码学习
在这里插入图片描述

源码部分可供以下这些博客资源作为参考资料:

全部评论 (0)

还没有任何评论哟~