Executando verificação de segurança...
2

Putz isso vai ser extremamente dificil kk

Exemplo: ‘Quanto custa 1kg do seu produto?’ ou ‘Quanto custa 1g do seu produto?’.

Já trabalhei com NLP, sem IA, a sugestão que eu vou dar é baseado no que eu já fiz no passado.

Basicamente tu pode fazer o mesmo que a gente faz com parsing de linguagem de programação (coisa que já fiz também), quebra o texto em tokens, por exemplo:

[str("Quanto"), str("custa"), number("1"), str("kg"), str("do"), str("seu"), str("produto"), str("?")]

Aqui tem várias decisões que você pode fazer também, você pode já no processo de criação de tokens determinar algumas keywords, como as linguagens fazem, e ai tua palavra kg já poderia vir com um tipo diferente:

[str("Quanto"), str("custa"), number("1"), mass_unit(KG, str("kg")), str("do"), str("seu"), str("produto"), str("?")]

ai você pode tirar também as stopwords para simplificar:

[str("Quanto"), str("custa"), number("1"), mass_unit(KG, str("kg")), str("produto"), str("?")]

Detalhe, na hora de armazenar os tokens, a gente não armazena as substrings, só os ranges, isso é crucial para qualquer lexer e parser feito na mão. Exemplo, a palavra custa fica armazenada como Token(range: [7..12], type: Str), e mass_unit ficaria: Token(range: [14..16], type: MassUnit), sem nenhuma string sendo armazenada.

Isso traz muitos ganhos de desempenho, por n ter q copiar string, e pouco custo de memória, pois você está armazenado ali por volta de 3 valores de 64-bit — pelo menos no exemplo que eu forneci com range tendo start e end, e o campo type (no total 3).

Caso queira armazenar um "ponteiro" para essa String (ou string slice), ai seriam 4 campos de 64-bit, mas vai depender se a linguagem copia a String ou apenas referencia ela, ou se suporta ponteiros. Mas isso é só uma conveniência, alguns lexers preferem ter um método get(str) e ai eles retornam a substring a partir daquela string que foi passada ao metodo, ou seja, eles esquecem completamente o input e só trabalham com ranges.

Depois tu meio que vai ter duas opções, você pode fazer um matching na mão com lookahead e lookbehind (era o que a gente fazia), ou já pode progredir para um sistema de regras e criar uma estrutura composta (ou uma Syntax Tree simplificada), um exemplo de regra seria (em pseudo-EBNF e bem simplificada mesmo):

texts    = text+ ;
text     = mass | massUnit | str ;
mass     = NUMBER, massUnit ;
massUnit = KG | G ;
str      = ALPHA

KG     = "kg" | "kilograma" | "quilograma";
G      = "g"  | "grama";
NUMBER = [0-9]+;
ALPHA  = [A-Za-z]+;

E ai no final você teria uma estrutura de dados tipo assim:

texts([text(str("Quanto")), text(str("custa")), mass(number(1), mass_unit(KG)), text(str("produto")), text(str("?"))])

Com isso você já pode fazer muita coisa, ai deixo para sua imaginação kkkk, não conheço o Pinecone e nem se seria possível fazer ele não comparar trechos do texto, outra opção seria fazer obfuscação com um hash dos trechos com unidades de medida, por exemplo:

Quanto custa LztgJ2EO8YcNEcjipENcYA do seu produto?

E ai qualquer pequena mudança nesse trecho já afetaria a distância de forma perceptível.

Só que o que eu acho que é mais dificil é na verdade outras coisas, até aritmética daria para fazer esse tricky que eu comentei, mas teriam muitos corner cases, você teria que fazer a mesma ideia com estados, tipo SP e SC são muito próximos, depois água e águia, e assim por diante. Seria possível minar todos os casos e classificar? Não, mas com o tempo conseguiria diminuir bastante os corner cases e deixa-los mais raros. E teria q ter uma forma de fazer isso com agilidade e de capturar quando isso ocorre também (Levenshtein distance caberia aqui para você logar os casos), e levaria muito tempo — os mais comuns seriam faceis, o resto teria que ser na base do uso e descoberta.

Carregando publicação patrocinada...
2

valeu @jhrl. meu exemplo foi ficticio mas acredito que seu comentário pode ajudar muita gente.
Na minha cabeça eu tinha algo utilizando o https://spacy.io/ ou https://www.nltk.org/. Mas não tinha pensado nada tão avançado como você exemplificou.
Acho que para identificar os termos, algo voltado a nltk e depois dar os pesos como você mensionou, pode resultar em algo bem bacana.

1

Interessante, os dois parecem usar Phrase structure rules.

Tu pegou um baita desafio e achei super interessante a proposta, não acho que seja impossível, mas de fato vai ser isso ai, vai ter q empregar várias técnicas e ter umas sacadas de gênio. Admiro bastante essa determinação, fiquei curioso para o desfecho também.