В этом уроке вы будете использовать набор данных, который сохранили в прошлом уроке, полный сбалансированных, чистых данных о кухнях.
Вы будете использовать этот набор данных с различными классификаторами, чтобы предсказать национальную кухню по набору ингредиентов. При этом вы узнаете больше о некоторых способах использования алгоритмов для задач классификации.
Если вы завершили Урок 1, убедитесь, что файл cleaned_cuisines.csv существует в корневой папке /data для этих четырёх уроков.
-
Работая в папке notebook.ipynb этого урока, импортируйте этот файл вместе с библиотекой Pandas:
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 |
-
Теперь импортируйте ещё несколько библиотек:
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
-
Разделите координаты X и y на два датафрейма для обучения.
cuisineможет быть датафреймом с метками:cuisines_label_df = cuisines_df['cuisine'] cuisines_label_df.head()
Это будет выглядеть так:
0 indian 1 indian 2 indian 3 indian 4 indian Name: cuisine, dtype: object -
Удалите столбцы
Unnamed: 0иcuisine, вызвав методdrop(). Сохраните оставшиеся данные как признаки для обучения: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 |
| 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 |
Теперь вы готовы обучить вашу модель!
Теперь, когда ваши данные чистые и готовы к обучению, вам нужно решить, какой алгоритм использовать для задачи.
Scikit-learn объединяет классификацию под категорией Обучение с учителем, и в этой категории вы найдете много способов классифицировать. Разнообразие сначала может ошеломить. Следующие методы включают техники классификации:
- Линейные модели
- Машины опорных векторов
- Стохастический градиентный спуск
- Ближайшие соседи
- Гауссовские процессы
- Деревья решений
- Ансамблевые методы (голосование классификаторов)
- Многоклассовые и многоцелевые алгоритмы (многоклассовая и многометочная классификация, многоклассово-многоцелевой классификатор)
Вы также можете использовать нейронные сети для классификации данных, но это вне рамок данного урока.
Итак, какой классификатор выбрать? Часто эффективным способом является запуск нескольких и поиск хорошего результата. Scikit-learn предлагает побочное сравнение на созданном наборе данных, сравнивая KNeighbors, SVC двумя способами, GaussianProcessClassifier, DecisionTreeClassifier, RandomForestClassifier, MLPClassifier, AdaBoostClassifier, GaussianNB и QuadraticDiscrinationAnalysis, показывая результаты визуализированными:
Графики из документации Scikit-learn
AutoML решает эту задачу аккуратно, запуская эти сравнения в облаке, позволяя вам выбрать лучший алгоритм для ваших данных. Попробуйте здесь
Лучшим методом, чем слепое угадывание, является следование идеям из этого загружаемого справочника по ML. Здесь мы узнаём, что для нашей задачи с многоклассовой классификацией у нас есть несколько вариантов:
Раздел справочника Microsoft по алгоритмам, описывающий варианты многоклассовой классификации
✅ Скачайте этот справочник, распечатайте и повесьте на стену!
Давайте попробуем рассуждать по поводу разных подходов с учётом имеющихся ограничений:
- Нейронные сети слишком тяжёлые. Учитывая наш чистый, но небольшой набор данных и тот факт, что обучение проводится локально в ноутбуках, нейронные сети слишком ресурсоёмки для этой задачи.
- Нет двухклассового классификатора. Мы не используем классификатор для двух классов, это исключает схему один-против-всех.
- Дерево решений или логистическая регрессия могут подойти. Дерево решений может подойти, или логистическая регрессия для многоклассовых данных.
- Многоклассовые бустинговые деревья решают другую задачу. Они более подходящи для непараметрических задач, например, для построения ранжирований, что нам не нужно.
Мы будем использовать Scikit-learn для анализа наших данных. Однако существует много способов использовать логистическую регрессию в Scikit-learn. Посмотрите параметры, которые можно передать здесь.
В основном, есть два важных параметра — 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'. Поскольку логистическая регрессия изначально предназначена для бинарной классификации, эти схемы позволяют лучше обрабатывать многоклассовые задачи. источник
🎓 'Solver' определяется как "алгоритм, используемый для решения задачи оптимизации". источник.
Scikit-learn предлагает эту таблицу, чтобы объяснить, как решатели справляются с различными типами данных:
Мы можем сосредоточиться на логистической регрессии для первой попытки обучения, так как вы недавно изучали её в предыдущем уроке.
Разделите данные на обучающую и тестовую выборки, вызвав train_test_split():
X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)Так как вы используете многоклассовый случай, нужно выбрать, какую схему использовать и какой решатель задать. Используйте LogisticRegression с многоклассовой настройкой и решателем liblinear для обучения.
-
Создайте логистическую регрессию с параметром multi_class, установленным в
ovr, и решателем, установленным вliblinear: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для уплощения данных, когда это необходимо.Точность хорошая — более 80%!
-
Вы можете увидеть работу модели, проверив одну строку данных (#50):
print(f'ingredients: {X_test.iloc[50][X_test.iloc[50]!=0].keys()}') print(f'cuisine: {y_test.iloc[50]}')
Результат выводится:
ingredients: Index(['cilantro', 'onion', 'pea', 'potato', 'tomato', 'vegetable_oil'], dtype='object') cuisine: indian✅ Попробуйте другой номер строки и проверьте результаты
-
Вникая глубже, вы можете проверить точность этого предсказания:
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 ✅ Можете ли вы объяснить, почему модель достаточно уверена, что это индийская кухня?
-
Получите больше информации, распечатав отчет о классификации, как вы делали в уроках по регрессии:
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), чтобы понять, что происходит за кулисами.
Углубитесь в математику, лежащую в основе логистической регрессии, в этом уроке
Отказ от ответственности:
Этот документ был переведён с помощью сервиса автоматического перевода Co-op Translator. Хотя мы стремимся к точности, имейте в виду, что автоматические переводы могут содержать ошибки или неточности. Оригинальный документ на родном языке следует считать авторитетным источником. Для получения критически важной информации рекомендуется обращаться к профессиональному человеческому переводу. Мы не несем ответственности за любые недоразумения или неправильные толкования, возникшие в результате использования данного перевода.


