вторник, 15 февраля 2022 г.

Машинное обучение с Python в розничной торговле : введение в алгоритмы машинного обучения

Рассмотрим   три метода машинного обучения: классификация, регрессия и кластеризация, реализованные в библиотеке машинного обучения в Python в модуле scikit-learn. Для иллюстрации методов будем использовать простой набор данных, представляющий месячные продажи 45 розничных магазинов одежды. Они разделены на три группы : маленькие магазины (small), т.н. магазины у дома, средние (middle), как бы районные универмаги и крупные (big) - магазины в крупных торговых центрах.

 В таблице приведены месячные продажи по следующим категориям : куртки (jacket), джинсы (jeans), трикотаж (tricot) и аксессуары (accsess).

df = pd.DataFrame({
'shop_size':['small','small','small','small','small','small','small','small','small','small','small','small','
small','small','small','small','small','small','small','small','middle','middle','middle','
middle','middle','middle','middle','middle','middle','middle','middle','middle','middle',
'middle','middle','big','big','big','big','big','big','big','big','big','big'],    
'access': [519,497,479,464,502,547,465,505,444,498,548,486,487,439,585,578,543,515,575,
         511,708,642,696,558,653,571,638,493,662,528,505,599,601,614,563,638,588,715,
         632,655,768,499,736,678,725],
'tricot': 
[357,309,329,312,364,393,349,344,296,312,371,342,308,306,408,441,393,359,381,
           389,325,321,313,234,284,282,331,246,294,277,208,309,222,291,296,337,272,308,
           293,306,301,257,294,255,368],
'jeans': 
[145,144,131,159,143,177,141,158,141,157,151,165,146,113,123,153,135,143,176,
          152,473,451,495,405,466,452,475,334,465,396,355,423,407,476,365,609,516,596,
          567,583,664,452,639,587,615],
'jacket':
 [26,28,26,25,26,45,39,23,22,12,29,25,12,14,23,49,46,32,39,37,147,154,154,135,           153,132,162,103,131,142,103,155,104,143,138,258,192,215,189,221,211,177,182,188,258]    })


Выведем общую информацию по данным

df.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 45 entries, 0 to 44
Data columns (total 5 columns):
 #   Column     Non-Null Count  Dtype 
---  ------     --------------  ----- 
 0   shop_size  45 non-null     object
 1   access     45 non-null     int64 
 2   tricot     45 non-null     int64 
 3   jeans      45 non-null     int64 
 4   jacket     45 non-null     int64 
dtypes: int64(4), object(1)
memory usage: 1.9+ KB

Выведем пять случайно выбранных строк 

df.sample(5)

shop_sizeaccesstricotjeansjacket
26middle638331475162
40big768301664211
33middle614291476143
36big588272516192
9small49831215712

Выведем состав данных по типам магазинов

df.groupby('shop_size').count()

accesstricotjeansjacket
shop_size
big10101010
middle15151515
small20202020

Выведем описательную статистику

df.describe()

accesstricotjeansjacket
count45.00000045.00000045.00000045.00000
mean574.488889317.488889338.200000105.00000
std86.28773849.779341185.98663276.14251
min439.000000208.000000113.00000012.00000
25%502.000000293.000000151.00000028.00000
50%563.000000309.000000365.000000104.00000
75%638.000000349.000000475.000000155.00000
max768.000000441.000000664.000000258.00000

Следующим шагом является визуализация отношений между различными показателями в наших данных.



На этом графике хорошо видно, что три типа магазинов хорошо группируются в измерениях категорий товара. Таким образом эти данные хорошо походят  для иллюстрации различных алгоритмов машинного обучения. 
Наш следующий шаг —  преобразовать данные к виду, более подходящий для машинного обучения.
Мы выделим продажи по категориям товара в качестве данных. Затем мы переведем строковое обозначение типов магазинов в числовые значения где 0, 1 и 2.  Это необходимо сделать, так как  алгоритмы машинного обучения работают с числами, а не со строковыми метками.

from sklearn.preprocessing import LabelEncoder

data = df[['access','tricot','jeans','jacket']]
labels = LabelEncoder().fit_transform(df.shop_size)
label_names = ['small','middle', 'big']


Мы можем вывести диаграмму рассеяния в двух координатах и увидеть четкую структуру в данных


fig, ax = plt.subplots(figsize=(7, 5))
ax = sns.scatterplot(x="jeans", y="jacket", palette="Set2", hue="shop_size", data=df, ax=ax, s=100)
ax.set_title("Shops Cluster-Classification Demonstration", fontsize=15)
ax.set_xlabel('jeans', fontsize=15)
ax.set_ylabel('jacket', fontsize=15)



Разделим данные на обучающую и тестовую части

from sklearn.model_selection import train_test_split

d_train, d_test, l_train, l_test \
    = train_test_split(data, labels, test_size=0.4, random_state=23)

Далее сделаем стандартизацию : данные масштабируются, чтобы иметь нулевое среднее значение  и единичную дисперсию.

from sklearn.preprocessing import StandardScaler

ss = StandardScaler().fit(d_train)

d_train_ss = ss.transform(d_train)
d_test_ss = ss.transform(d_test)

Теперь, когда наши данные правильно разделены на обучающую и тестовую части, а также соответствующим образом масштабированы, мы переходим к применению алгоритмов машинного обучения с использованием  библиотеки scikit-learn. 

Классификация

В данном примере мы будем использовать классификатор на основе метода k ближайших соседей, который легко интерпретировать. Построение этой модели заключается лишь в запоминании обучающего набора. Для того, чтобы сделать прогноз для новой точки данных, алгоритм находит точку в обучающем наборе, которая находится ближе всего к новой точке. Затем он присваивает метку, принадлежащую этой точке обучающего набора, новой точке данных.

В этом примере мы используем пять ближайших соседей (но это значение можно легко изменить, чтобы увидеть, как меняется производительность классификации). Как показано в этом примере кода, стандартный процесс классификации в scikit-learn заключается в том, чтобы сначала подобрать модель к обучающим данным, а затем применить эту модель для прогнозирования значений для тестовых данных. Также мы можем вычислить показатели точности для нашего обученного алгоритма, используя метод оценки для сравнения предсказанных и известных меток для данных тестирования.


from sklearn.neighbors import KNeighborsClassifier

Сначала мы построим нашу модель

knn = KNeighborsClassifier(n_neighbors=5)

Теперь обучаем нашу модель на обучающих данных

knn.fit(d_train_ss, l_train)

Получаем прогноз на тестовых данных

prediction = knn.predict(d_test_ss)

Выводим полученную точность классификации на тестовом наборе

score = 100.0 * knn.score(d_test_ss, l_test)
print(f"KNN ({nbrs} neighbors) prediction accuracy = {score:5.1f}%")

KNN (5 neighbors) prediction accuracy =  94.4%


Регрессия

Второе приложение машинного обучения, которое мы продемонстрируем —
это регрессия. 
Чтобы продемонстрировать регрессию, будем использовать решающие деревья. 
Применим  так сказать в учебных целях довольно неожиданное решение. 
Для начала выделим из наших данных независимые переменные, пусть это будет 
количество продаваемых аксессуаров, джинсов и трикотажа. А зависимой переменной 
сделаем  количество продаваемых курток. Разделим их на обучающую и 
тестовую части.

Независимые переменные

ind_data = data[['access','tricot','jeans']]

Зависимая переменная

dep_data = data['jacket']
Доля для тестовой выборки

frac = 0.4

Разделяем данные
d_train, d_test, r_train, r_test \ = train_test_split(ind_data, dep_data, test_size=frac, random_state=23)

Импортируем метод решающих деревьев

from sklearn.tree import DecisionTreeRegressor

Строим дерево-регрессор

dtr = DecisionTreeRegressor()


Обучаем на обучающей части

dtr.fit(d_train, r_train)

Точность на тестовых данных

score = 100.0 * dtr.score(d_test, r_test)
print(f'DT regression accuracy = {score:5.1f}%')

DT regression accuracy =  90.9%


Кластеризация

Цель кластеризации - выявить в наборе данных такие группы, для которых наблюдения пределах одной

группы сходны между собой, но отличаются от наблюдений в других группах.
В случае кластеризации методом k-средних мы указываем требуемое количество

кластеров, k, и алгоритм будет приписывать каждое наблюдение только к одному

из этих k кластеров. Алгоритм оптимизирует группы путем минимизации

внутрикластерной вариации (также известной как инерция), чтобы сумма

внутрикластерных вариаций по всем k кластерам была наименьшей.



Мы будем использовать kmeans от Scikit-Learn

Мы создаем экземпляр класса KMeans и задаем количество выделяемых кластеров.
Затем мы вызываем метод fit и передаем ему в качестве аргумента данные:

from sklearn.cluster import KMeans


Строим модель делением на три кластера

k_means = KMeans(n_clusters=3, random_state=23)

k_means.fit(data)

Во время работы алгоритма каждой точке обучающих данных присваивается метка
кластера. Можно найти эти метки в атрибуте

print(k_means.cluster_centers_)

[[5.006      3.428      1.462      0.246     ]
 [6.85       3.07368421 5.74210526 2.07105263]
 [5.9016129  2.7483871  4.39354839 1.43387097]]



Выведем диаграмму с кластерами

from matplotlib import cm

x = data['jeans']
y = data['jacket']

xcc = k_means.cluster_centers_[:,2]
ycc = k_means.cluster_centers_[:,3]


fig, ax = plt.subplots(figsize=(8, 8))

for idx in np.unique(labels):
    i = int(idx)
    ax.scatter(x[labels == i], y[labels == i], label=f'{label_names[i]}',
               s=100, alpha = .5, cmap=cm.coolwarm) 


Выводим центры кластеров

ax.scatter(xcc, ycc, marker='*', label='Cluster Centers', 
           s=500, alpha=0.75, cmap=cm.coolwarm)

ax.set_xlabel('jeans', fontsize=16)
ax.set_ylabel('jacket', fontsize=16)
ax.legend(loc = 7, labelspacing=2)
ax.set_title("Shops Cluster Demonstration", fontsize=18)
sns.despine(offset=0, trim=True)




На этом примере закончим поверхностное знакомство с методами машинного обучения и возможностями их применения для прикладных задач в области розничной торговли,
 в данном случае для анализа небольшой розничной сети магазинов одежды. 
В следующих  материалах каждый из этих методов будет рассмотрен подробнее.




Комментариев нет:

Отправить комментарий