# Въведение в класификацията В тези четири урока ще разгледате основен аспект на класическото машинно обучение - _класификация_. Ще преминем през използването на различни алгоритми за класификация с набор от данни за всички невероятни кухни на Азия и Индия. Надяваме се, че сте гладни! ![само щипка!](../../../../4-Classification/1-Introduction/images/pinch.png) > Празнувайте паназиатските кухни в тези уроци! Изображение от [Jen Looper](https://twitter.com/jenlooper) Класификацията е форма на [контролирано обучение](https://wikipedia.org/wiki/Supervised_learning), която има много общо с техниките за регресия. Ако машинното обучение е свързано с предсказване на стойности или имена на неща чрез използване на набори от данни, тогава класификацията обикновено се разделя на две групи: _бинарна класификация_ и _многокласова класификация_. [![Въведение в класификацията](https://img.youtube.com/vi/eg8DJYwdMyg/0.jpg)](https://youtu.be/eg8DJYwdMyg "Въведение в класификацията") > 🎥 Кликнете върху изображението по-горе за видео: Джон Гуттаг от MIT представя класификацията Запомнете: - **Линейната регресия** ви помогна да предскажете връзките между променливите и да направите точни прогнози за това къде нова точка от данни би попаднала спрямо тази линия. Например, можете да предскажете _каква ще бъде цената на тиква през септември спрямо декември_. - **Логистичната регресия** ви помогна да откриете "бинарни категории": при тази ценова точка, _тиквата оранжева ли е или не е оранжева_? Класификацията използва различни алгоритми, за да определи други начини за определяне на етикета или класа на дадена точка от данни. Нека работим с тези данни за кухни, за да видим дали, наблюдавайки група от съставки, можем да определим произхода на кухнята. ## [Тест преди лекцията](https://ff-quizzes.netlify.app/en/ml/) > ### [Този урок е наличен на R!](../../../../4-Classification/1-Introduction/solution/R/lesson_10.html) ### Въведение Класификацията е една от основните дейности на изследователя в областта на машинното обучение и на специалиста по данни. От основна класификация на бинарна стойност ("този имейл спам ли е или не?") до сложна класификация на изображения и сегментация с помощта на компютърно зрение, винаги е полезно да можете да сортирате данни в класове и да задавате въпроси за тях. За да опишем процеса по-научно, вашият метод за класификация създава предсказателен модел, който ви позволява да картографирате връзката между входните променливи и изходните променливи. ![бинарна срещу многокласова класификация](../../../../4-Classification/1-Introduction/images/binary-multiclass.png) > Бинарни срещу многокласови проблеми, които алгоритмите за класификация трябва да решат. Инфографика от [Jen Looper](https://twitter.com/jenlooper) Преди да започнем процеса на почистване на данните, визуализирането им и подготовката им за нашите задачи по машинно обучение, нека научим малко повече за различните начини, по които машинното обучение може да се използва за класифициране на данни. Произлизаща от [статистиката](https://wikipedia.org/wiki/Statistical_classification), класификацията с помощта на класическо машинно обучение използва характеристики като `smoker`, `weight` и `age`, за да определи _вероятността за развитие на дадено заболяване_. Като техника за контролирано обучение, подобна на упражненията за регресия, които извършихте по-рано, вашите данни са етикетирани, а алгоритмите за машинно обучение използват тези етикети, за да класифицират и предсказват класове (или 'характеристики') на набор от данни и да ги присвояват към група или резултат. ✅ Отделете момент, за да си представите набор от данни за кухни. Какво би могъл да отговори многокласов модел? Какво би могъл да отговори бинарен модел? Какво ако искате да определите дали дадена кухня вероятно използва сминдух? А какво ако искате да видите дали, при наличието на торба с хранителни продукти, съдържаща звезден анасон, артишок, карфиол и хрян, можете да създадете типично индийско ястие? [![Луди мистериозни кошници](https://img.youtube.com/vi/GuTeDbaNoEU/0.jpg)](https://youtu.be/GuTeDbaNoEU "Луди мистериозни кошници") > 🎥 Кликнете върху изображението по-горе за видео. Цялата идея на шоуто 'Chopped' е "мистериозната кошница", където готвачите трябва да направят ястие от случайно избрани съставки. Сигурно модел за машинно обучение би помогнал! ## Здравейте, 'класификатор' Въпросът, който искаме да зададем на този набор от данни за кухни, всъщност е **многокласов въпрос**, тъй като имаме няколко потенциални национални кухни, с които да работим. Като имаме група от съставки, към кой от тези много класове ще се впишат данните? Scikit-learn предлага няколко различни алгоритма за класифициране на данни, в зависимост от вида на проблема, който искате да решите. В следващите два урока ще научите за някои от тези алгоритми. ## Упражнение - почистете и балансирайте данните си Първата задача, преди да започнете този проект, е да почистите и **балансирате** данните си, за да получите по-добри резултати. Започнете с празния файл _notebook.ipynb_ в корена на тази папка. Първото нещо, което трябва да инсталирате, е [imblearn](https://imbalanced-learn.org/stable/). Това е пакет за Scikit-learn, който ще ви позволи да балансирате данните по-добре (ще научите повече за тази задача след малко). 1. За да инсталирате `imblearn`, изпълнете `pip install`, както следва: ```python pip install imblearn ``` 1. Импортирайте пакетите, които са ви необходими, за да импортирате данните си и да ги визуализирате, също така импортирайте `SMOTE` от `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 ``` Сега сте готови да импортирате данните. 1. Следващата задача е да импортирате данните: ```python df = pd.read_csv('../data/cuisines.csv') ``` Използването на `read_csv()` ще прочете съдържанието на csv файла _cusines.csv_ и ще го постави в променливата `df`. 1. Проверете формата на данните: ```python df.head() ``` Първите пет реда изглеждат така: ```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. Получете информация за тези данни, като извикате `info()`: ```python df.info() ``` Вашият изход изглежда така: ```output RangeIndex: 2448 entries, 0 to 2447 Columns: 385 entries, Unnamed: 0 to zucchini dtypes: int64(384), object(1) memory usage: 7.2+ MB ``` ## Упражнение - изучаване на кухни Сега работата започва да става по-интересна. Нека открием разпределението на данните по кухни. 1. Начертайте данните като барове, като извикате `barh()`: ```python df.cuisine.value_counts().plot.barh() ``` ![разпределение на данни за кухни](../../../../4-Classification/1-Introduction/images/cuisine-dist.png) Има ограничен брой кухни, но разпределението на данните е неравномерно. Можете да поправите това! Преди да го направите, изследвайте малко повече. 1. Разберете колко данни са налични за всяка кухня и ги отпечатайте: ```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}') ``` изходът изглежда така: ```output thai df: (289, 385) japanese df: (320, 385) chinese df: (442, 385) indian df: (598, 385) korean df: (799, 385) ``` ## Откриване на съставки Сега можете да се задълбочите в данните и да научите кои са типичните съставки за всяка кухня. Трябва да премахнете повтарящи се данни, които създават объркване между кухните, така че нека научим за този проблем. 1. Създайте функция `create_ingredient()` на Python, за да създадете dataframe за съставките. Тази функция ще започне с премахване на ненужна колона и ще сортира съставките според техния брой: ```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 ``` Сега можете да използвате тази функция, за да получите представа за десетте най-популярни съставки по кухня. 1. Извикайте `create_ingredient()` и начертайте, като извикате `barh()`: ```python thai_ingredient_df = create_ingredient_df(thai_df) thai_ingredient_df.head(10).plot.barh() ``` ![тайландска](../../../../4-Classification/1-Introduction/images/thai.png) 1. Направете същото за японските данни: ```python japanese_ingredient_df = create_ingredient_df(japanese_df) japanese_ingredient_df.head(10).plot.barh() ``` ![японска](../../../../4-Classification/1-Introduction/images/japanese.png) 1. Сега за китайските съставки: ```python chinese_ingredient_df = create_ingredient_df(chinese_df) chinese_ingredient_df.head(10).plot.barh() ``` ![китайска](../../../../4-Classification/1-Introduction/images/chinese.png) 1. Начертайте индийските съставки: ```python indian_ingredient_df = create_ingredient_df(indian_df) indian_ingredient_df.head(10).plot.barh() ``` ![индийска](../../../../4-Classification/1-Introduction/images/indian.png) 1. Накрая начертайте корейските съставки: ```python korean_ingredient_df = create_ingredient_df(korean_df) korean_ingredient_df.head(10).plot.barh() ``` ![корейска](../../../../4-Classification/1-Introduction/images/korean.png) 1. Сега премахнете най-често срещаните съставки, които създават объркване между различните кухни, като извикате `drop()`: Всички обичат ориз, чесън и джинджифил! ```python feature_df= df.drop(['cuisine','Unnamed: 0','rice','garlic','ginger'], axis=1) labels_df = df.cuisine #.unique() feature_df.head() ``` ## Балансиране на набора от данни Сега, когато сте почистили данните, използвайте [SMOTE](https://imbalanced-learn.org/dev/references/generated/imblearn.over_sampling.SMOTE.html) - "Техника за синтетично надсемплиране на малцинствени класове" - за да ги балансирате. 1. Извикайте `fit_resample()`, тази стратегия генерира нови проби чрез интерполация. ```python oversample = SMOTE() transformed_feature_df, transformed_label_df = oversample.fit_resample(feature_df, labels_df) ``` Чрез балансиране на данните си ще получите по-добри резултати при класифицирането им. Помислете за бинарна класификация. Ако повечето от вашите данни са от един клас, моделът за машинно обучение ще предсказва този клас по-често, просто защото има повече данни за него. Балансирането на данните премахва този дисбаланс. 1. Сега можете да проверите броя на етикетите за всяка съставка: ```python print(f'new label count: {transformed_label_df.value_counts()}') print(f'old label count: {df.cuisine.value_counts()}') ``` Вашият изход изглежда така: ```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 ``` Данните са чисти, балансирани и много вкусни! 1. Последната стъпка е да запазите балансираните си данни, включително етикети и характеристики, в нов dataframe, който може да бъде експортиран във файл: ```python transformed_df = pd.concat([transformed_label_df,transformed_feature_df],axis=1, join='outer') ``` 1. Можете да погледнете данните още веднъж, като използвате `transformed_df.head()` и `transformed_df.info()`. Запазете копие от тези данни за използване в бъдещи уроци: ```python transformed_df.head() transformed_df.info() transformed_df.to_csv("../data/cleaned_cuisines.csv") ``` Този нов CSV файл вече може да бъде намерен в основната папка с данни. --- ## 🚀Предизвикателство Тази учебна програма съдържа няколко интересни набора от данни. Прегледайте папките `data` и вижте дали някои от тях съдържат набори от данни, които биха били подходящи за бинарна или многокласова класификация? Какви въпроси бихте задали на този набор от данни? ## [Тест след лекцията](https://ff-quizzes.netlify.app/en/ml/) ## Преглед и самостоятелно обучение Разгледайте API на SMOTE. За какви случаи на употреба е най-подходящ? Какви проблеми решава? ## Задание [Изследвайте методи за класификация](assignment.md) --- **Отказ от отговорност**: Този документ е преведен с помощта на AI услуга за превод [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.