15 KiB
Construir um Aplicativo Web de Recomendação de Culinária
Nesta lição, você irá construir um modelo de classificação usando algumas das técnicas aprendidas em lições anteriores e com o delicioso conjunto de dados de culinária utilizado ao longo desta série. Além disso, você criará um pequeno aplicativo web para usar um modelo salvo, aproveitando o runtime web do Onnx.
Um dos usos práticos mais úteis do aprendizado de máquina é a construção de sistemas de recomendação, e você pode dar o primeiro passo nessa direção hoje!
🎥 Clique na imagem acima para assistir ao vídeo: Jen Looper constrói um aplicativo web usando dados de culinária classificados
Quiz pré-aula
Nesta lição, você aprenderá:
- Como construir um modelo e salvá-lo como um modelo Onnx
- Como usar o Netron para inspecionar o modelo
- Como usar seu modelo em um aplicativo web para inferência
Construa seu modelo
Construir sistemas de aprendizado de máquina aplicados é uma parte importante para aproveitar essas tecnologias em sistemas empresariais. Você pode usar modelos dentro de seus aplicativos web (e assim utilizá-los em um contexto offline, se necessário) usando Onnx.
Em uma lição anterior, você construiu um modelo de regressão sobre avistamentos de OVNIs, o "pickleou" e o utilizou em um aplicativo Flask. Embora essa arquitetura seja muito útil, trata-se de um aplicativo Python full-stack, e seus requisitos podem incluir o uso de um aplicativo JavaScript.
Nesta lição, você pode construir um sistema básico baseado em JavaScript para inferência. Primeiro, no entanto, você precisa treinar um modelo e convertê-lo para uso com Onnx.
Exercício - treinar modelo de classificação
Primeiro, treine um modelo de classificação usando o conjunto de dados de culinária limpo que utilizamos.
-
Comece importando bibliotecas úteis:
!pip install skl2onnx import pandas as pd
Você precisará de 'skl2onnx' para ajudar a converter seu modelo Scikit-learn para o formato Onnx.
-
Em seguida, trabalhe com seus dados da mesma forma que fez em lições anteriores, lendo um arquivo CSV usando
read_csv()
:data = pd.read_csv('../data/cleaned_cuisines.csv') data.head()
-
Remova as duas primeiras colunas desnecessárias e salve os dados restantes como 'X':
X = data.iloc[:,2:] X.head()
-
Salve os rótulos como 'y':
y = data[['cuisine']] y.head()
Inicie a rotina de treinamento
Usaremos a biblioteca 'SVC', que tem boa precisão.
-
Importe as bibliotecas apropriadas do Scikit-learn:
from sklearn.model_selection import train_test_split from sklearn.svm import SVC from sklearn.model_selection import cross_val_score from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report
-
Separe os conjuntos de treinamento e teste:
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3)
-
Construa um modelo de classificação SVC como fez na lição anterior:
model = SVC(kernel='linear', C=10, probability=True,random_state=0) model.fit(X_train,y_train.values.ravel())
-
Agora, teste seu modelo chamando
predict()
:y_pred = model.predict(X_test)
-
Imprima um relatório de classificação para verificar a qualidade do modelo:
print(classification_report(y_test,y_pred))
Como vimos antes, a precisão é boa:
precision recall f1-score support chinese 0.72 0.69 0.70 257 indian 0.91 0.87 0.89 243 japanese 0.79 0.77 0.78 239 korean 0.83 0.79 0.81 236 thai 0.72 0.84 0.78 224 accuracy 0.79 1199 macro avg 0.79 0.79 0.79 1199 weighted avg 0.79 0.79 0.79 1199
Converta seu modelo para Onnx
Certifique-se de fazer a conversão com o número correto de tensores. Este conjunto de dados possui 380 ingredientes listados, então você precisa anotar esse número em FloatTensorType
:
-
Converta usando um número de tensor de 380.
from skl2onnx import convert_sklearn from skl2onnx.common.data_types import FloatTensorType initial_type = [('float_input', FloatTensorType([None, 380]))] options = {id(model): {'nocl': True, 'zipmap': False}}
-
Crie o arquivo onx e salve como model.onnx:
onx = convert_sklearn(model, initial_types=initial_type, options=options) with open("./model.onnx", "wb") as f: f.write(onx.SerializeToString())
Nota: você pode passar opções no seu script de conversão. Neste caso, passamos 'nocl' como True e 'zipmap' como False. Como este é um modelo de classificação, você tem a opção de remover ZipMap, que produz uma lista de dicionários (não necessário).
nocl
refere-se à inclusão de informações de classe no modelo. Reduza o tamanho do seu modelo configurandonocl
como 'True'.
Executar o notebook completo agora criará um modelo Onnx e o salvará nesta pasta.
Visualize seu modelo
Modelos Onnx não são muito visíveis no Visual Studio Code, mas há um software gratuito muito bom que muitos pesquisadores utilizam para visualizar o modelo e garantir que ele foi construído corretamente. Baixe o Netron e abra seu arquivo model.onnx. Você poderá ver seu modelo simples visualizado, com seus 380 inputs e o classificador listado:
Netron é uma ferramenta útil para visualizar seus modelos.
Agora você está pronto para usar este modelo interessante em um aplicativo web. Vamos construir um aplicativo que será útil quando você olhar para sua geladeira e tentar descobrir quais combinações de ingredientes restantes podem ser usadas para cozinhar um prato específico, conforme determinado pelo seu modelo.
Construa um aplicativo web de recomendação
Você pode usar seu modelo diretamente em um aplicativo web. Essa arquitetura também permite que você o execute localmente e até mesmo offline, se necessário. Comece criando um arquivo index.html
na mesma pasta onde você armazenou seu arquivo model.onnx
.
-
Neste arquivo index.html, adicione a seguinte marcação:
<!DOCTYPE html> <html> <header> <title>Cuisine Matcher</title> </header> <body> ... </body> </html>
-
Agora, dentro das tags
body
, adicione uma pequena marcação para mostrar uma lista de caixas de seleção refletindo alguns ingredientes:<h1>Check your refrigerator. What can you create?</h1> <div id="wrapper"> <div class="boxCont"> <input type="checkbox" value="4" class="checkbox"> <label>apple</label> </div> <div class="boxCont"> <input type="checkbox" value="247" class="checkbox"> <label>pear</label> </div> <div class="boxCont"> <input type="checkbox" value="77" class="checkbox"> <label>cherry</label> </div> <div class="boxCont"> <input type="checkbox" value="126" class="checkbox"> <label>fenugreek</label> </div> <div class="boxCont"> <input type="checkbox" value="302" class="checkbox"> <label>sake</label> </div> <div class="boxCont"> <input type="checkbox" value="327" class="checkbox"> <label>soy sauce</label> </div> <div class="boxCont"> <input type="checkbox" value="112" class="checkbox"> <label>cumin</label> </div> </div> <div style="padding-top:10px"> <button onClick="startInference()">What kind of cuisine can you make?</button> </div>
Note que cada caixa de seleção recebe um valor. Isso reflete o índice onde o ingrediente é encontrado de acordo com o conjunto de dados. Por exemplo, maçã, nesta lista alfabética, ocupa a quinta coluna, então seu valor é '4', já que começamos a contar a partir de 0. Você pode consultar a planilha de ingredientes para descobrir o índice de um determinado ingrediente.
Continuando seu trabalho no arquivo index.html, adicione um bloco de script onde o modelo é chamado após o fechamento final de
</div>
. -
Primeiro, importe o Onnx Runtime:
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.9.0/dist/ort.min.js"></script>
Onnx Runtime é usado para permitir a execução de seus modelos Onnx em uma ampla gama de plataformas de hardware, incluindo otimizações e uma API para uso.
-
Uma vez que o Runtime esteja configurado, você pode chamá-lo:
<script> const ingredients = Array(380).fill(0); const checks = [...document.querySelectorAll('.checkbox')]; checks.forEach(check => { check.addEventListener('change', function() { // toggle the state of the ingredient // based on the checkbox's value (1 or 0) ingredients[check.value] = check.checked ? 1 : 0; }); }); function testCheckboxes() { // validate if at least one checkbox is checked return checks.some(check => check.checked); } async function startInference() { let atLeastOneChecked = testCheckboxes() if (!atLeastOneChecked) { alert('Please select at least one ingredient.'); return; } try { // create a new session and load the model. const session = await ort.InferenceSession.create('./model.onnx'); const input = new ort.Tensor(new Float32Array(ingredients), [1, 380]); const feeds = { float_input: input }; // feed inputs and run const results = await session.run(feeds); // read from results alert('You can enjoy ' + results.label.data[0] + ' cuisine today!') } catch (e) { console.log(`failed to inference ONNX model`); console.error(e); } } </script>
Neste código, várias coisas estão acontecendo:
- Você criou um array de 380 valores possíveis (1 ou 0) para serem configurados e enviados ao modelo para inferência, dependendo de quais caixas de seleção de ingredientes estão marcadas.
- Você criou um array de caixas de seleção e uma forma de determinar se elas foram marcadas em uma função
init
que é chamada quando o aplicativo inicia. Quando uma caixa de seleção é marcada, o arrayingredients
é alterado para refletir o ingrediente escolhido. - Você criou uma função
testCheckboxes
que verifica se alguma caixa de seleção foi marcada. - Você usa a função
startInference
quando o botão é pressionado e, se alguma caixa de seleção estiver marcada, inicia a inferência. - A rotina de inferência inclui:
- Configurar um carregamento assíncrono do modelo
- Criar uma estrutura de Tensor para enviar ao modelo
- Criar 'feeds' que refletem o input
float_input
que você criou ao treinar seu modelo (você pode usar o Netron para verificar esse nome) - Enviar esses 'feeds' ao modelo e aguardar uma resposta
Teste seu aplicativo
Abra uma sessão de terminal no Visual Studio Code na pasta onde seu arquivo index.html está localizado. Certifique-se de que você tenha o http-server instalado globalmente e digite http-server
no prompt. Um localhost deve abrir e você poderá visualizar seu aplicativo web. Verifique qual culinária é recomendada com base em vários ingredientes:
Parabéns, você criou um aplicativo web de 'recomendação' com alguns campos. Dedique algum tempo para expandir este sistema!
🚀Desafio
Seu aplicativo web é muito básico, então continue expandindo-o usando ingredientes e seus índices do ingredient_indexes. Quais combinações de sabores funcionam para criar um prato típico de uma determinada nacionalidade?
Quiz pós-aula
Revisão e Autoestudo
Embora esta lição tenha apenas tocado na utilidade de criar um sistema de recomendação para ingredientes alimentares, esta área de aplicações de aprendizado de máquina é muito rica em exemplos. Leia mais sobre como esses sistemas são construídos:
- https://www.sciencedirect.com/topics/computer-science/recommendation-engine
- https://www.technologyreview.com/2014/08/25/171547/the-ultimate-challenge-for-recommendation-engines/
- https://www.technologyreview.com/2015/03/23/168831/everything-is-a-recommendation/
Tarefa
Construa um novo sistema de recomendação
Aviso Legal:
Este documento foi traduzido utilizando o serviço de tradução por IA Co-op Translator. Embora nos esforcemos para garantir a precisão, esteja ciente de que traduções automáticas podem conter erros ou imprecisões. O documento original em seu idioma nativo deve ser considerado a fonte oficial. Para informações críticas, recomenda-se a tradução profissional realizada por humanos. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes do uso desta tradução.