Machine Learning: Как да разпределим в класове продукти чрез kNN?

Попадали ли сте в ситуация, в която имате база данни с множество еднотипни продукти, предварително разделени в класове. При добавяне на нов продукт какви са критериите, по които определяте точно в кой клас трябва да попадне той?

Тук на помощ идва класификацията. Тя е това, което ще придаде ред и структура, като групира по сходни характеристики. Идеята е да се намерят връзки между данните, които ни позволяват да направим разграничение между самите обекти. За да можем успешно да направим класификация, трябва да преценим кой би бил най-правилният метод за тази цел.

Съществуват най-различни начини за разпределяне на обекти в класове – Decision Tree, Random Forest, SVM (Support Vector Machines), kNN (k-nearest neighbors) и други. Кой метод да използваме определяме след задълбочен анализ на данните и множество тестове. Критерии за най-правилния метод са например каква е точността, колко време отнема за обучение, сложността на модела и други.

В тази статия ще разгледаме алгоритъма kNN и ще видим как действа той на практика чрез пример, в който ще разпределим продукти в класове.

Какво представлява kNN?

kNN е популярен алгоритъм за машинно обучение, който е предназначен за решаване на задачи, свързани с класификация на обекти или регресия. Използва се при необходимост от определяне кой обект с кои други си прилича (например групиране на клиенти със сходни характеристики).

kNN спада към тези алгоритми, които са с контролирано обучение (supervised), т.е. имаме набор от характеристики и целева променлива с известни стойности. На базата на тях обучаваме модела, като разделяме данните. Едната извадка се използва за обучение на модела, а другата за тест.

  • При класификация – един обект спада към класа, който е най-често срещан сред най-близките му k-съседи
  • При регресия – използва се за определяне на неизвестна характеристика на обект като се взима стойността, която най-много се наблюдава сред най-близките му k-съседи.

Какво е необходимо за класификация на обектите чрез kNN?

За прилагането на алгоритъма kNN е нужно да:

  • Изчислим разстоянията между обектите от обучаващата извадка
  • Изберем k обекти от обучаващата извадка, до които разстоянието е минимално
  • Поставим обекта в класа, който най-често се среща сред най-близките му k-съседи.

knn класификация 1 съсед

На изображението ясно се вижда, че при k=1 обектът ще е от класа на най-близкия му съсед – оранжевия.

knn класификация 3 съседа

При k=3 гледаме трите най-близки съседи и тъй като 2 от тях са от зеления клас, а един е от оранжевия, некласифицираният обект ще бъде от зеления клас.

Качество на модела

От какво зависи качеството?

  • броя съседи
  • метриката за определяне на разстоянието (евклидово, косинусно, на Минковски и др.), като при повечето метрики е необходимо мащабиране на характеристиките (напр. заплата 100000, възраст до 100)
  • тегло на съседите

Начини за проверка на качеството

  • разделяне на извадката на обучаваща (60-80%) и тестова (40-20%) и изчисляване на процент правилни отговори (най-простата метрика)
  • кръстосан контрол (cross validation) – алгоритъмът се обучава k-пъти и получените резултати се осредняват. Дава по-добри резултати, но изисква повече изчисления.

Практически пример за разпределяне на продукти в класове чрез kNN

В нашият пример ще използваме данни за продукти от онлайн магазин, като имаме следните колони:

  • uniq_id – уникалният идентификатор на продукта
  • product_name – наименованието на продукта
  • manufacturer – фирмата, която е изработила продукта
  • price – единичната цена
  • number_available_in_stock – колко броя има на склад
  • number_of_reviews – брой мнения от клиентите
  • number_of_answered_questions – брой отговорени въпроси относно продукта
  • average_review_rating – средна оценка на продукта
  • popularity – колко е популярен сред клиентите

На базата на тези данни, когато има нов запис, ще е необходимо да можем да преценим колко популярен е продуктът, като чрез алгоритъма kNN го класифицираме в някоя от трите категории за популярност – ниска, средна или висока.

Стъпка 1: Импорт на библиотеки и зареждане на данните

import warnings 
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd
import seaborn as sns
sns.set()
import matplotlib.pyplot as plt
df = pd.read_csv('./datasets/products-final.csv', sep=',')

df.head()

Резултат:

Nouniq_idproduct_namemanufacturerpricenumber_available_in_stocknumber_of_reviewsnumber_of_answered_questionsaverage_review_ratingpopularity
0eac7efa5dbd3d667f26eb3d3ab504464Hornby 2014 CatalogueHornby39.260313medium
1b17540ef7e86e461d37f3ae58b7b72acFunkyBuys® Large Christmas Holiday Express Fe...FunkyBuys74.562714high
2348f344247b0c1a935b1223072ef9d8aCLASSIC TOY TRAIN SET TRACK CARRIAGES LIGHT EN...ccf1.42320low
3e12b92dbb8eaee78b22965d2a9bbbd9fHORNBY Coach R4410A BR Hawksworth Corridor 3rdHornby26.6442820low
4e33a9adeed5f36840ccc227db4682a36Hornby 00 Gauge 0-4-0 Gildenlow Salt Co. Steam...Hornby80.137223medium

Стъпка 2: LabelEncoder

Използваме LabelEncoder, за да преобразуваме качествените данни в количествени.

from sklearn.preprocessing import LabelEncoder
labelencoder=LabelEncoder()
for column in df.columns:
    df[column] = labelencoder.fit_transform(df[column])

df.head()

Резултат:

Nouniq_idproduct_namemanufacturerpricenumber_available_in_stocknumber_of_reviewsnumber_of_answered_questionsaverage_review_ratingpopularity
0193842170543032
11435217133627040
2472465323101
31825921443928101
41856721140322132

Стъпка 3: Разделяне на данните на обучаваща и тестова извадка

Заделяме 70% от данните за обучението и 30% за тест.

from sklearn.model_selection import train_test_split
X=df.drop(['popularity'], axis=1)
Y=df['popularity']

X_train, X_test, y_train, y_test = train_test_split(X,
                                                    Y,
                                                    test_size=0.3,
                                                    random_state=17)

Стъпка 4: Обучение на модела

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=10)
%%time
knn.fit(X_train, y_train)

Стъпка 5: Проверка на качеството на модела

from sklearn.metrics import accuracy_score
knn_pred = knn.predict(X_test)

accuracy_score(y_test, knn_pred)

Резултат: 0.3333333333333333

В 33% от случаите моделът разпределя правилно продуктите в класовете.

Стъпка 6: Избор на оптимални параметри

from sklearn.model_selection import GridSearchCV, cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
knn_pipe = Pipeline([('scaler', StandardScaler()),
                     ('knn', KNeighborsClassifier(n_jobs=3))])

knn_params = {'knn__n_neighbors':range(1,10)}
knn_grid = GridSearchCV(knn_pipe, knn_params,cv=5, n_jobs=3, verbose=True)
%%time
knn_grid.fit(X_train, y_train)
knn_grid.best_params_, knn_grid.best_score_

Резултат:
({‘knn__n_neighbors’: 4}, 0.8)

accuracy_score(y_test, knn_grid.predict(X_test))

Резултат: 0.746031746031746

С оптималните параметри, в 75% от случаите моделът разпределя правилно продуктите в класовете.

Цялостния пример можете да свалите от тук.

Можете да използвате Jupyter Notebook или друг подобен инструмент, за да го изпълните.

Защо е важен този метод и в кои области е полезен?

kNN е алгоритъм, който е много лесен за разбиране и работи страхотно в практиката. Като предимство можем да кажем, че той е един от добре изучените методи и се ползва в много области (иконометрика, статистика и др.). За KNN съществуват важни теореми, съгласно които този метод е оптимален за класификация на безкрайни извадки. Може би едни от най-важните недостатъци, които има kNN, са това, че трябва да намерим оптималния брой съседи и че алгоритъмът не работи толкова добре, когато расте броят на променливите в данните. Колкото по-малко са, толкова по-точен е.

Искате да научите повече за машинното обучение?

Включете се в курса по машинно обучение и анализ на данни с python.

Научете повече

Автор: Десислава Христова