3
$\begingroup$

Just as I was warned, the documentation in SpaCy is a bit difficult to read. I don't have a software-engineer / CS background, so I'm really struggling with this.

I would like to use SpaCy's textcat_multilabel (tm). I have figured out how to setup the config, and how to train the data w/o CLI. I also know that tm wants SpaCy's own binary format for the training data (and dev == validation data). I know that I'm supposed to use DocBin, but I do not know how to do this. I couldn't find anything here that tells me how the classifier even wants the data, how to tell the classifier which are features and which are the labels, how to supply the labels (since it's multilabel, not so obvious to me, the few tutorials I saw were multiclass not multilabel).

If someone can point out to me how to do this it would be wonderful. Or even just point me towards the right direction.

$\endgroup$
1
  • $\begingroup$ Probably after this I would also ask how to tune the model, I figured since its a CNN there would be a threshold that I would need to tune. Then how to change the loss function. Then, if I can get numerical values (prediction_proba) so that I can rank the labels. But I suppose this should be another question. $\endgroup$ Commented Apr 19, 2023 at 12:01

1 Answer 1

2
$\begingroup$

In the official Explosion demo repository, you can find a sample JSONL file where each line is a sample input with multiple labels (categories), each label is marked with 0.0 or 1.0. That is, if your input should contain that label, you mark it with 1.0, otherwise, 0.0:

{"text":"Moving from MySQL to Hybrid SQL","cats":{"DOCUMENTATION":0.0,"OTHER":1.0}}

In this particular case, you see two labels (categories), but nothing prevents you from adding another category, e.g. "SOME OTHER LABEL / CATEGORY": 1.0.

For more information about JSONL format, please see: https://jsonlines.org.

In the same repository, you'll also see convert.py script that demonstrates how to convert such a JSONL file into spaCy's binary DocBin format that can be used by spaCy's training system:

"""Convert textcat annotation from JSONL to spaCy v3 .spacy format."""
import srsly
import typer
import warnings
from pathlib import Path

import spacy
from spacy.tokens import DocBin


def convert(lang: str, input_path: Path, output_path: Path):
    nlp = spacy.blank(lang)
    db = DocBin()
    for line in srsly.read_jsonl(input_path):
        doc = nlp.make_doc(line["text"])
        doc.cats = line["cats"]
        db.add(doc)
    db.to_disk(output_path)


if __name__ == "__main__":
    typer.run(convert)

I believe this should be enough for you to get started encoding your text input with whatever labels you want. The important thing is that, every single entry (e.g. line in JSONL file) should have all of the labels and then for the labels that are not associated with that input you should mark them with 0.0, otherwise 1.0.

You might ask: "but why should I start with JSONL?". You don't have to! If you want, of you course you can directly in your Python code create some text data and its related labels, and directly convert these to DocBin and save that, but I generally find it more convenient and human-readable to first have that data stored as JSONL file.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.