|
|
<!--
|
|
|
CO_OP_TRANSLATOR_METADATA:
|
|
|
{
|
|
|
"original_hash": "aaf391d922bd6de5efba871d514c6d47",
|
|
|
"translation_date": "2025-09-05T00:51:52+00:00",
|
|
|
"source_file": "4-Classification/1-Introduction/README.md",
|
|
|
"language_code": "bg"
|
|
|
}
|
|
|
-->
|
|
|
# Въведение в класификацията
|
|
|
|
|
|
В тези четири урока ще разгледате основен аспект на класическото машинно обучение - _класификация_. Ще преминем през използването на различни алгоритми за класификация с набор от данни за всички невероятни кухни на Азия и Индия. Надяваме се, че сте гладни!
|
|
|
|
|
|

|
|
|
|
|
|
> Празнувайте паназиатските кухни в тези уроци! Изображение от [Jen Looper](https://twitter.com/jenlooper)
|
|
|
|
|
|
Класификацията е форма на [контролирано обучение](https://wikipedia.org/wiki/Supervised_learning), която има много общо с техниките за регресия. Ако машинното обучение е свързано с предсказване на стойности или имена на неща чрез използване на набори от данни, тогава класификацията обикновено се разделя на две групи: _бинарна класификация_ и _многокласова класификация_.
|
|
|
|
|
|
[](https://youtu.be/eg8DJYwdMyg "Въведение в класификацията")
|
|
|
|
|
|
> 🎥 Кликнете върху изображението по-горе за видео: Джон Гуттаг от MIT представя класификацията
|
|
|
|
|
|
Запомнете:
|
|
|
|
|
|
- **Линейната регресия** ви помогна да предскажете връзките между променливите и да направите точни прогнози за това къде нова точка от данни би попаднала спрямо тази линия. Например, можете да предскажете _каква ще бъде цената на тиква през септември спрямо декември_.
|
|
|
- **Логистичната регресия** ви помогна да откриете "бинарни категории": при тази ценова точка, _тиквата оранжева ли е или не е оранжева_?
|
|
|
|
|
|
Класификацията използва различни алгоритми, за да определи други начини за определяне на етикета или класа на дадена точка от данни. Нека работим с тези данни за кухни, за да видим дали, наблюдавайки група от съставки, можем да определим произхода на кухнята.
|
|
|
|
|
|
## [Тест преди лекцията](https://ff-quizzes.netlify.app/en/ml/)
|
|
|
|
|
|
> ### [Този урок е наличен на R!](../../../../4-Classification/1-Introduction/solution/R/lesson_10.html)
|
|
|
|
|
|
### Въведение
|
|
|
|
|
|
Класификацията е една от основните дейности на изследователя в областта на машинното обучение и на специалиста по данни. От основна класификация на бинарна стойност ("този имейл спам ли е или не?") до сложна класификация на изображения и сегментация с помощта на компютърно зрение, винаги е полезно да можете да сортирате данни в класове и да задавате въпроси за тях.
|
|
|
|
|
|
За да опишем процеса по-научно, вашият метод за класификация създава предсказателен модел, който ви позволява да картографирате връзката между входните променливи и изходните променливи.
|
|
|
|
|
|

|
|
|
|
|
|
> Бинарни срещу многокласови проблеми, които алгоритмите за класификация трябва да решат. Инфографика от [Jen Looper](https://twitter.com/jenlooper)
|
|
|
|
|
|
Преди да започнем процеса на почистване на данните, визуализирането им и подготовката им за нашите задачи по машинно обучение, нека научим малко повече за различните начини, по които машинното обучение може да се използва за класифициране на данни.
|
|
|
|
|
|
Произлизаща от [статистиката](https://wikipedia.org/wiki/Statistical_classification), класификацията с помощта на класическо машинно обучение използва характеристики като `smoker`, `weight` и `age`, за да определи _вероятността за развитие на дадено заболяване_. Като техника за контролирано обучение, подобна на упражненията за регресия, които извършихте по-рано, вашите данни са етикетирани, а алгоритмите за машинно обучение използват тези етикети, за да класифицират и предсказват класове (или 'характеристики') на набор от данни и да ги присвояват към група или резултат.
|
|
|
|
|
|
✅ Отделете момент, за да си представите набор от данни за кухни. Какво би могъл да отговори многокласов модел? Какво би могъл да отговори бинарен модел? Какво ако искате да определите дали дадена кухня вероятно използва сминдух? А какво ако искате да видите дали, при наличието на торба с хранителни продукти, съдържаща звезден анасон, артишок, карфиол и хрян, можете да създадете типично индийско ястие?
|
|
|
|
|
|
[](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
|
|
|
<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
|
|
|
```
|
|
|
|
|
|
## Упражнение - изучаване на кухни
|
|
|
|
|
|
Сега работата започва да става по-интересна. Нека открием разпределението на данните по кухни.
|
|
|
|
|
|
1. Начертайте данните като барове, като извикате `barh()`:
|
|
|
|
|
|
```python
|
|
|
df.cuisine.value_counts().plot.barh()
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
Има ограничен брой кухни, но разпределението на данните е неравномерно. Можете да поправите това! Преди да го направите, изследвайте малко повече.
|
|
|
|
|
|
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()
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
1. Направете същото за японските данни:
|
|
|
|
|
|
```python
|
|
|
japanese_ingredient_df = create_ingredient_df(japanese_df)
|
|
|
japanese_ingredient_df.head(10).plot.barh()
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
1. Сега за китайските съставки:
|
|
|
|
|
|
```python
|
|
|
chinese_ingredient_df = create_ingredient_df(chinese_df)
|
|
|
chinese_ingredient_df.head(10).plot.barh()
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
1. Начертайте индийските съставки:
|
|
|
|
|
|
```python
|
|
|
indian_ingredient_df = create_ingredient_df(indian_df)
|
|
|
indian_ingredient_df.head(10).plot.barh()
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
1. Накрая начертайте корейските съставки:
|
|
|
|
|
|
```python
|
|
|
korean_ingredient_df = create_ingredient_df(korean_df)
|
|
|
korean_ingredient_df.head(10).plot.barh()
|
|
|
```
|
|
|
|
|
|

|
|
|
|
|
|
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). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод. |