FastText模型与弱监督学习在分类任务的应用

一、项目摘要

        弱监督学习在机器学习领域中具有重要的意义,传统的监督学习需要大量的准确标注数据,而弱监督学习通过利用相对较少或不完整的标注信息来训练模型,可以大大降低标注数据的需求量,从而节省了标注的时间和成本。FastText是一种基于词向量的文本分类模型,FastText模型通过将文本表示为词向量和n-gram特征的组合,并利用分层Softmax进行高效训练和预测,实现了快速有效的文本分类。它在处理大规模文本数据时具有较好的性能和效果。

        本次主要研究的是在弱监督学习的前提下使用FastText文本分类模型对少量的标注数据进行训练然后再使用训练好的模型去对大量无标签的文本数据进行预测工作。然后建立评价指标来观察FastText模型在弱监督文本分类的表现。我们希望FastText模型可以以极少的有标签的训练集情况下,在执行大规模的分类任务时仍有比较好的能力,我们使用web-snippets数据集作为我们的数据集,web-snippets数据集是一个包含大量互联网中的文本片段,用于自然语言处理和信息检索任务的研究和开发。它其中的文本片段是从互联网上的各个网页中提取得到的,涵盖了各种主题和领域的内容,这些文本片段通常是搜索引擎在搜索结果页面中显示的摘要或预览,用于展示与用户查询相关的网页内容。我们随机抽取了80条数据的索引,并以此作为训练集,约占数据集总量的0.5%。

二、工作流程

        1、下载fasttext模型,因为我们在运行代码时需要import fasttext。我们可以通过pip install fasttext 来下载fasttext模型,但是通常可能会失败。我采用的是直接下载工具包到lib文件夹,在该网站https://www.lfd.uci.edu/~gohlke/pythonlibs/#fasttext选择合适的安装包,然后直接pip工具包名称。

ps:这里不用gensim库导入FastText模型是因为gensim库中的模型通常用于词向量训练和获取词向量的相关操作。

        2、然后就是按照索引来切分数据集。我们通过索引来切分数据集的主要目的是为了固定下来训练集和测试集,避免每次的随机切割对多次的预测结果造成干扰。

ps:如何不需要结合其他对比模型试验,这里切割数据时我们完全可以使用我们之前提到的sklearn中的train_test_split(),同时将size设为0.005。

        3、 其次就是将训练集送入到fasttext模型中训练,对其词向量维度等进行微调。然后对测试集进行预测工作。

ps:fasttext模型要求输入的训练集的格式是"__label__" + "label" + "分词结果"

        4、最后就是评价预测结果,这里我们采用的是混淆矩阵来对预测结果进行评价,并使用PrettyTable来对评价结果进行美化。

三、实验代码

1、导入必要的库并且同时定义路径。这里的fasttext就是我们之前的提到的fasttext模型,由于其特殊性,所以在安装时候会遇到一些。

import pandas as pd
import fasttext
from sklearn.metrics import classification_report  #导入混淆矩阵对应的库
from collections import Counter
import math
from prettytable import PrettyTable

data_path = './web/'

# web数据集的标签目录
category_names = ['business', 'computers', 'culture art sentertainment','education science', 'engineering', 'health','politicssociety', 'sports']

 2、首先是读取数据集的函数。这里我们读取的数据集是将数据集分词处理后的数据集,前面的文章关于分词工作提到很多次,这里就不在赘述。

def read():
    df_data = pd.read_csv(data_path+'web分词数据.txt', header=0, sep='\t', engine='python', encoding='utf-8')
    print(df_data)
    df_word = pd.DataFrame(df_data['分词结果'])
    df_word.columns = ['sentence']
    df_label = pd.DataFrame(df_data['label_char'])
    df_label.columns = ['label']
    return df_word, df_label

3、然后就是我们的根据任务特定的需求,我们在分割数据集的时候使用特定的文章索引来切割数据集,此操作可以固定我们的训练集和测试集。

ps:ilocloc是Pandas库中用于基于索引进行数据访问和操作的两个函数。

      iloc:使用基于整数位置的索引;loc:使用基于标签的索引。

def trainsplit(data, label_ylable):
    #X_train, X_test, y_train, y_test = train_test_split(data, label_ylable, train_size=0.3)
    temp_train_index = pd.read_csv(data_path + 'splitdata_web/' + 'Number10_train_index_3.csv', header=None, names=['index'])
    #print(temp_train_index)
    X_train = pd.DataFrame(data.iloc[temp_train_index['index']])
    y_train = pd.DataFrame(label_ylable.iloc[temp_train_index['index']])
    #print(y_train)
    temp_test_index = pd.read_csv(data_path + 'splitdata_R8/' + 'Number10_test_index_3.csv', header=None, names=['index'])
    X_test = pd.DataFrame(data.iloc[temp_test_index['index']])
    y_test = pd.DataFrame(label_ylable.iloc[temp_test_index['index']])
    #print(X_train,X_test,y_train,y_test)
    return X_train, X_test, y_train, y_test

4、然后我要进行的一步就是将原来的分词数据转化为符合fasttext要求格式的数据集,在这里,我们只需要处理训练集就好,我们需要为训练打上标签,即在分词数据前加上__label__后面跟上真实的标签。这样fasttext在训练模型的时候才能识别出文章的标签。

def hand(X_train, X_test, y_train, y_test):
    label_list = y_train['label'].values.tolist()
    X_train["label"] = ""
    X_train["label"] = label_list
    X_train["datas"] = "__label__" + X_train["label"].map(str) + " " + X_train["sentence"].map(str)
    X_train_end = pd.DataFrame(X_train["datas"].values.tolist())
    X_test_end = X_test
    y_train_end = y_train['label'].values.tolist()
    y_test_end = y_test['label'].values.tolist()
    X_train_end.to_csv('fasttext_Xtrain.txt', index=False, header=False)
    X_test_end.to_csv('fasttext_Xtest.txt', index=False, header=False)
    train = 'fasttext_Xtrain.txt'
    test = 'fasttext_Xtest.txt'
    return train, test, y_train_end, y_test_end

5、其次就是我们的训练过程了。在这里我们加入对模型训练轮数和词向量维度的微调。在我们训练结束的同时,加入混淆矩阵来对预测结果进行简单的可视化评价。

def trainpre(train, test, y_train_end, y_test_end):
    model = fasttext.train_supervised(input=train, epoch=30, dim=400)
    #valid_result = model.test(test)
    f = open(test, encoding="utf-8", errors='ignore')
    text_result = []
    for index, line in enumerate(f.readlines()):
        line = line.strip()

        y = model.predict(line)
        y_one = y[0][0].replace('__label__', '')
        #print(y_one)
        text_result.append(y_one)
    print(classification_report(y_test_end, text_result))
    b = Counter(y_train_end)
    print('y_train', b)
    c = Counter(y_test_end)
    print('y_test', c)
    a = Counter(text_result)
    print('预测', a)
    output = classification_report(y_test_end, text_result, output_dict=True, digits=3,target_names=['business', 'computers', 'culture art sentertainment','education science', 'engineering', 'health','politicssociety', 'sports'])  # output_dict=True
    print(output)
    return c,a,output

6、使用 PrettyTable来优化评价结果,让评价结果直观上看起来更情况

四、总结

        在弱监督训练中,FastText表现出了一些优势和特点:文本分类效果比较好:FastText在文本分类任务上表现出色。它使用了n-gram特征,并将文本转化为向量表示。这种向量化的方式对于处理大规模的文本数据集十分高效,并且能够捕捉到词语和短语之间的语义关系。处理稀疏特征能力强:FastText采用了基于哈希的技术来处理大量的、稀疏的特征,这使得模型在面对高维度的输入时依然具备较快的训练速度和较小的内存占用。弱监督学习能力:FastText在弱监督学习中展现出优异的性能。它允许使用不完全标注的数据进行训练,例如只有标签而没有文本内容的数据。这种能力使得 FastText 在训练资源相对不足或难以获取标注的情况下仍然能够有效地进行模型训练。适用于大规模数据集:FastText在处理大规模数据集时具有优势。其模型结构简单且高效,并且可以通过并行计算来加速训练过程。因此,在大数据集上快速训练出具有良好性能的模型是 FastText 的一个优点。左图为R8,右图为web最终训练结果。在训练集只占0.005的情况下,精确度达到0.6左右。

然而,FastText也存在一些限制:无法处理序列信息:FastText不考虑词语的顺序和上下文关系,因此对于某些任务(如机器翻译、文本生成等)涉及到序列信息的情况,其表现可能不如一些序列模型。词向量粒度较粗:FastText将文本表示为词袋的形式,并且每个词都被视为独立的单元。这种粒度相对较粗,无法捕捉到词之间的具体顺序和关联,因此在某些任务中可能无法获得很好的性能。

        综上所述,FastText在弱监督训练中表现出比较好的文本分类效果、对稀疏特征的处理能力以及适用于大规模数据集等优势。然而,在涉及到序列信息和精细的语义理解时,其表现可能受限。使用时需要根据具体任务的要求和数据的特点进行评估和选择。

五、完整代码

        需要完整项目代码和数据集可以私信我上传,大家有不同想法和想要了解的可以发在评论区,欢迎讨论交流!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿二出没

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值