# 요리 추천 웹 앱 만들기
이 강의에서는 이전 강의에서 배운 기술과 이 시리즈에서 사용된 맛있는 요리 데이터셋을 활용하여 분류 모델을 구축합니다. 또한 저장된 모델을 사용하여 Onnx의 웹 런타임을 활용한 작은 웹 앱을 만들 것입니다.
머신 러닝의 가장 실용적인 활용 중 하나는 추천 시스템을 구축하는 것입니다. 오늘 그 방향으로 첫걸음을 내딛어 보세요!
[](https://youtu.be/17wdM9AHMfg "Applied ML")
> 🎥 위 이미지를 클릭하면 제니 루퍼가 분류된 요리 데이터를 사용하여 웹 앱을 만드는 영상을 볼 수 있습니다.
## [강의 전 퀴즈](https://ff-quizzes.netlify.app/en/ml/)
이 강의에서 배우게 될 내용:
- 모델을 구축하고 이를 Onnx 모델로 저장하는 방법
- Netron을 사용하여 모델을 검사하는 방법
- 웹 앱에서 모델을 사용하여 추론하는 방법
## 모델 구축하기
응용 머신 러닝 시스템을 구축하는 것은 비즈니스 시스템에서 이러한 기술을 활용하는 중요한 부분입니다. Onnx를 사용하면 웹 애플리케이션 내에서 모델을 사용할 수 있으며, 필요할 경우 오프라인 환경에서도 사용할 수 있습니다.
[이전 강의](../../3-Web-App/1-Web-App/README.md)에서는 UFO 목격에 대한 회귀 모델을 구축하고 이를 "피클링"하여 Flask 앱에서 사용했습니다. 이 아키텍처는 매우 유용하지만, 전체 스택 Python 앱이며 JavaScript 애플리케이션을 사용해야 할 수도 있습니다.
이번 강의에서는 추론을 위한 기본적인 JavaScript 기반 시스템을 구축할 수 있습니다. 먼저 모델을 훈련시키고 이를 Onnx에서 사용할 수 있도록 변환해야 합니다.
## 실습 - 분류 모델 훈련하기
먼저, 우리가 사용했던 정리된 요리 데이터셋을 사용하여 분류 모델을 훈련시킵니다.
1. 유용한 라이브러리를 가져옵니다:
```python
!pip install skl2onnx
import pandas as pd
```
Scikit-learn 모델을 Onnx 형식으로 변환하는 데 도움이 되는 '[skl2onnx](https://onnx.ai/sklearn-onnx/)'가 필요합니다.
1. 이전 강의에서 했던 것처럼 `read_csv()`를 사용하여 CSV 파일을 읽습니다:
```python
data = pd.read_csv('../data/cleaned_cuisines.csv')
data.head()
```
1. 첫 번째 두 개의 불필요한 열을 제거하고 나머지 데이터를 'X'로 저장합니다:
```python
X = data.iloc[:,2:]
X.head()
```
1. 레이블을 'y'로 저장합니다:
```python
y = data[['cuisine']]
y.head()
```
### 훈련 루틴 시작하기
우리는 정확도가 좋은 'SVC' 라이브러리를 사용할 것입니다.
1. Scikit-learn에서 적절한 라이브러리를 가져옵니다:
```python
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
```
1. 훈련 및 테스트 세트를 분리합니다:
```python
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3)
```
1. 이전 강의에서 했던 것처럼 SVC 분류 모델을 구축합니다:
```python
model = SVC(kernel='linear', C=10, probability=True,random_state=0)
model.fit(X_train,y_train.values.ravel())
```
1. 이제 `predict()`를 호출하여 모델을 테스트합니다:
```python
y_pred = model.predict(X_test)
```
1. 모델의 품질을 확인하기 위해 분류 보고서를 출력합니다:
```python
print(classification_report(y_test,y_pred))
```
이전에 본 것처럼 정확도가 좋습니다:
```output
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
```
### 모델을 Onnx로 변환하기
올바른 텐서 번호로 변환을 수행해야 합니다. 이 데이터셋에는 380개의 재료가 나열되어 있으므로 `FloatTensorType`에 해당 숫자를 기재해야 합니다.
1. 텐서 번호를 380으로 설정하여 변환합니다.
```python
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}}
```
1. onx를 생성하고 **model.onnx** 파일로 저장합니다:
```python
onx = convert_sklearn(model, initial_types=initial_type, options=options)
with open("./model.onnx", "wb") as f:
f.write(onx.SerializeToString())
```
> 참고로, 변환 스크립트에서 [옵션](https://onnx.ai/sklearn-onnx/parameterized.html)을 전달할 수 있습니다. 이 경우 'nocl'을 True로 설정하고 'zipmap'을 False로 설정했습니다. 이는 분류 모델이므로 ZipMap을 제거하여 딕셔너리 목록을 생성하지 않도록 할 수 있습니다(필요하지 않음). `nocl`은 모델에 클래스 정보를 포함시키는 옵션을 나타냅니다. `nocl`을 'True'로 설정하여 모델 크기를 줄일 수 있습니다.
전체 노트북을 실행하면 Onnx 모델이 생성되어 이 폴더에 저장됩니다.
## 모델 보기
Onnx 모델은 Visual Studio Code에서 잘 보이지 않지만, 많은 연구자들이 모델이 제대로 구축되었는지 확인하기 위해 사용하는 매우 좋은 무료 소프트웨어가 있습니다. [Netron](https://github.com/lutzroeder/Netron)을 다운로드하여 model.onnx 파일을 열어보세요. 380개의 입력과 분류기가 나열된 간단한 모델을 시각화할 수 있습니다:

Netron은 모델을 보는 데 유용한 도구입니다.
이제 이 멋진 모델을 웹 앱에서 사용할 준비가 되었습니다. 냉장고를 열어 남은 재료를 조합하여 모델이 결정한 요리를 만들 수 있는 앱을 만들어 봅시다.
## 추천 웹 애플리케이션 만들기
모델을 웹 앱에서 직접 사용할 수 있습니다. 이 아키텍처를 사용하면 로컬에서 실행하거나 필요할 경우 오프라인에서도 실행할 수 있습니다. `model.onnx` 파일이 저장된 동일한 폴더에 `index.html` 파일을 생성하세요.
1. 이 파일 _index.html_에 다음 마크업을 추가합니다:
```html