fastText代码实战篇——手把手教你使用fastText实现文本分类

目录

前言

fastText文本分类代码实战

安装

本文中使用的数据集

fastText文本分类技术流程图

代码 


前言

上一篇文章中,我们对fastText的原理进行了介绍,fastText原理篇,接下来我们进行代码实战,本文中使用fastText对新闻文本数据进行文本分类。

fasttext是facebook开源的一个词向量与文本分类工具,在学术上没有太多创新点,好处是模型简单,训练速度非常快。简单尝试可以发现,用起来还是非常顺手的,做出来的结果也不错,可以达到上线使用的标准。

简单说来,fastText做的事情,就是把文档中所有词通过lookup table变成向量,取平均之后直接用线性分类器得到分类结果。fastText和ACL-15上的deep averaging network(DAN,如下图)比较相似,是一个简化的版本,去掉了中间的隐层。论文指出了对一些简单的分类任务,没有必要使用太复杂的网络结构就可以取得差不多的结果。如左图DAN网络结构,右图fastText:

fastText论文中提到的两个tricks

  • hierarchical softmax
    • 类别数较多时,通过构建一个霍夫曼编码树来加速softmax layer的计算,和之前word2vec中的trick相同
  • N-gram features
    • 只用unigram的话会丢掉word order信息,fastTex考虑了语序信息即上下文信息,通过加入N-gram features进行补充并用hashing来减少N-gram的存储

fastText文本分类代码实战

安装

pip install fasttext

本文中使用的数据集

数据集:自己搜一下新闻文本分类开源数据集下载即可

  • 5分类中文新闻文本数据,分别是:technology、car、entertainment、military、sports
  • 每类数据取20000条,共计100000条数据作为训练集

原始数据示例:原始数据需要处理为fasttext要求的数据格式

fastText文本分类要求的数据存储格式:

__label__1   我  爱  中国

  • __label__: 类别前缀,__label__后面接类别
  • 1: 类别id,用来区分不同类,可自定义
  • “我   爱  中国”: 分词后文本
  • 代码:
    "__label__"+str(label)+"\t"+" ".join(segs)

     

fastText文本分类技术流程图

代码 

  • 数据读取
import jieba
import pandas as pd
import random

cate_dic = {'technology':1, 'car':2, 'entertainment':3, 'military':4, 'sports':5}

df_technology = pd.read_csv("./origin_data/technology_news.csv", encoding='utf-8')
df_technology = df_technology.dropna()

df_car = pd.read_csv("./origin_data/car_news.csv", encoding='utf-8')
df_car = df_car.dropna()

df_entertainment = pd.read_csv("./origin_data/entertainment_news.csv", encoding='utf-8')
df_entertainment = df_entertainment.dropna()

df_military = pd.read_csv("./origin_data/military_news.csv", encoding='utf-8')
df_military = df_military.dropna()

df_sports = pd.read_csv("./origin_data/sports_news.csv", encoding='utf-8')
df_sports = df_sports.dropna()

technology = df_technology.content.values.tolist()[1000:21000]
car = df_car.content.values.tolist()[1000:21000]
entertainment = df_entertainment.content.values.tolist()[:20000]
military = df_military.content.values.tolist()[:20000]
sports = df_sports.content.values.tolist()[:20000]
  • 数据清洗、分词、去停用词、整理为fastText要求的文本格式,并生成训练数据
stopwords=pd.read_csv("origin_data/stopwords.txt",index_col=False,quoting=3,sep="\t",names=['stopword'], encoding='utf-8')
stopwords=stopwords['stopword'].values

#分词去停用词,并整理为fasttext要求的文本格式
def preprocess_text(content_lines, sentences, category):
    for line in content_lines:
        try:
            segs=jieba.lcut(line)
            segs = list(filter(lambda x:len(x)>1, segs))
            segs = list(filter(lambda x:x not in stopwords, segs))
            sentences.append("__label__"+str(category)+"\t"+" ".join(segs))
        except Exception as e:
            print(line)
            continue

#生成训练数据
sentences = []

preprocess_text(technology, sentences, cate_dic['technology'])
preprocess_text(car, sentences, cate_dic['car'])
preprocess_text(entertainment, sentences, cate_dic['entertainment'])
preprocess_text(military, sentences, cate_dic['military'])
preprocess_text(sports, sentences, cate_dic['sports'])

#数据打乱
random.shuffle(sentences)
  • 训练数据写入文档
# 写入数据-fasttext格式
def generate_model_data(sentences): 
    train_num=int(len(sentences)*0.8)
    train_set=sentences[0:train_num]
    test_set=sentences[train_num:-1]
    print("writing data to fasttext format...")
    with open('./data/train_data.txt', 'w') as out:
        for sentence in train_set:
            out.write(sentence+"\n")
        print("done!")
    with open('./data/test_data.txt','w') as f:
        for sentence in test_set:
            f.write(sentence+'\n')
        print('done!')


generate_model_data(sentences)
  • 训练模型
import fasttext

classifier = fasttext.train_supervised('./data/train_data.txt',label='__label__', wordNgrams=2,epoch=20,lr=0.1,dim=100)

#参数说明
'''
train_supervised(input, lr=0.1, dim=100, 
                   ws=5, epoch=5, minCount=1, 
                   minCountLabel=0, minn=0, 
                   maxn=0, neg=5, wordNgrams=1, 
                   loss="softmax", bucket=2000000, 
                   thread=12, lrUpdateRate=100,
                   t=1e-4, label="__label__", 
                   verbose=2, pretrainedVectors="")
'''

  """
  训练一个监督模型, 返回一个模型对象

  @param input: 训练数据文件路径
  @param lr:              学习率
  @param dim:             向量维度
  @param ws:              cbow模型时使用
  @param epoch:           次数
  @param minCount:        词频阈值, 小于该值在初始化时会过滤掉
  @param minCountLabel:   类别阈值,类别小于该值初始化时会过滤掉
  @param minn:            构造subword时最小char个数
  @param maxn:            构造subword时最大char个数
  @param neg:             负采样
  @param wordNgrams:      n-gram个数
  @param loss:            损失函数类型, softmax, ns: 负采样, hs: 分层softmax
  @param bucket:          词扩充大小, [A, B]: A语料中包含的词向量, B不在语料中的词向量
  @param thread:          线程个数, 每个线程处理输入数据的一段, 0号线程负责loss输出
  @param lrUpdateRate:    学习率更新
  @param t:               负采样阈值
  @param label:           类别前缀
  @param verbose:         ??
  @param pretrainedVectors: 预训练的词向量文件路径, 如果word出现在文件夹中初始化不再随机
  @return model object

  """
  • 保存模型
classifier.save_model('./model/fasttext.bin')
  • 模型批量预测,以及效果评估
’‘’
@return [样本个数, 准确率, 召回率]
‘’‘
train_result=classifier.test('./data/train_data.txt')
print('train_precision:', train_result[1])
print('train_recall:', train_result[2])
print('Number of train examples:', train_result[0])
test_result=classifier.test('./data/test_data.txt')
print('test_precision:', test_result[1])
print('test_recall:', test_result[2])
print('Number of test examples:', test_result[0])  


打印结果:
train_precision: 0.9906387350876191
train_recall: 0.9906387350876191
Number of train examples: 70076
test_precision: 0.9036990524032423
test_recall: 0.9036990524032423
Number of test examples: 17518
  • 模型单例预测
label_to_cate = {1:'technology', 2:'car', 3:'entertainment', 4:'military', 5:'sports'}

texts = '中新网 日电 2018 预赛 亚洲区 强赛 中国队 韩国队 较量 比赛 上半场 分钟 主场 作战 中国队 率先 打破 场上 僵局 利用 角球 机会 大宝 前点 攻门 得手 中国队 领先'
# texts = '这 是 中国 第 一 次 军舰 演习'
labels = classifier.predict(texts)
print(labels)
print(label_to_cate[int(labels[0][0].strip('__label__'))])


打印结果:
(('__label__5',), array([0.9999727]))
sports
  • 模型加载
model = fasttext.load_model(path)
  • 模型优化方向
  1. 上面仅是代码示例,你可以把它封装成一个类
  2. 进行数据预处理,比如减少不必要字符、优化停用词、过滤出现次数较少的词组等
  3. 更改样本训练次数epochs(使用参数 –epoch,标准范围[5, 50])
  4. 更改学习率learning rate(使用参数 –lr,标准范围[0.1-1])
  5. 使用word n-grams(使用参数 –wordNgrams,标准范围[1-5])

 

### 回答1: 以下是使用 fasttext 进行文本分类的示例代码: ``` import fasttext # 训练模型 classifier = fasttext.train_supervised(input="data.train", lr=1.0, epoch=25, wordNgrams=2) # 预测 texts = ["I love playing football", "I hate playing football"] labels, probs = classifier.predict(texts) print(labels) # 输出预测的标签 print(probs) # 输出预测的概率 # 评估模型 print(classifier.test("data.valid")) ``` 其中,"data.train" 是训练集文件路径,"data.valid" 是验证集文件路径,可根据自己的数据进行修改。 在这个例子中,我们使用了一个超参数wordNgrams=2,意味着我们把两个连续的单词组合成一个特征。 ### 回答2: FastText 是一个基于词袋模型的文本分类工具,采用了层次 Softmax 进行多层分类。以下是使用 FastText 实现文本分类的示例代码: 首先,需要安装 fasttext 库,并导入相应的模块: ``` !pip install fasttext import fasttext ``` 接下来,准备训练数据和测试数据。假设文本分类的目标是将电影评论分为积极和消极两类。训练数据和测试数据分别保存在 train.txt 和 test.txt 文件中,每行包含一个标签和一个句子,以空格分隔,例如: ``` __label__positive 这部电影真的很棒 __label__negative 这个电影太糟糕了 ``` 创建 FastText 的分类器,并设置一些模型参数: ``` classifier = fasttext.supervised('train.txt', 'model', label_prefix='__label__') ``` 使用训练数据训练模型: ``` classifier = fasttext.train_supervised('train.txt', label_prefix='__label__') ``` 对测试数据进行预测: ``` result = classifier.predict('test.txt') ``` 输出预测结果: ``` print(result) ``` 以上就是使用 FastText 实现文本分类的示例代码。通过训练和预测,可以对新的文本数据进行分类,并获得分类结果。需要注意的是,这只是一个简单的示例,实际应用中还需要进行更多的数据预处理、模型调参和评估等工作。 ### 回答3: 以下是使用fasttext实现文本分类的示例代码: ```python import pandas as pd import fasttext # 读取训练数据 train_data = pd.read_csv('train_data.csv') # 将训练数据写入文本文件 train_data['text_label'] = '__label__' + train_data['label'].astype(str) + ' ' + train_data['text'] train_data[['text_label']].to_csv('train.txt', index=False, header=False, sep='\t') # 训练模型 model = fasttext.train_supervised(input='train.txt', epoch=10, lr=1.0, wordNgrams=2) # 保存模型 model.save_model('model.bin') # 加载模型 model = fasttext.load_model('model.bin') # 预测文本分类 text = '这是一个测试文本' predicted_label = model.predict(text) print(predicted_label[0][0]) # 输出预测的类别 ``` 首先,要准备好训练数据,数据格式为CSV文件,包含两列:label和text,其中label代表文本类别,text代表文本内容。 读取训练数据后,将label和text合并,形成fasttext所需的标签格式。然后将标签格式的数据写入文本文件(train.txt)中,每行包含一个文本的标签和内容。 使用`fasttext.train_supervised`函数来训练文本分类模型,指定输入文件、迭代次数、学习率和wordNgrams等参数。 训练完成后,保存模型为二进制文件(model.bin)。 加载模型后,使用`model.predict`函数对文本进行分类预测,得到预测的类别。 最后打印出预测的类别。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值