Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to group all level-2 label, without adding a value for each level-1 label ? #7011

Open
quang-anh-nguyen opened this issue Feb 3, 2025 · 1 comment

Comments

@quang-anh-nguyen
Copy link

quang-anh-nguyen commented Feb 3, 2025

Hello, I am working with hierarchical multi-label classification, with many levels of labels. Here is my label config, assuming that the first level labels are A and B, while the second level labels are A1, A2 and B1, B2, B3.

<View>
  <Text name="text" value="$text"/>
  <View style="box-shadow: 2px 2px 5px #999;
               padding: 20px; margin-top: 2em;
               border-radius: 5px;">
    <Header value="Choose themes present in the text"/>
    <Choices name="theme" toName="text"
             choice="multiple" showInLine="true">
      <Choice value="A"/>
      <Choice value="B"/>
    </Choices>

    <!-- Sub-themes for ESG -->
    <View visibleWhen="choice-selected"
          whenTagName="theme"
          whenChoiceValue="A">
      <Header value="Select sub-themes for A"/>
      <Choices name="A_subtheme" toName="text"
               choice="multiple" showInLine="true">
        <Choice value="A1"/>
        <Choice value="A2"/>
      </Choices>
    </View>

    <!-- Sub-themes for Conformité -->
    <View visibleWhen="choice-selected"
          whenTagName="theme"
          whenChoiceValue="B">
      <Header value="Select sub-themes for B"/>
      <Choices name="B_subtheme" toName="text"
               choice="multiple" showInLine="true">
        <Choice value="B1"/>
        <Choice value="B2"/>
        <Choice value="B3"/>
      </Choices>
    </View>

  </View>
</View>


<!-- {
  "data": {"text": "This is a great 3D movie that delivers everything almost right in your face."}
} -->

And this is an output example with correct labels as A2, B3

[
    {
        "value": {
            "choices": [
                "A",
                "B"
            ]
        },
        "id": "8bcyK27T0I",
        "from_name": "theme",
        "to_name": "text",
        "type": "choices"
    },
    {
        "value": {
            "choices": [
                "B3"
            ]
        },
        "id": "05s0gu-RXH",
        "from_name": "B_subtheme",
        "to_name": "text",
        "type": "choices"
    },
    {
        "value": {
            "choices": [
                "A2"
            ]
        },
        "id": "R3cFXz42dB",
        "from_name": "A_subtheme",
        "to_name": "text",
        "type": "choices"
    }
]

As seen, it includes the second level labels in two different fields named A_subtheme and B_subtheme. My question is if it is possible to configure to merge all the sub-label into a same field, and its value may be either [A2, B3] or a dict {A: A2, B: B3} of some sorts. This will make the process more systematic, instead of having to create a new name for every first-level labels.

If I give them the same name, say subtheme, an error is raised: Label config contains non-unique names

If you have any answers, please let me know. Thank you very much.

@heidi-humansignal
Copy link
Collaborator

Hello,

Thank you for contacting Label Studio,

Label Studio doesn’t currently provide a straightforward way to merge all sub-labels into a single field when using separate <View visibleWhen="choice-selected"> sections. In other words, if you rely on conditions to display sub-labels (e.g. <View ... whenChoiceValue="A"> and <View ... whenChoiceValue="B">), you’ll inevitably end up with separate from_name fields for each group of sub-labels.
Below are two approaches to unify your hierarchical labeling into one output field instead of separate “A_subtheme” and “B_subtheme” fields:


1) Use the <Taxonomy> Tag
A single <Taxonomy> configuration can capture both top-level and sub-level labels in one field:

<View> <Text name="text" value="$text"/> <Taxonomy name="themes" toName="text" leafsOnly="true" maxUsages="10"> <Choice value="A"> <Choice value="A1"/> <Choice value="A2"/> </Choice> <Choice value="B"> <Choice value="B1"/> <Choice value="B2"/> <Choice value="B3"/> </Choice> </Taxonomy></View>
  • How it works: Annotators see a hierarchical tree. If they select A, then they can further pick A1, A2, etc. Because leafsOnly="true", Label Studio only records the final label(s) chosen.
  • Output: All chosen labels (top-level and sub-level) appear in the single "themes" field, simplifying how you parse the results.

2) Nest All Labels Under One <Choices> Tag with allowNested="true"
If you want to stay with <Choices> (rather than <Taxonomy>), you can nest sub-labels under one from_name:

<View> <Text name="text" value="$text"/> <Choices name="themes" toName="text" choice="multiple" showInline="true" allowNested="true"> <Choice value="A"> <Choice value="A1"/> <Choice value="A2"/> </Choice> <Choice value="B"> <Choice value="B1"/> <Choice value="B2"/> <Choice value="B3"/> </Choice> </Choices></View>
  • How it works: All top-level and sub-level labels are grouped in one “themes” control. If an annotator clicks a top-level label, it can expand to show sub-labels.
  • Output: You get a single "themes" entry in your annotation results, typically in a nested list structure. The sub-label(s) selected under each top-level label appear together.
    That said, the nested <Choices> approach behaves a bit differently than visibleWhen logic. For example, sub-labels remain visible once you expand them in the interface. If your team prefers a more typical “expand>pick>collapse” workflow, <Taxonomy> is often more intuitive.

Which Should You Pick?

  • Use <Taxonomy> if you want a clean hierarchical selection that unifies everything into one control and one output array. It was built for hierarchical label structures.
  • Use nested <Choices allowNested="true"> if you need to remain within the <Choices> tag for some reason (e.g., you prefer the user interface it offers). Just keep in mind it yields a nested array structure in your annotations.
    At the moment, there isn’t a built-in trick to keep your separate conditional <View ... whenChoiceValue="A"> blocks while forcing everything into one single output name — each set of <Choices> must have its own unique from_name. But the two approaches above can solve this by collecting everything under one control.
    I
    hope this clarifies how to unify your multiple levels of labels into a single field. Please let me know how it goes or if you have any questions!
    Best regards,

Comment by Oussama Assili
Workflow Run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants