Classificando receitas usando PNL e regressão logística

Jan 24 2023
O mundo do processamento de linguagem natural cresceu rapidamente nos últimos dois anos. Recentemente, vimos o lançamento e o incrível poder do ChatGPT lançado pela OpenAI, que foi baseado no GPT 3, um revolucionário modelo de linguagem AI capaz de produzir texto semelhante ao humano.

O mundo do processamento de linguagem natural cresceu rapidamente nos últimos dois anos. Recentemente, vimos o lançamento e o incrível poder do ChatGPT lançado pela OpenAI, que foi baseado no GPT 3, um revolucionário modelo de linguagem AI capaz de produzir texto semelhante ao humano. Também existem modelos de linguagem empregados por grandes empresas de tecnologia como o Google, que criou o modelo de linguagem BERT e atualmente é usado para processar consultas em inglês na Pesquisa do Google.

Neste artigo, forneceremos a você um forte entendimento dos fundamentos do NLP, especificamente matrizes de frequência de documento inverso de frequência de termo (tf-idf) e como elas podem ser aplicadas em aplicativos de previsão, como regressão logística. Você também aprenderá sobre diferentes métodos que pode usar para melhorar suas pontuações/previsões de precisão no aprendizado de máquina!

Neste artigo, estaremos prevendo os tipos de culinária a partir de listas de ingredientes usando regressão logística. É baseado neste projeto guiado da IBM Skills Network

Passo 1: Processando os dados usando NLP

Qualquer bom cientista de dados sabe que a qualidade dos dados é muito importante. Isso significa ter pontos de dados representativos do assunto que você está estudando, ser capaz de interpretar os dados e extrair informações importantes para o seu trabalho e processar esses dados de forma que você possa usar todo o seu potencial.

Neste cenário, estamos analisando os dados da receita. Vamos dar uma olhada primeiro para entender com o que estamos trabalhando!

Ao amostrar 5 linhas de nosso conjunto de dados, podemos ver que temos três partes de dados para começar:

  • id: o identificador de uma receita específica
  • cozinha: o tipo de cozinha a que uma receita específica pertence
  • ingredientes: uma lista de ingredientes em uma receita específica armazenada como uma string

O que você gostaria de analisar a seguir? Eu pessoalmente gostaria de examinar todas as cozinhas e como meu conjunto de dados de receitas é distribuído pelas cozinhas. Isso ajuda a ter uma boa ideia de como meus dados são abrangentes e me permite prever como meu modelo pode funcionar com eles. (Para cozinhas com poucas receitas, acho que meu modelo não seria muito bom em prever a participação nessas cozinhas)

Isso parece bem interessante! Vemos que temos MUITA culinária italiana e mexicana, mas pouquíssimas receitas russas, brasileiras e jamaicanas.

Ok, com isso fora do caminho, vamos passar para os ingredientes. Como você pensaria em usar os ingredientes para classificar as cozinhas?

Inicialmente, você pode pensar em simplesmente dividir os ingredientes em suas próprias colunas e simplesmente usar uma variável indicadora (1 ou 0) para mostrar qual ingrediente pertence a qual prato. Isso parece uma boa ideia, até você perceber que cada ingrediente pode ser único. Por exemplo, uma receita pode usar suco de limão fresco , mas outra pode usar suco de limão e outra pode usar suco de limão processado . Algumas receitas levam sal e pimenta-do-reino moída, enquanto outras levam sal grosso ou sal, pimenta-do-reino moída.Se você decidisse expandir cada ingrediente da lista e criar uma variável/coluna para cada um, rapidamente teria muitas colunas para lidar, sem contar que muitas dessas colunas só vão se referir a uma única receita!

Tudo bem então, o que devemos fazer?

Entre na PNL. Uma das tarefas mais básicas do NLP é a tokenização, que simplesmente dividirá um vetor de strings em tokens. Um exemplo de token é uma palavra. Mas um token também pode ser coarse salt, conhecido como 2-gram . Um token pode ter n gramas de comprimento, o que significa simplesmente que ele possui n palavras/strings separadas dentro dele.

O que faremos é aplicar um tokenizer de sklearn.feature_extraction.textchamado CountVectorizer. Tem um argumento, ngram_rangeque podemos usar para limitar o número de palavras em um determinado ingrediente. Se definirmos como (1,2), então nosso CountVectorizerolhará para apenas uma ou duas palavras por vez, como chickene chicken broth, mas não fat free less sodium chicken broth.

Podemos ver que esta matriz é bastante esparsa. Isso significa que existem muitos valores iguais a 0, que ocupam espaço e não fornecem nenhum valor. Você também pode ver que CountVectorizerordenou nossos tokens em ordem alfabética.

Qual é o nosso objetivo com isso? Lembre-se de que queríamos processar os dados para extrair informações importantes e processar esses dados de forma que você possa usar todo o seu potencial. Como devemos processar ainda mais essa matriz de receitas e ingredientes tokenizados?

Podemos ver claramente que existem alguns recursos como alle whitee bayque claramente não representam ingredientes. Na verdade, essas variáveis ​​não ajudam em nada nossa análise e podem ser removidas com segurança. Se examinarmos todos os tokens produzidos, cv.get_feature_names_out()podemos selecionar manualmente certos recursos que queremos excluir.

Agora que concluímos o processamento de dados (muito trabalho, eu sei, mas também uma das partes mais importantes da ciência de dados), podemos prosseguir para o treinamento de um modelo.

Nota: Outra matriz popular para usar em NLP é a matriz tf-idf , que representa o termo frequência — matriz de frequência de documento inverso . Essa matriz aumenta os termos na matriz de frequência de termos de forma que palavras mais importantes/especiais para um determinado documento tenham valores mais altos do que palavras que ocorrem muito, como “o” ou “e” . Usando esta matriz, você pode criar incorporações de documentos mais significativas, o que pode ajudar em vários aplicativos que requerem representações precisas de documentos.

É claro que precisamos dividir os dados em dados de treinamento e teste,

x_train, x_test, y_train, y_test = train_test_split(df_vectorized, df[‘cuisine’], test_size=0.25, random_state=1, stratify=df[‘cuisine’])

Onde:

  1. df_vectorizedrepresenta os recursos que prevemos (variáveis ​​independentes/explicativas)
  2. df['cuisine']representa a variável que queremos prever (variável dependente/alvo)
  3. Definimos o conjunto de teste como 25% de todo o conjunto de dados
  4. A random_stateajuda a garantir que as receitas que vão no conjunto de teste e as que vão no conjunto de treinamento permaneçam as mesmas em várias execuções para garantir a consistência
  5. A estratificação garante que a distribuição das diferentes cozinhas seja uniforme entre os dados de teste e treinamento. Se não fizéssemos isso, o conjunto de teste poderia estar cheio de receitas russas, enquanto os dados de treinamento não conteriam nenhuma e nosso modelo teria um desempenho muito ruim.

O cerne deste projeto é a regressão logística, que é o que usaremos para classificar os pratos em seus distintos tipos de culinária. Não vou repassar a teoria por trás da regressão logística, pois ela é perfeitamente explicada neste artigo da IBM .

O que você precisa saber é que, dada uma matriz N por M, onde N é o número de pontos de dados (receitas aqui) e M é o número de recursos (palavras dessas receitas), a Regressão Logística identificará o que torna uma receita mais parecida uma cozinha comparada a outra. É importante saber que a regressão logística normal destina-se a separar os dados em apenas DOIS grupos/classes. Neste artigo, usaremos a regressão logística multinomial , que nos permite separar nossos dados em vários grupos/classes! Assim poderemos agrupar as receitas em várias cozinhas diferentes.

W56•e pode usar a regressão logística da seguinte forma:

lr = LogisticRegression(multiclass=”multinomial”).fit(x_train, y_train)

Podemos ver os resultados de quão bem nosso algoritmo foi capaz de prever diferentes cozinhas usando:

print(classification_report(y_test, lr.predict(x_test)))

Como previmos, a previsão de receitas brasileiras, jamaicanas e russas não teve um desempenho muito bom. Por outro lado, podemos ver que os pratos mexicanos tiveram uma precisão bastante alta! Obviamente, isso não é tão bom. A precisão do nosso modelo é de apenas 66% (como visto na seção inferior, com três linhas), então definitivamente há espaço para melhorias. Lembre-se, a ciência de dados é mais do que apenas processar dados e jogá-los em um modelo.

Como podemos melhorar?

Existem várias maneiras pelas quais podemos tentar melhorar nossos resultados! Você pode analisá-los completamente através deste projeto guiado . As possíveis soluções que podemos explorar são:

  1. Implementando validação cruzada
  2. Aumente a quantidade de recursos!
  3. Jogando com o recurso Count Vectorizer, tamanhos ngram
  4. Reduza a dimensionalidade da matriz de recursos enquanto aumenta a quantidade de recursos
  5. Brincando com tamanhos de conjunto de treinamento/teste

Obrigado por ficar comigo por isso e espero que você tenha aprendido alguma coisa!