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

[Help] Slot Fill in middle of text #1263

Open
guilhermelirio opened this issue Jan 27, 2023 · 6 comments
Open

[Help] Slot Fill in middle of text #1263

guilhermelirio opened this issue Jan 27, 2023 · 6 comments

Comments

@guilhermelirio
Copy link

guilhermelirio commented Jan 27, 2023

I have 2 entities below:

entities: {
  frase: {
    trim: [
      {
        position: "betweenLast",
        leftWords: [
          "falar"
        ],
        rightWords: [
          "na"
        ]
      },
      {
        position: "afterLast",
        words: [
          "falar"
        ]
      }
    ]
  },
  voz: {
    trim: [
      {
        position: "betweenLast",
        leftWords: [
          "na voz do",
          "na voz da",
          "na voz de"
        ],
        rightWords: [
          "falar"
        ]
      },
      {
        position: "afterLast",
        words: [
          "na voz do",
          "na voz da",
          "na voz de"
        ]
      }
    ]
  }
}

When I say the phrase: "falar testando, 1 2 3 na voz do chaves" the slot works normally.

But I have a problem: when a user types the following sentence: "Minha secretária pediu um aumento, mas não posso dar. Me descreva 5 motivos para falar isso para ela de forma bem delicada." is falling into that slot, where the correct thing would be to fall into None.

How do I fix this slot to accept only when it starts with the word "falar"?

@Apollon77
Copy link
Contributor

Can you please share the exact return in the entities array? ALso in which of the tweo slots that sentence "falls into"?
ALso Which versio of nlp.js you use? Please provide more information and details

@Apollon77
Copy link
Contributor

Apollon77 commented Jan 27, 2023

PS: Additionally: you know that in trim rules are all "standing for themself", so it is not a "combination", means in your case you have two entitied and they have both TWO options to be matched. (they are kind of "OR" connected). To add an "AND" logic there (which indeed might be a cool idea) this would be more a feature request.

I would expect (I did not tried it!) for your sentence the following result:

  • frase - betweenLast rule ... not matched because no "na" is in
  • frase - afterLast rule ... should be matched with "isso para ela de forma bem delicada." as content
  • voz should never match because you put "several words" into a string that should match to single words. Currently these are really "tokens" that are checked there and not strings
    So if the results are as I would expect them the library works "as designed"

Also to allow "phrases" (aka multiple words in a defined order) in lef/rightwords would be a feature request.

@guilhermelirio
Copy link
Author

guilhermelirio commented Jan 27, 2023

Can you please share the exact return in the entities array? ALso in which of the tweo slots that sentence "falls into"?
ALso Which versio of nlp.js you use? Please provide more information and details

nlp.js Version
"@nlpjs/basic": "^4.25.0",

Corpora:

{
    "name": "Intents",
    "locale": "pt-BR",
    "data": [
        {
            "intent": "DalleIntent",
            "utterances": [
                "uma imagem",
                "gerar uma imagem",
                "uma imagem de",
                "uma foto",
                "uma foto de",
                "me dá uma imagem",
                "me dá uma imagem de",
                "me dá uma foto",
                "me dá uma foto de",
                "quero uma imagem",
                "gere uma imagem",
                "gere uma foto",
                "imagem"
            ],
            "answers": [
                "Tudo bem, estou gerando uma imagem!",
                "Aguarde enquanto crio a sua imagem."
            ]
        },
        {
            "intent": "HelloIntent",
            "utterances": [
                "oi",
                "olá",
                "ei",
                "alô",
                "oie",
                "oi tudo bem"
            ],
            "answers": [
                "Olá, como posso te ajudar?"
            ]
        },
        {
            "intent": "InWorldIntent",
            "utterances": [
                "falar com chucky"
            ],
            "answers": [
                "Agora você está conversando com o Chucky!"
            ]
        },
        {
            "intent": "FalatronIntent",
            "utterances": [
                "falar @frase na voz do @voz",
                "falar @frase na voz da @voz",
                "falar @frase na voz de @voz"
            ],
            "answers": [
                "Tudo bem, estou gerando o seu áudio do/da {{voz}}: {{frase}}.",
                "Aguarde enquanto crio o seu áudio do/da {{voz}}: {{frase}}."
            ],
            "slotFilling": {
                "voz": {
                    "mandatory": true,
                    "question": "De qual voz?"
                },
                "frase": {
                    "mandatory": true,
                    "question": "Qual o texto?"
                }
            }
        },
        {
            "intent": "None",
            "utterances": [
                ""
            ],
            "answers": [
                "Desculpe, mas não entendi o que disse. Repita, por favor."
            ]
        },
        {
            "intent": "SairIntent",
            "utterances": [
                "sair",
                "cancelar"
            ],
            "answers": [
                "Tudo bem, até mais!"
            ]
        },
        {
            "intent": "HelpIntent",
            "utterances": [
                "ajuda",
                "quero ajuda",
                "preciso de ajuda"
            ],
            "answers": [
                "Claro, irei te ajudar! \n - Se você deseja gerar uma imagem, só escrever: gere uma imagem <conteúdo> / quero uma imagem <conteúdo>. \n - Se você deseja que eu crie uma imitação do Chaves por exemplo, é só escrever: falar <texto da imitação> na voz do chaves (só substiruir o chaves por algum outro personagem). \n - Se deseja qualquer outra coisa, é só esrever mesmo!"
            ]
        },
        {
            "intent": "IaraDigitalIntent",
            "utterances": [
                "quem é iara",
                "me conta sobre iara"
            ],
            "answers": [
                "Iara Digital é uma agência baseada em São Paulo que acredita no poder das experiências centradas em voz.  O nosso nome vem do folclore Tupi-Guarani brasileiro. Iara é uma sereia que vive nas águas do Rio Amazonas.  Quando ela vê um homem na floresta, ela começa a cantar para encantá-lo. Uma vez sob o feitiço de Iara, o homem larga qualquer coisa para viver com ela embaixo da água para sempre."
            ]
        }
    ],
    "entities": {
        "frase": {
            "trim": [
                {
                    "position": "betweenLast",
                    "leftWords": [
                        "falar"
                    ],
                    "rightWords": [
                        "na"
                    ]
                },
                {
                    "position": "afterLast",
                    "words": [
                        "falar"
                    ]
                }
            ]
        },
        "voz": {
            "trim": [
                {
                    "position": "betweenLast",
                    "leftWords": [
                        "na voz do",
                        "na voz da",
                        "na voz de"
                    ],
                    "rightWords": [
                        "falar"
                    ]
                },
                {
                    "position": "afterLast",
                    "words": [
                        "na voz do",
                        "na voz da",
                        "na voz de"
                    ]
                }
            ]
        }
    }
}

My Sample Code:

const { dockStart } = require('@nlpjs/basic');

(async () => {
    const dock = await dockStart();
    const nlp = dock.get('nlp');
    await nlp.train();
    const response = await nlp.process('pt', 'Minha secretária pediu um aumento, mas não posso dar. Me descreva 5 motivos para falar isso para ela de forma bem delicada.');

    console.log(JSON.stringify(response));
})();

conf.json

{
    "settings": {
        "nlp": {
            "forceNER": true,
            "languages": [
                "pt"
            ],
            "corpora": [
                "./intents.json"
            ]
        }
    },
    "use": [
        "Basic",
        "LangPt"
    ]
}

Return:

{
  "locale": "pt",
  "utterance": "Minha secretária pediu um aumento, mas não posso dar. Me descreva 5 motivos para falar isso para ela de forma bem delicada.",
  "languageGuessed": false,
  "localeIso2": "pt",
  "language": "Portuguese",
  "nluAnswer": {
    "classifications": [
      {
        "intent": "FalatronIntent",
        "score": 0.465536644040642
      },
      {
        "intent": "None",
        "score": 0.2582708877945899
      },
      {
        "intent": "InWorldIntent",
        "score": 0.22199608769066007
      },
      {
        "intent": "IaraDigitalIntent",
        "score": 0.05419638047410807
      }
    ]
  },
  "classifications": [
    {
      "intent": "FalatronIntent",
      "score": 0.465536644040642
    },
    {
      "intent": "None",
      "score": 0.2582708877945899
    },
    {
      "intent": "InWorldIntent",
      "score": 0.22199608769066007
    },
    {
      "intent": "IaraDigitalIntent",
      "score": 0.05419638047410807
    }
  ],
  "intent": "FalatronIntent",
  "score": 0.465536644040642,
  "domain": "default",
  "optionalUtterance": "Minha secretária pediu um aumento, mas não posso dar. Me descreva 5 motivos para falar @frase",
  "sourceEntities": [
    
  ],
  "entities": [
    {
      "type": "trim",
      "subtype": "afterLast",
      "start": 87,
      "end": 122,
      "len": 36,
      "accuracy": 0.99,
      "sourceText": "isso para ela de forma bem delicada.",
      "utteranceText": "isso para ela de forma bem delicada.",
      "entity": "frase"
    }
  ],
  "slotFill": {
    "localeIso2": "pt",
    "intent": "FalatronIntent",
    "entities": [
      {
        "type": "trim",
        "subtype": "afterLast",
        "start": 87,
        "end": 122,
        "len": 36,
        "accuracy": 0.99,
        "sourceText": "isso para ela de forma bem delicada.",
        "utteranceText": "isso para ela de forma bem delicada.",
        "entity": "frase"
      }
    ],
    "currentSlot": "voz"
  },
  "srcAnswer": "De qual voz?",
  "answers": [
    {
      "answer": "Tudo bem, estou gerando o seu áudio do/da {{voz}}: isso para ela de forma bem delicada.."
    },
    {
      "answer": "Aguarde enquanto crio o seu áudio do/da {{voz}}: isso para ela de forma bem delicada.."
    }
  ],
  "answer": "De qual voz?",
  "actions": [
    
  ],
  "sentiment": {
    "score": 6,
    "numWords": 22,
    "numHits": 7,
    "average": 0.2727272727272727,
    "type": "afinn",
    "locale": "pt",
    "vote": "positive"
  }
}

@Apollon77
Copy link
Contributor

Ok, so my assumptions were right what is matched and so the description is above

@guilhermelirio
Copy link
Author

Thanks @Apollon77 /

Do you have any more examples of using trim?

@Apollon77
Copy link
Contributor

maybe https://github.com/axa-group/nlp.js/blob/master/docs/v4/ner-manager.md#trim-entities gives some more context

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