# Hierarchical labels

**URL:** <https://support.prodi.gy/t/hierarchical-labels/6545>\
**Category:** Uncategorized\
**Created:** [May 13, 2023, 4:45am UTC](https://support.prodi.gy/t/hierarchical-labels/6545 "2023-05-13T04:45:32Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![russel](https://avatars.discourse-cdn.com/v4/letter/r/ee7513/32.png) [@russel](https://support.prodi.gy/u/russel)\
**Post date:** [May 13, 2023, 4:45am UTC](https://support.prodi.gy/t/hierarchical-labels/6545/1 "2023-05-13T04:45:32Z")

</div>

Can you help create a custom recipe with hierarchical labels?

Specifically my hierarchy would look like the following with 3 levels in each category:

Politics  
- Asia  
-- elections  
-- foreign  
- Europe  
-- local  
-- election  
-- finance  
- America  
-- business  
-- finance  
Sports  
- Team  
-- football  
-- baseball  
- Individual  
-- golf  
-- tennis

This is sample example.jsonl has the following two records to annotate:

{ "text": "Cyber researchers have linked the vulnerability exploited by the latest ransomware to “WannaCry”. Both versions of malicious software rely on weaknesses discovered by the National Security Agency years ago, Kaspersky said." }

{ "text": "Java J\*\*\*\*EE Developer \*\*\*\*k **k Music, Film & TV London Java J** EE Developers required for software house with client sectors of music, film and TV. Salary: Maximum \*\*\*\*: Discretionary bonus and benefits package. Location: Near Euston and King's Cross, London THE COMPANY: Consistent new business wins for the world leader in the provision of software solutions to the Music and Entertainment industry has given rise to the need for an experienced Java Developer. The working environment here is very pleasant with a casual dress code, laid back and friendly atmosphere"}

My recipe file looks as follows:

```python
import prodigy

LABEL_HIERARCHY = {
    "CATEGORY": {
        "Politics": {
            "Asia": {
                "elections":{},
                "foreign":{}
            },
            "Elections": {
                "A":{}, 
                "B":{}
            }
        }
    }
}

def add_label_hierarchy(examples):
    for eg in examples:
        eg["hierarchy"] = LABEL_HIERARCHY
    return examples

@prodigy.recipe('hierarchy_recipe')
def hierarchy_recipe(dataset, source):
    stream = prodigy.get_stream(source)
    stream = add_label_hierarchy(stream)
    return {
        'dataset': dataset,
        'stream': stream,
        'view_id': 'hierarchy_recipe',
        'config': {
            'labels': None
        }
    }

@prodigy.serve('hierarchy_recipe')
def hierarchy_recipe():
    html_template = """
        <div style="font-size: 16px">
            <p>Text: <strong>{{text}}</strong></p>
            <p>Labels:</p>
            <ul>
            {% for level1 in hierarchy %}
                <li>{{ level1 }}
                    {% if hierarchy[level1] %}
                        <ul>
                        {% for level2 in hierarchy[level1] %}
                            <li>{{ level2 }}
                                {% if hierarchy[level1][level2] %}
                                    <ul>
                                    {% for level3 in hierarchy[level1][level2] %}
                                        <li><input type="checkbox" name="{{ level1 }}|{{ level2 }}|{{ level3 }}" value="accept">{{ level3 }}</li>
                                    {% endfor %}
                                    </ul>
                                {% endif %}
                            </li>
                        {% endfor %}
                        </ul>
                    {% endif %}
                </li>
            {% endfor %}
            </ul>
        </div>
    """
    return {'html_template': html_template}

```

I am running this command: prodigy hierarchy\_recipe -F hierarchy\_recipe.py test\_dataset example.jsonl

Getting this error: usage: prodigy hierarchy\_recipe [-h] dataset source

prodigy hierarchy\_recipe: error: the following arguments are required: dataset, source

---

<div class="post-metadata">

**Author:** ![russel](https://avatars.discourse-cdn.com/v4/letter/r/ee7513/32.png) [@russel](https://support.prodi.gy/u/russel)\
**Post date:** [May 13, 2023, 6:00am UTC](https://support.prodi.gy/t/hierarchical-labels/6545/3 "2023-05-13T06:00:49Z")

</div>

I have tried this recipe as well, but getting error: AttributeError: module 'prodigy.components.printers' has no attribute 'print\_total\_annotations'

```python
import prodigy
from prodigy.components import printers
from prodigy.util import log

LABELS = {
    "Politics": {
        "Asia": ["elections", "foreign"],
        "Europe": ["local", "election", "finance"],
        "America": ["business", "finance"]
    },
    "Sports": {
        "Team": ["football", "baseball"],
        "Individual": ["golf", "tennis"]
    }
}

@prodigy.recipe("hierarchical_labels",
    dataset=("The dataset to use", "positional", None, str),
    source=("The source data as a JSONL file", "positional", None, str))
def hierarchical_labels(dataset, source):
    def update(examples):
        for eg in examples:
            # add an empty "label" property to each example
            eg["label"] = ""
        return examples

    stream = prodigy.get_stream(source)
    stream = update(stream)
    
    return {
        "dataset": dataset,
        "stream": stream,
        "view_id": "classification",
        "config": {
            "labels": LABELS,
            "choice_style": "multiple",
            "instructions": "Categorize the text into one or more categories"
        },
        "update": update,
        "on_exit": printers.print_total_annotations,
        "log_level": log.WARNING
    }

```

---

<div class="post-metadata">

**Author:** ![ryanwesslen](https://sea2.discourse-cdn.com/flex020/user_avatar/support.prodi.gy/ryanwesslen/32/2969_2.png) [@ryanwesslen](https://support.prodi.gy/u/ryanwesslen)\
**Post date:** [May 15, 2023, 7:57pm UTC](https://support.prodi.gy/t/hierarchical-labels/6545/4 "2023-05-15T19:57:49Z")

</div>

hi @russel!

Thanks for your question and welcome to the Prodigy community 👋

> [@russel](#):
>
> error: AttributeError: module 'prodigy.components.printers' has no attribute 'print\_total\_annotations'

You're getting this error because there doesn't exist an attribute named `print_total_annotations` 🙂

Just curious - did you create these Prodigy recipes from a generative model like ChatGPT? I ask b/c I noticed some weird things with them. For example, some of the config keys don't exist like `"log_level"`, `"config": {"labels": ...` or are used incorrectly (e.g., `"instructions"` is a `true` or `false`).

We have other posts that suggest the best way to do this is multiple passes (e.g., start with top level, then confirm bottom level).

> [@Hierarchal text classification trouble shooting](https://support.prodi.gy/t/hierarchal-text-classification-trouble-shooting/4557/4):
>
> Sorry for the late reply here. For hierarchical text classification we typically recommend doing multiple passes over the dataset for each level of the hierarchy. This discussion thread has a lot of good info on this idea: [Two levels of classifications for text classifications - #2 by ines](https://support.prodi.gy/t/two-levels-of-classifications-for-text-classifications/3514/2) If you really want to try this async workflow, it is not very straightforward with Prodigy. Internally, Prodigy uses Python generators for the "stream". Prodigy then pulls a batch of examples at a time to be…

Let me know if this makes sense.

---

<div class="post-metadata">

**Author:** ![russel](https://avatars.discourse-cdn.com/v4/letter/r/ee7513/32.png) [@russel](https://support.prodi.gy/u/russel)\
**Post date:** [May 16, 2023, 5:44pm UTC](https://support.prodi.gy/t/hierarchical-labels/6545/5 "2023-05-16T17:44:29Z")

</div>

Thank you Ryan, and yes you are right I tried with the GPT first to get started.

I am trying to make a 3 level-hierarchical list of keywords for the annotators to tag each data stream. When a annotator selects first level keyword, it expands to the next level and so on the front-end.
