Italian Translation - Chapter 4 complete

pull/234/head
Roberto Pauletto 3 years ago
parent 0ef25fe4c2
commit f73b84f84a

@ -0,0 +1,297 @@
# Introduzione alla classificazione
In queste quattro lezioni si esplorerà un focus fondamentale del machine learning classico: _la classificazione_. Verrà analizzato l'utilizzo di vari algoritmi di classificazione con un insieme di dati su tutte le brillanti cucine dell'Asia e dell'India. Si spera siate affamati!
![solo un pizzico!](../images/pinch.png)
> In queste lezioni di celebrano le cucine panasiatiche! Immagine di [Jen Looper](https://twitter.com/jenlooper)
La classificazione è una forma di [apprendimento supervisionato](https://it.wikipedia.org/wiki/Apprendimento_supervisionato) che ha molto in comune con le tecniche di regressione. Se machine learning riguarda la previsione di valori o nomi di cose utilizzando insiemi di dati, la classificazione generalmente rientra in due gruppi: _classificazione binaria_ e _classificazione multiclasse_.
[![Introduzione allaclassificazione](https://img.youtube.com/vi/eg8DJYwdMyg/0.jpg)](https://youtu.be/eg8DJYwdMyg "Introduzione alla classificazione")
> 🎥 Fare clic sull'immagine sopra per un video: John Guttag del MIT introduce la classificazione
Ricordare:
- La **regressione lineare** ha aiutato a prevedere le relazioni tra le variabili e a fare previsioni accurate su dove un nuovo punto dati si sarebbe posizionato in relazione a quella linea. Quindi, si potrebbe prevedere _quale prezzo avrebbe una zucca a settembre rispetto a dicembre_, ad esempio.
- La **regressione logistica** ha aiutato a scoprire le "categorie binarie": a questo prezzo, _questa zucca è arancione o non arancione_?
La classificazione utilizza vari algoritmi per determinare altri modi per definire l'etichetta o la classe di un punto dati. Si lavorerà con questi dati di cucina per vedere se, osservando un gruppo di ingredienti, è possibile determinarne la cucina di origine.
## [Quiz Pre-Lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/19/)
### Introduzione
La classificazione è una delle attività fondamentali del ricercatore di machine learning e data scientist. Dalla classificazione basica di un valore binario ("questa email è spam o no?"), alla complessa classificazione e segmentazione di immagini utilizzando la visione artificiale, è sempre utile essere in grado di ordinare i dati in classi e porre domande su di essi.
Per definire il processo in modo più scientifico, il metodo di classificazione crea un modello predittivo che consente di mappare la relazione tra le variabili di input e le variabili di output.
![classificazione binaria vs. multiclasse](../images/binary-multiclass.png)
> Problemi binari e multiclasse per la gestione di algoritmi di classificazione. Infografica di [Jen Looper](https://twitter.com/jenlooper)
Prima di iniziare il processo di pulizia dei dati, visualizzazione e preparazione per le attività di machine learning, si apprenderà qualcosa circa i vari modi in cui machine learning può essere sfruttato per classificare i dati.
Derivata dalla [statistica](https://it.wikipedia.org/wiki/Classificazione_statistica), la classificazione che utilizza machine learning classico utilizza caratteristiche come l'`essere fumatore`, il `peso` e l'`età` per determinare _la probabilità di sviluppare la malattia X._ Essendo una tecnica di apprendimento supervisionata simile agli esercizi di regressione eseguiti in precedenza, i dati vengono etichettati e gli algoritmi ML utilizzano tali etichette per classificare e prevedere le classi (o "caratteristiche") di un insieme di dati e assegnarle a un gruppo o risultato.
✅ Si prenda un momento per immaginare un insieme di dati sulle cucine. A cosa potrebbe rispondere un modello multiclasse? A cosa potrebbe rispondere un modello binario? Se si volesse determinare se una determinata cucina potrebbe utilizzare il fieno greco? Se si volesse vedere se, regalando una busta della spesa piena di anice stellato, carciofi, cavolfiori e rafano, si possa creare un piatto tipico indiano?
[![Cesti misteriosi pazzeschi](https://img.youtube.com/vi/GuTeDbaNoEU/0.jpg)](https://youtu.be/GuTeDbaNoEU " Cestini misteriosi pazzeschi")
> 🎥 Fare clic sull'immagine sopra per un video. L'intera premessa dello spettacolo 'Chopped' è il 'cesto misterioso' dove gli chef devono preparare un piatto con una scelta casuale di ingredienti. Sicuramente un modello ML avrebbe aiutato!
## Ciao 'classificatore'
La domanda che si vuole porre a questo insieme di dati sulla cucina è in realtà una **domanda multiclasse**, poiché ci sono diverse potenziali cucine nazionali con cui lavorare. Dato un lotto di ingredienti, in quale di queste molte classi si identificheranno i dati?
Scikit-learn offre diversi algoritmi da utilizzare per classificare i dati, a seconda del tipo di problema che si desidera risolvere. Nelle prossime due lezioni si impareranno a conoscere molti di questi algoritmi.
## Esercizio: pulire e bilanciare i dati
Il primo compito, prima di iniziare questo progetto, sarà pulire e **bilanciare** i dati per ottenere risultati migliori. Si inizia con il file vuoto _notebook.ipynb_ nella radice di questa cartella.
La prima cosa da installare è [imblearn](https://imbalanced-learn.org/stable/). Questo è un pacchetto di apprendimento di Scikit che consentirà di bilanciare meglio i dati (si imparerà di più su questa attività tra un minuto).
1. Per installare `imblearn`, eseguire `pip install`, in questo modo:
```python
pip install imblearn
```
1. Importare i pacchetti necessari per caricare i dati e visualizzarli, importare anche `SMOTE` da `imblearn`.
```python
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from imblearn.over_sampling import SMOTE
```
Ora si è pronti per la successiva importazione dei dati.
1. Il prossimo compito sarà quello di importare i dati:
```python
df = pd.read_csv('../data/cuisines.csv')
```
Usando `read_csv()` si leggerà il contenuto del file csv _cusines.csv_ e lo posizionerà nella variabile `df`.
1. Controllare la forma dei dati:
```python
df.head()
```
Le prime cinque righe hanno questo aspetto:
```output
| | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
| --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- |
| 0 | 65 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 66 | indian | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 67 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 68 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 69 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
```
1. Si possono ottienere informazioni su questi dati chiamando `info()`:
```python
df.info()
```
Il risultato assomiglia a:
```output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2448 entries, 0 to 2447
Columns: 385 entries, Unnamed: 0 to zucchini
dtypes: int64(384), object(1)
memory usage: 7.2+ MB
```
## Esercizio - conoscere le cucine
Ora il lavoro inizia a diventare più interessante. Si scoprirà la distribuzione dei dati, per cucina
1. Tracciare i dati come barre chiamando `barh()`:
```python
df.cuisine.value_counts().plot.barh()
```
![distribuzione dati cuisine](../images/cuisine-dist.png)
Esiste un numero finito di cucine, ma la distribuzione dei dati non è uniforme. Si può sistemare! Prima di farlo, occorre esplorare un po' di più.
1. Si deve scoprire quanti dati sono disponibili per cucina e stamparli:
```python
thai_df = df[(df.cuisine == "thai")]
japanese_df = df[(df.cuisine == "japanese")]
chinese_df = df[(df.cuisine == "chinese")]
indian_df = df[(df.cuisine == "indian")]
korean_df = df[(df.cuisine == "korean")]
print(f'thai df: {thai_df.shape}')
print(f'japanese df: {japanese_df.shape}')
print(f'chinese df: {chinese_df.shape}')
print(f'indian df: {indian_df.shape}')
print(f'korean df: {korean_df.shape}')
```
il risultato si presenta così:
```output
thai df: (289, 385)
japanese df: (320, 385)
chinese df: (442, 385)
indian df: (598, 385)
korean df: (799, 385)
```
## Alla scoperta degli ingredienti
Ora si possono approfondire i dati e scoprire quali sono gli ingredienti tipici per cucina. Si dovrebbero ripulire i dati ricorrenti che creano confusione tra le cucine, quindi si affronterà questo problema.
1. Creare una funzione `create_ingredient()` in Python per creare un dataframe ingredient Questa funzione inizierà eliminando una colonna non utile e ordinando gli ingredienti in base al loro conteggio:
```python
def create_ingredient_df(df):
ingredient_df = df.T.drop(['cuisine','Unnamed: 0']).sum(axis=1).to_frame('value')
ingredient_df = ingredient_df[(ingredient_df.T != 0).any()]
ingredient_df = ingredient_df.sort_values(by='value', ascending=False
inplace=False)
return ingredient_df
```
Ora si può usare questa funzione per farsi un'idea dei primi dieci ingredienti più popolari per cucina.
1. Chiamare `create_ingredient_df()` e tracciare il grafico chiamando `barh()`:
```python
thai_ingredient_df = create_ingredient_df(thai_df)
thai_ingredient_df.head(10).plot.barh()
```
![thai](../images/thai.png)
1. Fare lo stesso per i dati giapponesi:
```python
japanese_ingredient_df = create_ingredient_df(japanese_df)
japanese_ingredient_df.head(10).plot.barh()
```
![Giapponese](../images/japanese.png)
1. Ora per gli ingredienti cinesi:
```python
chinese_ingredient_df = create_ingredient_df(chinese_df)
chinese_ingredient_df.head(10).plot.barh()
```
![cinese](../images/chinese.png)
1. Tracciare gli ingredienti indiani:
```python
indian_ingredient_df = create_ingredient_df(indian_df)
indian_ingredient_df.head(10).plot.barh()
```
![indiano](../images/indian.png)
1. Infine, tracciare gli ingredienti coreani:
```python
korean_ingredient_df = create_ingredient_df(korean_df)
korean_ingredient_df.head(10).plot.barh()
```
![Coreano](../images/korean.png)
1. Ora, eliminare gli ingredienti più comuni che creano confusione tra le diverse cucine, chiamando `drop()`:
Tutti amano il riso, l'aglio e lo zenzero!
```python
feature_df= df.drop(['cuisine','Unnamed: 0','rice','garlic','ginger'], axis=1)
labels_df = df.cuisine #.unique()
feature_df.head()
```
## Bilanciare l'insieme di dati
Ora che i dati sono puliti, si usa [SMOTE](https://imbalanced-learn.org/dev/references/generated/imblearn.over_sampling.SMOTE.html) - "Tecnica di sovracampionamento della minoranza sintetica" - per bilanciarlo.
1. Chiamare `fit_resample()`, questa strategia genera nuovi campioni per interpolazione.
```python
oversample = SMOTE()
transformed_feature_df, transformed_label_df = oversample.fit_resample(feature_df, labels_df)
```
Bilanciando i dati, si otterranno risultati migliori quando si classificano. Si pensi a una classificazione binaria. Se la maggior parte dei dati è una classe, un modello ML prevederà quella classe più frequentemente, solo perché ci sono più dati per essa. Il bilanciamento dei dati prende tutti i dati distorti e aiuta a rimuovere questo squilibrio.
1. Ora si può controllare il numero di etichette per ingrediente:
```python
print(f'new label count: {transformed_label_df.value_counts()}')
print(f'old label count: {df.cuisine.value_counts()}')
```
il risultato si presenta così:
```output
new label count: korean 799
chinese 799
indian 799
japanese 799
thai 799
Name: cuisine, dtype: int64
old label count: korean 799
indian 598
chinese 442
japanese 320
thai 289
Name: cuisine, dtype: int64
```
I dati sono belli e puliti, equilibrati e molto deliziosi!
1. L'ultimo passaggio consiste nel salvare i dati bilanciati, incluse etichette e caratteristiche, in un nuovo dataframe che può essere esportato in un file:
```python
transformed_df = pd.concat([transformed_label_df,transformed_feature_df],axis=1, join='outer')
```
1. Si può dare un'altra occhiata ai dati usando `transform_df.head()` e `transform_df.info()`. Salvare una copia di questi dati per utilizzarli nelle lezioni future:
```python
transformed_df.head()
transformed_df.info()
transformed_df.to_csv("../data/cleaned_cuisine.csv")
```
Questo nuovo CSV può ora essere trovato nella cartella data in radice.
---
## 🚀 Sfida
Questo programma di studi contiene diversi insiemi di dati interessanti. Esaminare le cartelle `data` e vedere se contiene insiemi di dati che sarebbero appropriati per la classificazione binaria o multiclasse. Quali domande si farebbero a questo insieme di dati?
## [Quiz post-lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/20/)
## Revisione e Auto Apprendimento
Esplorare l'API di SMOTE. Per quali casi d'uso è meglio usarla? Quali problemi risolve?
## Compito
[Esplorare i metodi di classificazione](assignment.it.md)

@ -0,0 +1,11 @@
# Esplorare i metodi di classificazione
## Istruzioni
Nella [documentazione](https://scikit-learn.org/stable/supervised_learning.html) di Scikit-learn si troverà un ampio elenco di modi per classificare i dati. Fare una piccola caccia al tesoro in questi documenti: l'obiettivo è cercare metodi di classificazione e abbinare un insieme di dati in questo programma di studi, una domanda che si può porre e una tecnica di classificazione. Creare un foglio di calcolo o una tabella in un file .doc e spiegare come funzionerebbe l'insieme di dati con l'algoritmo di classificazione.
## Rubrica
| Criteri | Ottimo | Adeguato | Necessita miglioramento |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| | viene presentato un documento che riporta una panoramica di 5 algoritmi insieme a una tecnica di classificazione. La panoramica è ben spiegata e dettagliata. | viene presentato un documento che riporta una panoramica di 3 algoritmi insieme a una tecnica di classificazione. La panoramica è ben spiegata e dettagliata. | viene presentato un documento che riporta una panoramica di meno di tre algoritmi insieme a una tecnica di classificazione e la panoramica non è né ben spiegata né dettagliata. |

@ -0,0 +1,241 @@
# Classificatori di cucina 1
In questa lezione, si utilizzerà l'insieme di dati salvati dall'ultima lezione, pieno di dati equilibrati e puliti relativi alle cucine.
Si utilizzerà questo insieme di dati con una varietà di classificatori per _prevedere una determinata cucina nazionale in base a un gruppo di ingredienti_. Mentre si fa questo, si imparerà di più su alcuni dei modi in cui gli algoritmi possono essere sfruttati per le attività di classificazione.
## [Quiz Pre-Lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/21/)
# Preparazione
Supponendo che la [Lezione 1](../1-Introduction/README.md) sia stata completata, assicurarsi che _esista_ un file clean_cuisines.csv nella cartella in radice `/data` per queste quattro lezioni.
## Esercizio - prevedere una cucina nazionale
1. Lavorando con il _notebook.ipynb_ di questa lezione nella cartella radice, importare quel file insieme alla libreria Pandas:
```python
import pandas as pd
cuisines_df = pd.read_csv("../../data/cleaned_cuisine.csv")
cuisines_df.head()
```
I dati si presentano così:
```output
| | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
| --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- |
| 0 | 0 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | indian | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 2 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 3 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 4 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
```
1. Ora importare molte altre librerie:
```python
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve
from sklearn.svm import SVC
import numpy as np
```
1. Dividere le coordinate X e y in due dataframe per l'addestramento. `cuisine` può essere il dataframe delle etichette:
```python
cuisines_label_df = cuisines_df['cuisine']
cuisines_label_df.head()
```
Apparirà così
```output
0 indian
1 indian
2 indian
3 indian
4 indian
Name: cuisine, dtype: object
```
1. Scartare la colonna `Unnamed: 0` e la colonna `cuisine` , chiamando `drop()`. Salvare il resto dei dati come caratteristiche addestrabili:
```python
cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)
cuisines_feature_df.head()
```
Le caratteristiche sono così:
| almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | artemisia | artichoke | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini | |
| -----: | -------: | ----: | ---------: | ----: | -----------: | ------: | -------: | --------: | --------: | ---: | ------: | ----------: | ---------: | ----------------------: | ---: | ---: | ---: | ----: | -----: | -------: | --- |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
Ora si è pronti per addestrare il modello!
## Scegliere il classificatore
Ora che i dati sono puliti e pronti per l'addestramento, si deve decidere quale algoritmo utilizzare per il lavoro.
Scikit-learn raggruppa la classificazione in Supervised Learning, e in quella categoria si troveranno molti modi per classificare. [La varietà](https://scikit-learn.org/stable/supervised_learning.html) è piuttosto sconcertante a prima vista. I seguenti metodi includono tutti tecniche di classificazione:
- Modelli Lineari
- Macchine a Vettori di Supporto
- Discesa stocastica del gradiente
- Nearest Neighbors
- Processi Gaussiani
- Alberi di Decisione
- Apprendimento ensemble (classificatore di voto)
- Algoritmi multiclasse e multioutput (classificazione multiclasse e multietichetta, classificazione multiclasse-multioutput)
> Si possono anche usare [le reti neurali per classificare i dati](https://scikit-learn.org/stable/modules/neural_networks_supervised.html#classification), ma questo esula dall'ambito di questa lezione.
### Con quale classificatore andare?
Quale classificatore si dovrebbe scegliere? Spesso, scorrerne diversi e cercare un buon risultato è un modo per testare. Scikit-learn offre un [confronto fianco](https://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html) a fianco su un insieme di dati creato, confrontando KNeighbors, SVC in due modi, GaussianProcessClassifier, DecisionTreeClassifier, RandomForestClassifier, MLPClassifier, AdaBoostClassifier, GaussianNB e QuadraticDiscrinationAnalysis, mostrando i risultati visualizzati:
![confronto di classificatori](../images/comparison.png)
> Grafici generati sulla documentazione di Scikit-learn
> AutoML risolve questo problema in modo ordinato eseguendo questi confronti nel cloud, consentendo di scegliere l'algoritmo migliore per i propri dati. Si può provare [qui](https://docs.microsoft.com/learn/modules/automate-model-selection-with-azure-automl/?WT.mc_id=academic-15963-cxa)
### Un approccio migliore
Un modo migliore che indovinare a caso, tuttavia, è seguire le idee su questo [ML Cheat sheet](https://docs.microsoft.com/azure/machine-learning/algorithm-cheat-sheet?WT.mc_id=academic-15963-cxa) scaricabile. Qui si scopre che, per questo problema multiclasse, si dispone di alcune scelte:
![cheatsheet per problemi multiclasse](../images/cheatsheet.png)
> Una sezione dell'Algorithm Cheat Sheet di Microsoft, che descrive in dettaglio le opzioni di classificazione multiclasse
✅ Scaricare questo cheat sheet, stamparlo e appenderlo alla parete!
### Motivazione
Si prova a ragionare attraverso diversi approcci dati i vincoli presenti:
- **Le reti neurali sono troppo pesanti**. Dato l'insieme di dati pulito, ma minimo, e il fatto che si sta eseguendo l'addestramento localmente tramite notebook, le reti neurali sono troppo pesanti per questo compito.
- **Nessun classificatore a due classi**. Non si usa un classificatore a due classi, quindi questo esclude uno contro tutti.
- L'**albero decisionale o la regressione logistica potrebbero funzionare**. Potrebbe funzionare un albero decisionale o una regressione logistica per dati multiclasse.
- **Gli alberi decisionali potenziati multiclasse risolvono un problema diverso**. L'albero decisionale potenziato multiclasse è più adatto per attività non parametriche, ad esempio attività progettate per costruire classifiche, quindi non è utile in questo caso.
### Utilizzo di Scikit-learn
Si userà Scikit-learn per analizzare i dati. Tuttavia, ci sono molti modi per utilizzare la regressione logistica in Scikit-learn. Dare un'occhiata ai [parametri da passare](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html?highlight=logistic%20regressio#sklearn.linear_model.LogisticRegression).
Essenzialmente ci sono due importanti parametri `multi_class` e `solver`, che occorre specificare, quando si chiede a Scikit-learn di eseguire una regressione logistica. Il valore `multi_class` si applica un certo comportamento. Il valore del risolutore è quale algoritmo utilizzare. Non tutti i risolutori possono essere associati a tutti i valori `multi_class` .
Secondo la documentazione, nel caso multiclasse, l'algoritmo di addestramento:
- **Utilizza lo schema one-vs-rest (OvR)** - uno contro tutti, se l'opzione `multi_class` è impostata su `ovr`
- **Utilizza la perdita di entropia incrociata**, se l 'opzione `multi_class` è impostata su `multinomial`. (Attualmente l'opzione multinomiale è supportata solo dai solutori 'lbfgs', 'sag', 'saga' e 'newton-cg')."
> 🎓 Lo 'schema' qui può essere 'ovr' (one-vs-rest) - uno contro tutti - o 'multinomiale'. Poiché la regressione logistica è realmente progettata per supportare la classificazione binaria, questi schemi consentono di gestire meglio le attività di classificazione multiclasse. [fonte](https://machinelearningmastery.com/one-vs-rest-and-one-vs-one-for-multi-class-classification/)
> 🎓 Il 'solver' è definito come "l'algoritmo da utilizzare nel problema di ottimizzazione". [fonte](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html?highlight=logistic%20regressio#sklearn.linear_model.LogisticRegression).
Scikit-learn offre questa tabella per spiegare come i risolutori gestiscono le diverse sfide presentate da diversi tipi di strutture dati:
![risolutori](../images/solvers.png)
## Esercizio: dividere i dati
Ci si può concentrare sulla regressione logistica per la prima prova di addestramento poiché di recente si è appreso di quest'ultima in una lezione precedente.
Dividere i dati in gruppi di addestramento e test chiamando `train_test_split()`:
```python
X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)
```
## Esercizio: applicare la regressione logistica
Poiché si sta utilizzando il caso multiclasse, si deve scegliere quale _schema_ utilizzare e quale _solutore_ impostare. Usare LogisticRegression con un'impostazione multiclasse e il solutore **liblinear** da addestrare.
1. Creare una regressione logistica con multi_class impostato su `ovr` e il risolutore impostato su `liblinear`:
```python
lr = LogisticRegression(multi_class='ovr',solver='liblinear')
model = lr.fit(X_train, np.ravel(y_train))
accuracy = model.score(X_test, y_test)
print ("Accuracy is {}".format(accuracy))
```
✅ Provare un risolutore diverso come `lbfgs`, che è spesso impostato come predefinito
> Nota, usare la funzione [`ravel`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.ravel.html) di Pandas per appiattire i dati quando necessario.
La precisione è buona oltre l'**80%**!
1. Si può vedere questo modello in azione testando una riga di dati (#50):
```python
print(f'ingredients: {X_test.iloc[50][X_test.iloc[50]!=0].keys()}')
print(f'cuisine: {y_test.iloc[50]}')
```
Il risultato viene stampato:
```output
ingredients: Index(['cilantro', 'onion', 'pea', 'potato', 'tomato', 'vegetable_oil'], dtype='object')
cuisine: indian
```
✅ Provare un numero di riga diverso e controllare i risultati
1. Scavando più a fondo, si può verificare l'accuratezza di questa previsione:
```python
test= X_test.iloc[50].values.reshape(-1, 1).T
proba = model.predict_proba(test)
classes = model.classes_
resultdf = pd.DataFrame(data=proba, columns=classes)
topPrediction = resultdf.T.sort_values(by=[0], ascending = [False])
topPrediction.head()
```
Il risultato è stampato: la cucina indiana è la sua ipotesi migliore, con buone probabilità:
| | 0 | | | | | | | | | | | | | | | | | | | | |
| -------: | -------: | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| indiano | 0,715851 | | | | | | | | | | | | | | | | | | | | |
| cinese | 0.229475 | | | | | | | | | | | | | | | | | | | | |
| Giapponese | 0,029763 | | | | | | | | | | | | | | | | | | | | |
| Coreano | 0.017277 | | | | | | | | | | | | | | | | | | | | |
| thai | 0.007634 | | | | | | | | | | | | | | | | | | | | |
✅ Si è in grado di spiegare perché il modello è abbastanza sicuro che questa sia una cucina indiana?
1. Ottenere maggiori dettagli stampando un rapporto di classificazione, come fatto nelle lezioni di regressione:
```python
y_pred = model.predict(X_test)
print(classification_report(y_test,y_pred))
```
| precisione | recall | punteggio f1 | supporto | | | | | | | | | | | | | | | | | | |
| ------------ | ------ | -------- | ------- | ---- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| cinese | 0,73 | 0,71 | 0,72 | 229 | | | | | | | | | | | | | | | | | |
| indiano | 0,91 | 0,93 | 0,92 | 254 | | | | | | | | | | | | | | | | | |
| Giapponese | 0.70 | 0,75 | 0,72 | 220 | | | | | | | | | | | | | | | | | |
| Coreano | 0,86 | 0,76 | 0,81 | 242 | | | | | | | | | | | | | | | | | |
| thai | 0,79 | 0,85 | 0.82 | 254 | | | | | | | | | | | | | | | | | |
| accuratezza | 0,80 | 1199 | | | | | | | | | | | | | | | | | | | |
| macro media | 0,80 | 0,80 | 0,80 | 1199 | | | | | | | | | | | | | | | | | |
| Media ponderata | 0,80 | 0,80 | 0,80 | 1199 | | | | | | | | | | | | | | | | | |
## 🚀 Sfida
In questa lezione, sono stati utilizzati dati puliti per creare un modello di apprendimento automatico in grado di prevedere una cucina nazionale basata su una serie di ingredienti. Si prenda del tempo per leggere le numerose opzioni fornite da Scikit-learn per classificare i dati. Approfondire il concetto di "risolutore" per capire cosa succede dietro le quinte.
## [Quiz post-lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/22/)
## Revisione e Auto Apprendimento
Approfondire un po' la matematica alla base della regressione logistica in [questa lezione](https://people.eecs.berkeley.edu/~russell/classes/cs194/f11/lectures/CS194%20Fall%202011%20Lecture%2006.pdf)
## Compito
[Studiare i risolutori](assignment.it.md)

@ -0,0 +1,10 @@
# Studiare i risolutori
## Istruzioni
In questa lezione si è imparato a conoscere i vari risolutori che associano algoritmi a un processo di machine learning per creare un modello accurato. Esaminare i risolutori elencati nella lezione e sceglierne due. Con parole proprie, confrontare questi due risolutori. Che tipo di problema affrontano? Come funzionano con varie strutture di dati? Perché se ne dovrebbe sceglierne uno piuttosto che un altro?
## Rubrica
| Criteri | Ottimo | Adeguato | Necessita miglioramento |
| -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------ | ---------------------------- |
| | Viene presentato un file .doc con due paragrafi, uno su ciascun risolutore, confrontandoli attentamente. | Un file .doc viene presentato con un solo paragrafo | Il compito è incompleto |

@ -0,0 +1,235 @@
# Classificatori di cucina 2
In questa seconda lezione sulla classificazione, si esploreranno più modi per classificare i dati numerici. Si Impareranno anche le ramificazioni per la scelta di un classificatore rispetto all'altro.
## [Quiz Pre-Lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/23/)
### Prerequisito
Si parte dal presupposto che siano state completate le lezioni precedenti e si disponga di un insieme di dati pulito nella cartella `data` chiamato _clean_cuisine.csv_ nella radice di questa cartella di 4 lezioni.
### Preparazione
Il file _notebook.ipynb_ è stato caricato con l'insieme di dati pulito ed è stato diviso in dataframe di dati X e y, pronti per il processo di creazione del modello.
## Una mappa di classificazione
In precedenza, si sono apprese le varie opzioni a disposizione durante la classificazione dei dati utilizzando il cheat sheet di Microsoft. Scikit-learn offre un cheat sheet simile, ma più granulare che può aiutare ulteriormente a restringere i propri stimatori (un altro termine per i classificatori):
![Mappa ML da Scikit-learn](../images/map.png)
> Suggerimento: [visitare questa mappa online](https://scikit-learn.org/stable/tutorial/machine_learning_map/) e fare clic lungo il percorso per leggere la documentazione.
### Il piano
Questa mappa è molto utile una volta che si ha una chiara comprensione dei propri dati, poiché si può "camminare" lungo i suoi percorsi verso una decisione:
- Ci sono >50 campioni
- Si vuole pronosticare una categoria
- I dati sono etichettati
- Ci sono meno di 100K campioni
- ✨ Si può scegliere un SVC lineare
- Se non funziona, visto che ci sono dati numerici
- Si può provare un ✨ KNeighbors Classifier
- Se non funziona, si prova ✨ SVC e ✨ Classificatori di ensemble
Questo è un percorso molto utile da seguire.
## Esercizio: dividere i dati
Seguendo questo percorso, si dovrebbe iniziare importando alcune librerie da utilizzare.
1. Importare le librerie necessarie:
```python
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve
import numpy as np
```
1. Dividere i dati per allenamento e test:
```python
X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)
```
## Classificatore lineare SVC
Il clustering Support-Vector (SVC) è figlio della famiglia di tecniche ML Support-Vector (ulteriori informazioni su queste di seguito). In questo metodo, si può scegliere un "kernel" per decidere come raggruppare le etichette. Il parametro 'C' si riferisce alla 'regolarizzazione' che regola l'influenza dei parametri. Il kernel può essere uno dei [tanti](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC); qui si imposta su 'lineare' per assicurarsi di sfruttare l'SVC lineare. Il valore predefinito di probabilità è 'false'; qui si imposta su 'true' per raccogliere stime di probabilità. Si imposta lo stato casuale su "0" per mescolare i dati per ottenere le probabilità.
### Esercizio: applicare una SVC lineare
Iniziare creando un array di classificatori. Si aggiungerà progressivamente a questo array durante il test.
1. Iniziare con un SVC lineare:
```python
C = 10
# Create different classifiers.
classifiers = {
'Linear SVC': SVC(kernel='linear', C=C, probability=True,random_state=0)
}
```
2. Addestrare il modello utilizzando Linear SVC e stampare un rapporto:
```python
n_classifiers = len(classifiers)
for index, (name, classifier) in enumerate(classifiers.items()):
classifier.fit(X_train, np.ravel(y_train))
y_pred = classifier.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy (train) for %s: %0.1f%% " % (name, accuracy * 100))
print(classification_report(y_test,y_pred))
```
Il risultato è abbastanza buono:
```output
Accuracy (train) for Linear SVC: 78.6%
precision recall f1-score support
chinese 0.71 0.67 0.69 242
indian 0.88 0.86 0.87 234
japanese 0.79 0.74 0.76 254
korean 0.85 0.81 0.83 242
thai 0.71 0.86 0.78 227
accuracy 0.79 1199
macro avg 0.79 0.79 0.79 1199
weighted avg 0.79 0.79 0.79 1199
```
## Classificatore K-Neighbors
K-Neighbors fa parte della famiglia dei metodi ML "neighbors" (vicini), che possono essere utilizzati sia per l'apprendimento supervisionato che non supervisionato. In questo metodo, viene creato un numero predefinito di punti e i dati vengono raccolti attorno a questi punti in modo tale da poter prevedere etichette generalizzate per i dati.
### Esercizio: applicare il classificatore K-Neighbors
Il classificatore precedente era buono e funzionava bene con i dati, ma forse si può ottenere una maggiore precisione. Provare un classificatore K-Neighbors.
1. Aggiungere una riga all'array classificatore (aggiungere una virgola dopo l'elemento Linear SVC):
```python
'KNN classifier': KNeighborsClassifier(C),
```
Il risultato è un po' peggio:
```output
Accuracy (train) for KNN classifier: 73.8%
precision recall f1-score support
chinese 0.64 0.67 0.66 242
indian 0.86 0.78 0.82 234
japanese 0.66 0.83 0.74 254
korean 0.94 0.58 0.72 242
thai 0.71 0.82 0.76 227
accuracy 0.74 1199
macro avg 0.76 0.74 0.74 1199
weighted avg 0.76 0.74 0.74 1199
```
✅ Scoprire [K-Neighbors](https://scikit-learn.org/stable/modules/neighbors.html#neighbors)
## Classificatore Support Vector
I classificatori Support-Vector fanno parte della famiglia di metodi ML [Support-Vector Machine](https://it.wikipedia.org/wiki/Macchine_a_vettori_di_supporto) utilizzati per le attività di classificazione e regressione. Le SVM "mappano esempi di addestramento in punti nello spazio" per massimizzare la distanza tra due categorie. I dati successivi vengono mappati in questo spazio in modo da poter prevedere la loro categoria.
### Esercizio: applicare un classificatore di vettori di supporto
Si prova a ottenere una precisione leggermente migliore con un classificatore di vettori di supporto.
1. Aggiungere una virgola dopo l'elemento K-Neighbors, quindi aggiungere questa riga:
```python
'SVC': SVC(),
```
Il risultato è abbastanza buono!
```output
Accuracy (train) for SVC: 83.2%
precision recall f1-score support
chinese 0.79 0.74 0.76 242
indian 0.88 0.90 0.89 234
japanese 0.87 0.81 0.84 254
korean 0.91 0.82 0.86 242
thai 0.74 0.90 0.81 227
accuracy 0.83 1199
macro avg 0.84 0.83 0.83 1199
weighted avg 0.84 0.83 0.83 1199
```
✅ Scoprire i vettori di [supporto](https://scikit-learn.org/stable/modules/svm.html#svm)
## Classificatori ensamble
Si segue il percorso fino alla fine, anche se il test precedente è stato abbastanza buono. Si provano un po' di classificatori di ensemble, nello specifico Random Forest e AdaBoost:
```python
'RFST': RandomForestClassifier(n_estimators=100),
'ADA': AdaBoostClassifier(n_estimators=100)
```
Il risultato è molto buono, soprattutto per Random Forest:
```output
Accuracy (train) for RFST: 84.5%
precision recall f1-score support
chinese 0.80 0.77 0.78 242
indian 0.89 0.92 0.90 234
japanese 0.86 0.84 0.85 254
korean 0.88 0.83 0.85 242
thai 0.80 0.87 0.83 227
accuracy 0.84 1199
macro avg 0.85 0.85 0.84 1199
weighted avg 0.85 0.84 0.84 1199
Accuracy (train) for ADA: 72.4%
precision recall f1-score support
chinese 0.64 0.49 0.56 242
indian 0.91 0.83 0.87 234
japanese 0.68 0.69 0.69 254
korean 0.73 0.79 0.76 242
thai 0.67 0.83 0.74 227
accuracy 0.72 1199
macro avg 0.73 0.73 0.72 1199
weighted avg 0.73 0.72 0.72 1199
```
✅ Ulteriori informazioni sui [classificatori di ensemble](https://scikit-learn.org/stable/modules/ensemble.html)
Questo metodo di Machine Learning "combina le previsioni di diversi stimatori di base" per migliorare la qualità del modello. In questo esempio, si è utilizzato Random Trees e AdaBoost.
- [Random Forest](https://scikit-learn.org/stable/modules/ensemble.html#forest), un metodo di calcolo della media, costruisce una "foresta" di "alberi decisionali" infusi di casualità per evitare il sovradattamento. Il parametro n_estimators è impostato sul numero di alberi.
- [AdaBoost](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html) adatta un classificatore a un insieme di dati e quindi adatta le copie di quel classificatore allo stesso insieme di dati. Si concentra sui pesi degli elementi classificati in modo errato e regola l'adattamento per il successivo classificatore da correggere.
---
## 🚀 Sfida
Ognuna di queste tecniche ha un gran numero di parametri che si possono modificare. Ricercare i parametri predefiniti di ciascuno e pensare a cosa significherebbe modificare questi parametri per la qualità del modello.
## [Quiz post-lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/24/)
## Revisione e Auto Apprendimento
C'è molto gergo in queste lezioni, quindi si prenda un minuto per rivedere [questo elenco](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-15963-cxa) di terminologia utile!
## Compito
[Giocore coi parametri](assignment.it.md)

@ -0,0 +1,11 @@
# Giocore coi parametri
## Istruzioni
Ci sono molti parametri impostati in modalità predefinita quando si lavora con questi classificatori. Intellisense in VS Code può aiutare a scavare in loro. Adottare una delle tecniche di classificazione ML in questa lezione e riaddestrare i modelli modificando i vari valori dei parametri. Costruire un notebook spiegando perché alcune modifiche aiutano la qualità del modello mentre altre la degradano. La risposta sia dettagliata.
## Rubrica
| Criteri | Ottimo | Adeguato | Necessita miglioramento |
| -------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | ----------------------------- |
| | Un notebook viene presentato con un classificatore completamente costruito e i suoi parametri ottimizzati e le modifiche spiegate nelle caselle di testo | Un quaderno è presentato parzialmente o spiegato male | Un notebook contiene errori o è difettoso |

@ -0,0 +1,336 @@
# Costruire un'App Web per Consigliare una Cucina
In questa lezione si creerà un modello di classificazione utilizzando alcune delle tecniche apprese nelle lezioni precedenti e con il delizioso insieme di dati sulla cucina utilizzato in questa serie. Inoltre, si creerà una piccola app web per utilizzare un modello salvato, sfruttando il runtime web di Onnx.
Uno degli usi pratici più utili dell'apprendimento automatico è la creazione di sistemi di raccomandazione e oggi si può fare il primo passo in quella direzione!
[![Introduzione ai Sistemi di Raccomandazione](https://img.youtube.com/vi/giIXNoiqO_U/0.jpg)](https://youtu.be/giIXNoiqO_U "Introduzione ai Sistemi di Raccomandazione")
> 🎥 Fare clic sull'immagine sopra per un video: Andrew Ng introduce la progettazione di un sistema di raccomandazione
## [Quiz Pre-Lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/25/)
In questa lezione, si imparerà:
- Come costruire un modello e salvarlo come modello Onnx
- Come usare Netron per ispezionare il modello
- Come utilizzare il modello in un'app web per l'inferenza
## Costruire il modello
La creazione di sistemi ML applicati è una parte importante dell'utilizzo di queste tecnologie per i sistemi aziendali. Si possono utilizzare i modelli all'interno delle proprie applicazioni web (e quindi utilizzarli in un contesto offline se necessario) utilizzando Onnx.
In una [lezione precedente](../../../3-Web-App/1-Web-App/translations/README.it.md) si è costruito un modello di regressione sugli avvistamenti di UFO, è stato serializzato e lo si è utilizzato in un'app Flask. Sebbene questa architettura sia molto utile da conoscere, è un'app Python completa e i requisiti potrebbero includere l'uso di un'applicazione JavaScript.
In questa lezione si può creare un sistema di inferenza di base utilizzando JavaScript. Prima, tuttavia, è necessario addestrare un modello e convertirlo per l'utilizzo con Onnx.
## Esercizio - modello di classificazione di addestramento
Innanzitutto, addestrare un modello di classificazione utilizzando l'insieme di dati pulito delle cucine precedentemente usato.
1. Iniziare importando librerie utili:
```python
!pip install skl2onnx
import pandas as pd
```
Serve '[skl2onnx](https://onnx.ai/sklearn-onnx/)' per poter convertire il modello di Scikit-learn in formato Onnx.
1. Quindi si lavora con i dati nello stesso modo delle lezioni precedenti, leggendo un file CSV usando `read_csv()`:
```python
data = pd.read_csv('../data/cleaned_cuisine.csv')
data.head()
```
1. Rimuovere le prime due colonne non necessarie e salvare i dati rimanenti come "X":
```python
X = data.iloc[:,2:]
X.head()
```
1. Salvare le etichette come "y":
```python
y = data[['cuisine']]
y.head()
```
### Iniziare la routine di addestramento
Verrà usata la libreria 'SVC' che ha una buona precisione.
1. Importare le librerie appropriate da 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. Separare gli insiemi di allenamento e test:
```python
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3)
```
1. Costruire un modello di classificazione SVC come fatto nella lezione precedente:
```python
model = SVC(kernel='linear', C=10, probability=True,random_state=0)
model.fit(X_train,y_train.values.ravel())
```
1. Ora provare il modello, chiamando `predict()`:
```python
y_pred = model.predict(X_test)
```
1. Stampare un rapporto di classificazione per verificare la qualità del modello:
```python
print(classification_report(y_test,y_pred))
```
Come visto prima, la precisione è buona:
```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
```
### Convertire il modello in Onnx
Assicurarsi di eseguire la conversione con il numero tensore corretto. Questo insieme di dati ha 380 ingredienti elencati, quindi è necessario annotare quel numero in `FloatTensorType`:
1. Convertire usando un numero tensore di 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. Creare l'onx e salvarlo come file **model.onnx**:
```python
onx = convert_sklearn(model, initial_types=initial_type, options=options)
with open("./model.onnx", "wb") as f:
f.write(onx.SerializeToString())
```
> Nota, si possono passare le[opzioni](https://onnx.ai/sklearn-onnx/parameterized.html) nello script di conversione. In questo caso, si è passato 'nocl' come True e 'zipmap' come False. Poiché questo è un modello di classificazione, si ha la possibilità di rimuovere ZipMap che produce un elenco di dizionari (non necessario). `nocl` si riferisce alle informazioni sulla classe incluse nel modello. Ridurre le dimensioni del modello impostando `nocl` su 'True'.
L'esecuzione dell'intero notebook ora creerà un modello Onnx e lo salverà in questa cartella.
## Visualizzare il modello
I modelli Onnx non sono molto visualizzabili in Visual Studio code, ma c'è un ottimo software gratuito che molti ricercatori usano per visualizzare il modello per assicurarsi che sia costruito correttamente. Scaricare [Netron](https://github.com/lutzroeder/Netron) e aprire il file model.onnx. Si può vedere il modello semplice visualizzato, con i suoi 380 input e classificatore elencati:
![Vista Netron ](../images/netron.png)
Netron è uno strumento utile per visualizzare i modelli.
Ora si è pronti per utilizzare questo modello accurato in un'app web. Si costruisce un'app che tornerà utile quando si guarda nel frigorifero e si prova a capire quale combinazione di ingredienti avanzati si può usare per cucinare una determinata tipologia di cucina, come determinato dal modello.
## Creare un'applicazione web di raccomandazione
Si può utilizzare il modello direttamente in un'app web. Questa architettura consente anche di eseguirlo localmente e anche offline se necessario. Iniziare creando un file `index.html` nella stessa cartella in cui si è salvato il file `model.onnx`.
1. In questo file _index.html_, aggiungere il seguente codice markup:
```html
<!DOCTYPE html>
<html>
<header>
<title>Cuisine Matcher</title>
</header>
<body>
...
</body>
</html>
```
1. Ora, lavorando all'interno del tag `body` , aggiungere un piccolo markup per mostrare un elenco di caselle di controllo che riflettono alcuni ingredienti:
```html
<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>
```
Notare che a ogni casella di controllo viene assegnato un valore. Questo riflette l'indice in cui si trova l'ingrediente in base all'insieme di dati. Apple, ad esempio, in questo elenco alfabetico, occupa la quinta colonna, quindi il suo valore è "4" poiché si inizia a contare da 0. Si può consultare il [foglio di calcolo degli ingredienti](../../data/ingredient_indexes.csv) per scoprire l'indice di un determinato ingrediente.
Continuando il lavoro nel file index.html, aggiungere un blocco di script in cui viene chiamato il modello dopo la chiusura del tag `</div>` finale.
1. Innanzitutto, importare il [runtime Onnx](https://www.onnxruntime.ai/):
```html
<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.8.0-dev.20210608.0/dist/ort.min.js"></script>
```
> Onnx Runtime viene utilizzato per consentire l'esecuzione dei modelli Onnx su un'ampia gamma di piattaforme hardware, comprese le ottimizzazioni e un'API da utilizzare.
1. Una volta che il Runtime è a posto, lo si può chiamare:
```javascript
<script>
const ingredients = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
const checks = [].slice.call(document.querySelectorAll('.checkbox'));
// use an async context to call onnxruntime functions.
function init() {
checks.forEach(function (checkbox, index) {
checkbox.onchange = function () {
if (this.checked) {
var index = checkbox.value;
if (index !== -1) {
ingredients[index] = 1;
}
console.log(ingredients)
}
else {
var index = checkbox.value;
if (index !== -1) {
ingredients[index] = 0;
}
console.log(ingredients)
}
}
})
}
function testCheckboxes() {
for (var i = 0; i < checks.length; i++)
if (checks[i].type == "checkbox")
if (checks[i].checked)
return true;
return false;
}
async function startInference() {
let checked = testCheckboxes()
if (checked) {
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: ${e}.`);
}
}
else alert("Please check an ingredient")
}
init();
</script>
```
In questo codice, accadono diverse cose:
1. Si è creato un array di 380 possibili valori (1 o 0) da impostare e inviare al modello per l'inferenza, a seconda che una casella di controllo dell'ingrediente sia selezionata.
2. Si è creata una serie di caselle di controllo e un modo per determinare se sono state selezionate in una funzione `init` chiamata all'avvio dell'applicazione. Quando una casella di controllo è selezionata, l 'array `ingredients` viene modificato per riflettere l'ingrediente scelto.
3. Si è creata una funzione `testCheckboxes` che controlla se una casella di controllo è stata selezionata.
4. Si utilizza quella funzione quando si preme il pulsante e, se una casella di controllo è selezionata, si avvia l'inferenza.
5. La routine di inferenza include:
1. Impostazione di un caricamento asincrono del modello
2. Creazione di una struttura tensoriale da inviare al modello
3. Creazione di "feed" che riflettano l'input `float_input` creato durante l'addestramento del modello (si può usare Netron per verificare quel nome)
4. Invio di questi "feed" al modello e attesa di una risposta
## Verificare l'applicazione
Aprire una sessione terminale in Visual Studio Code nella cartella in cui risiede il file index.html. Assicurarsi di avere [http-server](https://www.npmjs.com/package/http-server) installato globalmente e digitare `http-server` al prompt. Dovrebbe aprirsi nel browser un localhost e si può visualizzare l'app web. Controllare quale cucina è consigliata in base ai vari ingredienti:
![app web degli ingredienti](../images/web-app.png)
Congratulazioni, si è creato un'app web di "raccomandazione" con pochi campi. Si prenda del tempo per costruire questo sistema!
## 🚀 Sfida
L'app web è molto minimale, quindi continuare a costruirla usando gli ingredienti e i loro indici dai dati [ingredient_indexes](../../data/ingredient_indexes.csv) . Quali combinazioni di sapori funzionano per creare un determinato piatto nazionale?
## [Quiz post-lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/26/)
## Revisione e Auto Apprendimento
Sebbene questa lezione abbia appena toccato l'utilità di creare un sistema di raccomandazione per gli ingredienti alimentari, quest'area delle applicazioni ML è molto ricca di esempi. Leggere di più su come sono costruiti questi sistemi:
- 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/
## Compito
[Creare un nuovo sistema di raccomandazione](assignment.it.md)

@ -0,0 +1,11 @@
# Creare un sistema di raccomandazione
## Istruzioni
Dati gli esercizi di questa lezione, ora si conosce come creare un'app Web basata su JavaScript utilizzando Onnx Runtime e un modello Onnx convertito. Sperimentare con la creazione di un nuovo sistema di raccomandazione utilizzando i dati di queste lezioni o provenienti da altre parti (citare le fonti, per favore). Si potrebbe creare un sistema di raccomandazione di animali domestici in base a vari attributi della personalità o un sistema di raccomandazione di genere musicale basato sull'umore di una persona. Dare sfogo alla creatività!
## Rubrica
| Criteri | Ottimo | Adeguato | Necessita miglioramento |
| -------- | ---------------------------------------------------------------------- | ------------------------------------- | --------------------------------- |
| | Vengono presentati un'app Web e un notebook, entrambi ben documentati e funzionanti | Uno di quei due è mancante o difettoso | Entrambi sono mancanti o difettosi |

@ -0,0 +1,26 @@
# Iniziare con la classificazione
## Argomento regionale: Deliziose Cucine Asiatiche e Indiane 🍜
In Asia e in India, le tradizioni alimentari sono estremamente diverse e molto deliziose! Si darà un'occhiata ai dati sulle cucine regionali per cercare di capirne gli ingredienti.
![Venditore di cibo tailandese](../images/thai-food.jpg)
> Foto di <a href="https://unsplash.com/@changlisheng?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Lisheng Chang</a> su <a href="https://unsplash.com/s/photos/asian-food?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
## Cosa si imparerà
In questa sezione si approfondiranno le abilità sulla regressione apprese nella prima parte di questo programma di studi per conoscere altri classificatori da poter utilizzare e che aiuteranno a conoscere i propri dati.
> Esistono utili strumenti a basso codice che possono aiutare a imparare a lavorare con i modelli di regressione. Si provi [Azure ML per questa attività](https://docs.microsoft.com/learn/modules/create-classification-model-azure-machine-learning-designer/?WT.mc_id=academic-15963-cxa)
## Lezioni
1. [Introduzione alla classificazione](../1-Introduction/translations/README.it.md)
2. [Più classificatori](../2-Classifiers-1/translations/README.it.md)
3. [Ancora altri classificatori](../3-Classifiers-2/translations/README.it.md)
4. [Machine Learning applicato: sviluppare un'app web](../4-Applied/translations/README.it.md)
## Crediti
"Iniziare con la classificazione" è stato scritto con ♥️ da [Cassie Breviu](https://www.twitter.com/cassieview) e [Jen Looper](https://www.twitter.com/jenlooper)
L'insieme di dati sulle deliziose cucine proviene da [Kaggle](https://www.kaggle.com/hoandan/asian-and-indian-cuisines)
Loading…
Cancel
Save