You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ML-For-Beginners/translations/ru/4-Classification/2-Classifiers-1/README.md

247 lines
20 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Классификаторы кухни 1
В этом уроке вы будете использовать набор данных, который сохранили в прошлом уроке, полный сбалансированных, чистых данных о кухнях.
Вы будете использовать этот набор данных с различными классификаторами, чтобы _предсказать национальную кухню по набору ингредиентов_. При этом вы узнаете больше о некоторых способах использования алгоритмов для задач классификации.
## [Тест перед лекцией](https://ff-quizzes.netlify.app/en/ml/)
# Подготовка
Если вы завершили [Урок 1](../1-Introduction/README.md), убедитесь, что файл _cleaned_cuisines.csv_ существует в корневой папке `/data` для этих четырёх уроков.
## Упражнение предсказать национальную кухню
1. Работая в папке _notebook.ipynb_ этого урока, импортируйте этот файл вместе с библиотекой Pandas:
```python
import pandas as pd
cuisines_df = pd.read_csv("../data/cleaned_cuisines.csv")
cuisines_df.head()
```
Данные выглядят так:
| | 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. Теперь импортируйте ещё несколько библиотек:
```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. Разделите координаты X и y на два датафрейма для обучения. `cuisine` может быть датафреймом с метками:
```python
cuisines_label_df = cuisines_df['cuisine']
cuisines_label_df.head()
```
Это будет выглядеть так:
```output
0 indian
1 indian
2 indian
3 indian
4 indian
Name: cuisine, dtype: object
```
1. Удалите столбцы `Unnamed: 0` и `cuisine`, вызвав метод `drop()`. Сохраните оставшиеся данные как признаки для обучения:
```python
cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)
cuisines_feature_df.head()
```
Ваши признаки выглядят так:
| | 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 | 0 |
| 1 | 1 | 0 | 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 | 0 |
| 3 | 0 | 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 | 0 |
Теперь вы готовы обучить вашу модель!
## Выбор классификатора
Теперь, когда ваши данные чистые и готовы к обучению, вам нужно решить, какой алгоритм использовать для задачи.
Scikit-learn объединяет классификацию под категорией Обучение с учителем, и в этой категории вы найдете много способов классифицировать. [Разнообразие](https://scikit-learn.org/stable/supervised_learning.html) сначала может ошеломить. Следующие методы включают техники классификации:
- Линейные модели
- Машины опорных векторов
- Стохастический градиентный спуск
- Ближайшие соседи
- Гауссовские процессы
- Деревья решений
- Ансамблевые методы (голосование классификаторов)
- Многоклассовые и многоцелевые алгоритмы (многоклассовая и многометочная классификация, многоклассово-многоцелевой классификатор)
> Вы также можете использовать [нейронные сети для классификации данных](https://scikit-learn.org/stable/modules/neural_networks_supervised.html#classification), но это вне рамок данного урока.
### Какой классификатор выбрать?
Итак, какой классификатор выбрать? Часто эффективным способом является запуск нескольких и поиск хорошего результата. Scikit-learn предлагает [побочное сравнение](https://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html) на созданном наборе данных, сравнивая KNeighbors, SVC двумя способами, GaussianProcessClassifier, DecisionTreeClassifier, RandomForestClassifier, MLPClassifier, AdaBoostClassifier, GaussianNB и QuadraticDiscrinationAnalysis, показывая результаты визуализированными:
![сравнение классификаторов](../../../../translated_images/ru/comparison.edfab56193a85e7f.webp)
> Графики из документации Scikit-learn
> AutoML решает эту задачу аккуратно, запуская эти сравнения в облаке, позволяя вам выбрать лучший алгоритм для ваших данных. Попробуйте [здесь](https://docs.microsoft.com/learn/modules/automate-model-selection-with-azure-automl/?WT.mc_id=academic-77952-leestott)
### Лучший подход
Лучшим методом, чем слепое угадывание, является следование идеям из этого загружаемого [справочника по ML](https://docs.microsoft.com/azure/machine-learning/algorithm-cheat-sheet?WT.mc_id=academic-77952-leestott). Здесь мы узнаём, что для нашей задачи с многоклассовой классификацией у нас есть несколько вариантов:
![шпаргалка по многоклассовым задачам](../../../../translated_images/ru/cheatsheet.07a475ea444d2223.webp)
> Раздел справочника Microsoft по алгоритмам, описывающий варианты многоклассовой классификации
✅ Скачайте этот справочник, распечатайте и повесьте на стену!
### Рассуждения
Давайте попробуем рассуждать по поводу разных подходов с учётом имеющихся ограничений:
- **Нейронные сети слишком тяжёлые**. Учитывая наш чистый, но небольшой набор данных и тот факт, что обучение проводится локально в ноутбуках, нейронные сети слишком ресурсоёмки для этой задачи.
- **Нет двухклассового классификатора**. Мы не используем классификатор для двух классов, это исключает схему один-против-всех.
- **Дерево решений или логистическая регрессия могут подойти**. Дерево решений может подойти, или логистическая регрессия для многоклассовых данных.
- **Многоклассовые бустинговые деревья решают другую задачу**. Они более подходящи для непараметрических задач, например, для построения ранжирований, что нам не нужно.
### Использование Scikit-learn
Мы будем использовать Scikit-learn для анализа наших данных. Однако существует много способов использовать логистическую регрессию в Scikit-learn. Посмотрите параметры, которые можно передать [здесь](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html?highlight=logistic%20regressio#sklearn.linear_model.LogisticRegression).
В основном, есть два важных параметра — `multi_class` и `solver` — которые нужно указать, когда вы просите Scikit-learn выполнить логистическую регрессию. Значение `multi_class` задаёт определённое поведение. Значение `solver` указывает, какой алгоритм использовать. Не все решения (solvers) совместимы со всеми значениями `multi_class`.
Согласно документации, в случае многоклассовой задачи алгоритм обучения:
- **Использует схему one-vs-rest (OvR)**, если опция `multi_class` установлена в `ovr`
- **Использует функцию потерь кросс-энтропии**, если `multi_class` установлена в `multinomial`. (В настоящее время опция `multinomial` поддерживается только решателями lbfgs, sag, saga и newton-cg)."
> 🎓 Здесь 'scheme' может быть 'ovr' (один-против-остальных) или 'multinomial'. Поскольку логистическая регрессия изначально предназначена для бинарной классификации, эти схемы позволяют лучше обрабатывать многоклассовые задачи. [источник](https://machinelearningmastery.com/one-vs-rest-and-one-vs-one-for-multi-class-classification/)
> 🎓 'Solver' определяется как "алгоритм, используемый для решения задачи оптимизации". [источник](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html?highlight=logistic%20regressio#sklearn.linear_model.LogisticRegression).
Scikit-learn предлагает эту таблицу, чтобы объяснить, как решатели справляются с различными типами данных:
![решатели](../../../../translated_images/ru/solvers.5fc648618529e627.webp)
## Упражнение разделение данных
Мы можем сосредоточиться на логистической регрессии для первой попытки обучения, так как вы недавно изучали её в предыдущем уроке.
Разделите данные на обучающую и тестовую выборки, вызвав `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)
```
## Упражнение применить логистическую регрессию
Так как вы используете многоклассовый случай, нужно выбрать, какую _схему_ использовать и какой _решатель_ задать. Используйте LogisticRegression с многоклассовой настройкой и решателем **liblinear** для обучения.
1. Создайте логистическую регрессию с параметром multi_class, установленным в `ovr`, и решателем, установленным в `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))
```
✅ Попробуйте другой решатель, например `lbfgs`, который часто используется по умолчанию
> Обратите внимание, используйте функцию Pandas [`ravel`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.ravel.html) для уплощения данных, когда это необходимо.
Точность хорошая — более **80%**!
1. Вы можете увидеть работу модели, проверив одну строку данных (#50):
```python
print(f'ingredients: {X_test.iloc[50][X_test.iloc[50]!=0].keys()}')
print(f'cuisine: {y_test.iloc[50]}')
```
Результат выводится:
```output
ingredients: Index(['cilantro', 'onion', 'pea', 'potato', 'tomato', 'vegetable_oil'], dtype='object')
cuisine: indian
```
✅ Попробуйте другой номер строки и проверьте результаты
1. Вникая глубже, вы можете проверить точность этого предсказания:
```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()
```
Результат напечатан индийская кухня является лучшим предположением с высокой вероятностью:
| | 0 |
| -------: | -------: |
| indian | 0.715851 |
| chinese | 0.229475 |
| japanese | 0.029763 |
| korean | 0.017277 |
| thai | 0.007634 |
✅ Можете ли вы объяснить, почему модель достаточно уверена, что это индийская кухня?
1. Получите больше информации, распечатав отчет о классификации, как вы делали в уроках по регрессии:
```python
y_pred = model.predict(X_test)
print(classification_report(y_test,y_pred))
```
| | precision | recall | f1-score | support |
| ------------ | --------- | ------ | -------- | ------- |
| chinese | 0.73 | 0.71 | 0.72 | 229 |
| indian | 0.91 | 0.93 | 0.92 | 254 |
| japanese | 0.70 | 0.75 | 0.72 | 220 |
| korean | 0.86 | 0.76 | 0.81 | 242 |
| thai | 0.79 | 0.85 | 0.82 | 254 |
| accuracy | | | 0.80 | 1199 |
| macro avg | 0.80 | 0.80 | 0.80 | 1199 |
| weighted avg | 0.80 | 0.80 | 0.80 | 1199 |
## 🚀Задача
В этом уроке вы использовали очищенные данные для построения модели машинного обучения, которая может предсказывать национальную кухню на основе набора ингредиентов. Найдите время, чтобы изучить множество вариантов, которые предоставляет Scikit-learn для классификации данных. Глубже разберитесь в концепции «решателя» (solver), чтобы понять, что происходит за кулисами.
## [Викторина после лекции](https://ff-quizzes.netlify.app/en/ml/)
## Обзор и самостоятельное изучение
Углубитесь в математику, лежащую в основе логистической регрессии, в [этом уроке](https://people.eecs.berkeley.edu/~russell/classes/cs194/f11/lectures/CS194%20Fall%202011%20Lecture%2006.pdf)
## Задание
[Изучите решатели](assignment.md)
---
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**Отказ от ответственности**:
Этот документ был переведён с помощью сервиса автоматического перевода [Co-op Translator](https://github.com/Azure/co-op-translator). Хотя мы стремимся к точности, имейте в виду, что автоматические переводы могут содержать ошибки или неточности. Оригинальный документ на родном языке следует считать авторитетным источником. Для получения критически важной информации рекомендуется обращаться к профессиональному человеческому переводу. Мы не несем ответственности за любые недоразумения или неправильные толкования, возникшие в результате использования данного перевода.
<!-- CO-OP TRANSLATOR DISCLAIMER END -->