【问题标题】:Training a custom text classification model using spaCy使用 spaCy 训练自定义文本分类模型
【发布时间】:2020-09-07 06:26:03
【问题描述】:

我有以下名为 dataset.csv 的 csv 文件:

is_offensive,text
0,Hi there! My name is oliver
1,Shut up man!
0,What is wrong?
1,Go away idiot!

其中包含 +5000 行类似的注释数据。

第一列is_offensive包含我要预测的标签,第二列text是用于训练的实际文本。

查看 spaCy 文档后,我可以看到,为了训练自己的自定义文本分类模型,训练数据需要如下所示:

TRAINING_DATA = [
    ["Hi there! My name is oliver", {"OFFENSIVE": True}],
    ["Shup up man!", {"OFFENSIVE": True}],
    ["What is wrong?", {"OFFENSIVE": False}],
    ["Go away idiot!", {"OFFENSIVE": True}]
]

我创建了以下方法,解析这个 CSV 文件并以 spaCy 期望的格式返回:

def convert():
    TRAINING_DATA = defaultdict(list)
    # Open CSV file.
    with open('train/profanity/data/profanity_cleaned_data.csv', mode='r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        line_count = 1
        for row in csv_reader:
            if line_count > 0 and line_count < 1000: #Read the first 1000 lines.
                TRAINING_DATA['csv'].append([str(row['text']), {
                    'OFFENSIVE': bool(int(row['is_offensive']))}])
                line_count += 1

    return TRAINING_DATA['csv']

现在,为了训练数据,我只需这样做:

def train():
    output_dir = 'train/profanity/model/'
    TRAINING_DATA = convert()

    nlp = spacy.blank("en")
    category = nlp.create_pipe("textcat")
    category.add_label("OFFENSIVE")
    nlp.add_pipe(category)

    # Start the training
    nlp.begin_training()

    # Loop for 10 iterations
    for itn in range(10):
        # Shuffle the training data
        random.shuffle(TRAINING_DATA)

        # Batch the examples and iterate over them
        for batch in tqdm(spacy.util.minibatch(TRAINING_DATA, size=1)):
            texts = [nlp(text) for text, entities in batch]
            annotations = [{"cats": entities} for text, entities in batch]
            nlp.update(texts, annotations)

    nlp.to_disk(output_dir)
    print("Saved model to", output_dir)

最后,在新文本上测试模型:

def testModel():
    test_text = "You are a very kind person."
    model_dir = 'train/profanity/model/'
    nlp = spacy.load(model_dir)
    doc = nlp(test_text)
    print(test_text, doc.cats)

上述方法testModel()返回:

You are a very kind person. {'OFFENSIVE': 0.9999545812606812}

实际上,无论我使用什么文本作为输入,我以非常接近 100 的置信度返回 OFFENSIVE 标签。但是,正如您在输入文本中看到的那样:You are a very kind person 应该 被归类为OFFENSIVE

我做错了什么?

【问题讨论】:

  • 我看过那个例子(它也发布在他们的Usage Documentation上)。它并没有真正帮助我(或者至少,我个人无法理解)。我看到我只添加了一个标签 (OFFENSIVE),但看到这将是 TrueFalse,我认为这不是问题。

标签: python python-3.x machine-learning nlp spacy


【解决方案1】:

我刚刚遇到了类似的问题。 我改编了 Spacy V2 文档 (https://v2.spacy.io/usage/training#textcat) 中的代码,就像你所做的那样,我只需要一个类,而该示例从一个类中创建了两个具有相反布尔值的类。

事实证明,如果您针对单个班级进行训练,同时还指定班级是排他性的,这似乎会出现问题。

当你创建管道时,你应该指定类不是独占的:

nlp.create_pipe("textcat", config={"exclusive_classes": False, "architecture": "simple_cnn"})

如果 "exclusive_classes" 设置为 True,如果您只有一个类,则需要执行以下操作:

category.add_label("OTHER")

这个“其他”类实际上并没有用在数据标签中。

请注意,如果您使用上面链接的 Spacy 示例之类的评估方法,则需要添加一个条件以跳过“其他”标签(请参阅上面链接上的评估方法):

for label, score in doc.cats.items():
    if label not in gold:
        continue
    if label == "OTHER":
        continue

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 2019-11-15
    • 2021-01-12
    • 2020-10-16
    • 2021-05-15
    相关资源
    最近更新 更多