html文本分类输出,NLP哪里跑: 文本分类工具一览 · ZMonster's Blog

本文介绍了如何使用AllenNLP配置文件快速搭建文本分类模型,涉及数据处理(如jieba分词)、模型选择(基本_classifier与CNN编码)及训练设置。重点讲解了如何自定义中文分词器以处理中文数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AllenNLP 完全通过配置文件来对数据处理、模型结果和训练过程进行设置,最简单的情况下可以一行代码不写就把一个文本分类模型训练出来。下面是一个配置文件示例:

{

"dataset_reader": {

"type": "text_classification_json",

"tokenizer": {

"type": "word",

"word_splitter": {

"type": "jieba",

}

}

},

"train_data_path": "allen.data.train",

"test_data_path": "allen.data.test",

"evaluate_on_test": true,

"model": {

"type": "basic_classifier",

"text_field_embedder": {

"tokens": {

"type": "embedding",

"embedding_dim": 100,

"trainable": true

}

},

"seq2vec_encoder": {

"type": "cnn",

"embedding_dim": 100,

"num_filters": 1,

"ngram_filter_sizes": [2, 3, 4]

}

},

"iterator": {

"type": "bucket",

"sorting_keys": [["tokens", "num_tokens"]],

"batch_size": 64

},

"trainer": {

"num_epochs": 40,

"patience": 3,

"cuda_device": -1,

"grad_clipping": 5.0,

"validation_metric": "+accuracy",

"optimizer": {

"type": "adam"

}

}

}

配置文件中的内容可以分成

数据部分: 包括 dataset_reader/train_data_path/test_data_path 这几个 key 及其 value

模型部分: 就是 model 这个 key 的内容

训练部分: 包括 evaluate_on_test/iterator/trainer 这几个 key 及其 value

由于本文不是专门介绍 AllenNLP 的文章,所以只对这些配置做简要说明,详细内容可查看文档。

数据部分

train_data_path 和 test_data_path 比较好理解,它们指定了训练数据和测试数据的文件路径;而 data_reader 则限定了数据文件的格式。

data_reader 中的配置,会被用来构建一个 DatasetReader 的子类的对象,用来读取数据并转换成一个个 Instance 对象。

内置的可用来读取分类数据的 DataReader 是 TextClassificationJsonReader ,所以配置中有

"type": "text_classification_json"

这个 type 的值是 TextClassificationJsonReader 这个类实现的时候注册上的,去看代码会看到有这样的片段

@DatasetReader.register("text_classification_json")

class TextClassificationJsonReader(DatasetReader):

这个 TextClassificationJsonReader 要求的数据文件是一行一个 json 数据,如下:

{"label": "education", "text": "名师指导托福语法技巧:名词的复数形式"}

{"label": "education", "text": "中国高考成绩海外认可是“狼来了”吗?"}

{"label": "sports, "text": "图文:法网孟菲尔斯苦战进16强孟菲尔斯怒吼"}

{"label": "sports, "text": "四川丹棱举行全国长距登山挑战赛近万人参与"}

DataReader 通过配置中 tokenizer 部分会创建一个分词器,用来将文本转换为词序列

"tokenizer": {

"type": "word",

"word_splitter": {

"type": "jieba",

}

}

type 的值设置为 word,这没什么好说的。

tokenizer 中的 word_splitter 指定的才是真正的分词器(比较绕)。

如果是英文的数据,那么 word_splitter 的配置可以不写,默认就是支持英文分词的。

但如果是用于中文处理的话,有一个 SpacyWordSplitter 可以用于中文分类,但是现有的中文 spaCy 模型仅支持 spaCy 2.0.x,和 AllenNLP 中 spaCy 要求的版本不兼容,这个是比较坑的。

好在 AllenNLP 提供了加载自定义模块的方法,按照如下方法来处理这个问题

mkdir allen_ext/

touch allen_ext/__init__.py

touch allen_ext/word_splitter.py

然后在 allen_ext/word_splitter.py 中写入如下内容

from typing import List

import jieba

from overrides import overrides

from allennlp.data.tokenizers.token import Token

from allennlp.data.tokenizers.word_splitter import WordSplitter

@WordSplitter.register('jieba')

class JiebaWordSplitter(WordSplitter):

def __init__(self):

pass

@overrides

def split_words(self, sentence: str) -> List[Token]:

offset = 0

tokens = []

for word in jieba.lcut(sentence):

word = word.strip()

if not word:

continue

start = sentence.find(word, offset)

tokens.append(Token(word, start))

offset = start + len(word)

return tokens

使用 WordSplitter.register('jieba') 后就可以在配置中 word_splitter 部分写上 "type": "jieba" 来启用。

在 allen_ext/__init__.py 中写入如下内容

from .word_splitter import JiebaWordSplitter

__all__ = ['JiebaWordSplitter']

自定义了 JiebaWordSplitter 后在训练的时候还要加载 allen_ext 这个目录才能生效,这个之后再说。

模型部分

因为是做文本分类,所以 type 设置为 basic_classifier。

这个分类器需要 text_field_embedder 和 seq2vec_encoder 两个参数:

text_field_embedder 用来定义 word embedding,这个配置应该还好理解

"text_field_embedder": {

"tokens": {

"type": "embedding",

"embedding_dim": 100,

"trainable": true

}

}

seq2vec_encoder 则用来产生句子的编码向量用于分类,这里选择了 CNN

"seq2vec_encoder": {

"type": "cnn",

"embedding_dim": 100,

"num_filters": 1,

"ngram_filter_sizes": [2, 3, 4]

}

训练部分:略

配置文件写好后,假设配置文件为 config.json,直接执行下面的命令来训练即可

allennlp train config.json -s model_save_dir --include-package allen_ext

选项 --include-package allen_ext 用来来加载自定义的模块。

最终会在 save_dir 目录下产生一个 model.tar.gz 文件,就是模型参数,然后目录下还会产生 tensorboard 能读取的 log,这个挺方便的。

评估的话,用 evaluate 命令

allennlp evaluate model_save_dir/model.tar.gz test.jsonl --include-package allen_ext

比较麻烦的是,预测需要一个 Predictor,而 AllenNLP 中内置的 TextClassifierPredictor 要求的输入是 {"sentence": "xxx"} ,这个和 TextClassificationJsonReader 的要求不一样……

如果是在代码里进行预测,那么是没有问题的,可以这样

from allen_ext import * #noqa

from allennlp.models.archival import load_archive

from allennlp.predictors.predictor import Predictor

archive = load_archive('model_save_dir/model.tar.gz')

predictor = Predictor.from_archive(archive)

inputs = {"sentence": "名师指导托福语法技巧:名词的复数形式"}

result = predictor.predict_json(inputs)

得到的 result 是这样的结构

{

'label': 'education',

'logits': [

15.88630199432373,

0.7209644317626953,

7.292031764984131,

5.195938587188721,

5.073373317718506,

-35.6490478515625,

-7.7982988357543945,

-35.44648742675781,

-18.14293098449707,

-14.513381004333496

],

'probs': [

0.999771773815155,

2.592259420453047e-07,

0.0001851213601185009,

2.2758060367777944e-05,

2.013285666180309e-05,

4.153195524896307e-23,

5.1737975015342386e-11,

5.085729773519049e-23,

1.6641527142180782e-15,

6.273159211056881e-14

],

}

这个输出结构完全是由 TextClassifierPredictor 决定的。

如果要自定义 Predictor,可以参考文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值