Windows下fasttext文本分类

在写论文的时候了解到有fasttext这种文本分类方法,也看了很多别人的博客,但感觉使用这种方法的人并不是很多,或者使用的版本有些旧。本文会介绍下Windows下最新的fasttext版本以及如何进行文本分类



以下是本篇文章正文内容,下面案例可供参考

fasttext简介

fasttext是2016年facebook开源的一款简单而高效词表示和文本分类工具。它不仅训练速度快,而且模型的准确率的和其他深层学习分类器不相上下,并且在训练和评估上要比深度学习分类器快好几个数量级。它是一个浅层神经网络,其模型结构类似于word2vec的CBOW。
fasttext模型结构图

fasttext之所以高效,是因为它在预测类别数很多时,采用了基于霍夫曼编码树的分层softmax,计算的复杂度从O(Kd)下降为O(dlog2k)。其中K是预测类别数,d是神经网络隐藏层的节点数量。在预测时,分层softmax也提高了速度。使用深度优先搜索(depth first search)来遍历霍夫曼编码树并可快速找打最大概率的树叶,剪去任何与较小概率相联的分枝。

此外,fasttext还加入了额外的n-gram特征,通过一个哈希(hashing)技巧维持了快速且有效的 n-gram 映射(Weinberger et al., 2009),这个哈希技巧与 Mikolov et al.(2011)论文中的哈希函数相同,使它可以和精确使用词语顺序的方法达到同样的准确度。

官网: https://fasttext.cc/docs/en/python-module.html.

Windows下安装

代码如下(示例):

pip install fasttext

版本

2019年6月25官网发布了Windows下的最新版本,这个版本将原来的官方版fastText和非官方版fasttext合并,现在最新版本fasttext在github repository和 pypi.org都可以找到。

新版特色

保留了官方API和顶层函数(例如train_unsupervised和train_supervised)以及返回的numpy对象。 从非正式API中删除了cbow,skipgram和supervised函数。 并且将非官方API中的好主意带到了官方API中。 特别是,我们喜欢WordVectorModel这类很python的方法。

主要函数及用法

如果是文本分类用到的函数就是 train_supervised

import fasttext

model = fasttext.train_supervised('data.train.txt')

这里data.train.txt是一个文本文件,每行包含一个训练语句以及标签。 默认情况下,我们假设标签是带有字符串__label__前缀的string.

该函数主要参数如下:

 input             # training file path (required)
    lr                # learning rate [0.1]
    dim               # size of word vectors [100]
    ws                # size of the context window [5]
    epoch             # number of epochs [5]
    minCount          # minimal number of word occurences [1]
    minCountLabel     # minimal number of label occurences [1]
    minn              # min length of char ngram [0]
    maxn              # max length of char ngram [0]
    neg               # number of negatives sampled [5]
    wordNgrams        # max length of word ngram [1]
    loss              # loss function {ns, hs, softmax, ova} [softmax]
    bucket            # number of buckets [2000000]
    thread            # number of threads [number of cpus]
    lrUpdateRate      # change the rate of updates for the learning rate [100]
    t                 # sampling threshold [0.0001]
    label             # label prefix ['__label__']
    verbose           # verbose [2]
    pretrainedVectors # pretrained word vectors (.vec file) for supervised learning []
    #可以用训练好的词向量  

文本分类

数据集

这里用携程酒店评论数据https://www.kesci.com/home/dataset/5e620482b8dfce002d803622
共有7766条其中正向5322条,负向2444条。

import pandas as pd 
import numpy as np
from sklearn  import metrics
from sklearn import model_selection
from sklearn.naive_bayes import BernoulliNB
import jieba
from xgboost import plot_importance,plot_tree
import xgboost as xgb
import fasttext
import time
df = pd.read_csv('D:word data/ChnSentiCorp_htl_all.csv',encoding='utf-8')
df = df.dropna()
print(df.dtypes)
df.head()

前五条数据

数据处理

分词和去除停用词

def filter_stopwords(txt):
    sent = jieba.lcut(txt)
    words = []
    for word in sent:
        if(word in stopwords):
            continue
        else:
            words.append(word)
    return ' '.join(words)
def get_custom_stopwords(stop_words_file):
    with open(stop_words_file,encoding="utf8") as f:
        stopwords = f.read()
    stopwords_list = stopwords.split('\n')
    custom_stopwords_list = [i for i in stopwords_list]
    return custom_stopwords_list

stop_words_file = 'D:/data/stoplist.txt'
stopwords = get_custom_stopwords(stop_words_file)

文本格式处理

df['cut_review'] = df.review.apply(filter_stopwords)
df['label'] = '__label__'+ df['label'] #fasttext需要将分类标签添上'__label__'前缀
#且要求每行输出如下中间用分隔符分开,而','分隔符是不行的
df['res'] = df['label'] + ' ' + df['cut_review']

处理后数据

划分数据集并保存为txt文件

由于train_supervised中input参数只接受文件路径,划分数据集为训练集和测试集后保存为text文件

sentences = df['res']
sentences_train,sentences_test = train_test_split(sentences,test_size = 0.3)
sentences_train = sentences_train.values.tolist()
sentences_test = sentences_test.values.tolist()

def writeData(sentences,fileName):
    print("writing data to fasttext format...")
    out=open(fileName,'w',encoding='utf-8')
    for sentence in sentences:
        out.write(sentence+"\n")
    print("done!")

fileName = 'D:word data/ChnSentiCorp_htl_train.txt'
writeData(sentences_train,fileName)
fileName = 'D:word data/ChnSentiCorp_htl_test.txt'
writeData(sentences_test,fileName)

二分类

ts = time.time()
model = fasttext.train_supervised('D:word data/ChnSentiCorp_htl_train.txt')
time.time() - ts
# 0.2246713638305664

#模型评估
def print_results(N, p, r):
    print("N\t" + str(N))
    print("P@{}\t{:.3f}".format(1, p))
    print("R@{}\t{:.3f}".format(1, r))

print_results(*model.test('D:word data/ChnSentiCorp_htl_test.txt'))


# N	2330
# P@1	0.861 precsion 这可能是正样本比例偏高导致的
# R@1	0.861 recall

调参

#考虑word ngram 并改损失函数为负采样的损失函数
ts = time.time()
model = fasttext.train_supervised('D:word data/ChnSentiCorp_htl_train.txt',wordNgrams = 2,loss = 'ns')
time.time() - ts
# 0.2246713638305664

#模型评估
def print_results(N, p, r):
    print("N\t" + str(N))
    print("P@{}\t{:.3f}".format(1, p))
    print("R@{}\t{:.3f}".format(1, r))

print_results(*model.test('D:word data/ChnSentiCorp_htl_test.txt'))
# N	2330
# P@1	0.856
# R@1	0.856
#效果并没有提高

和朴素贝叶斯比较

#导入数据并处理
df = pd.read_csv('D:word data/ChnSentiCorp_htl_all.csv',encoding='utf-8')
df = df.dropna()
df['cut_review'] = df.review.apply(filter_stopwords)
X = df['cut_review']
y = df.label
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=22)

#词向量化 只考虑每个单词出现的频率;然后构成一个特征矩阵,每一行表示一个训练文#本的词频统计结果
from sklearn.feature_extraction.text import CountVectorizer
vect = CountVectorizer(max_df = 0.8, 
                       min_df = 3, 
                       token_pattern=u'(?u)\\b[^\\d\\W]\\w+\\b', 
                       stop_words=frozenset(stopwords))

from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()

X_train_vect = vect.fit_transform(X_train)
nb.fit(X_train_vect, y_train)
train_score = nb.score(X_train_vect, y_train)
print(train_score)
# 0.895363811976819

#模型评估
pred = nb.predict(X_test_vect)
y_test
X_test_vect = vect.transform(X_test)
metrics.precision_score(y_test,nb.predict(X_test_vect)),metrics.recall_score(y_test,pred)
# (0.8984088127294981, 0.9157829070492826)
# 朴素贝叶斯效果还是好一些的

小节

本文仅仅简单介绍了fasttext的使用,可能数据集比较小,又是简单的二分类任务,fasttext优势并没有展现出来,之后会用更大的训练集和多分类任务进行测试。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值