Результат эксперимента по созданию интеллектуального решения бизнес-аналитики на базе бесплатных сервисов Google.
Многие из нас привыкли думать, что бизнес-аналитика - это то, что используют крупные компании и что создается с помощью инструментов, которые дороги и часто трудны в освоении (хотя есть приятные исключения, такие как Метабаза и Суперсет). В своей статье я хочу показать, что практически каждый может использовать возможности Business Intelligence и даже добавить к нему прогнозную аналитику с помощью общедоступных и бесплатных онлайн-инструментов, таких как Google Colab и Google Data Studio. Развертывание базы данных не требуется. Все данные для анализа и визуализации мы будем хранить в Google Таблицах.
Мы реализуем модель машинного обучения в Google Colab и на основе истории продаж продуктов сможем прогнозировать будущие продажи на несколько месяцев и визуализировать наш прогноз в Google Data Studio.
Мы будем использовать набор данных с информацией о списке продуктов и историей продаж за 12 месяцев для каждого продукта.
Модель будет анализировать историю продаж и изменения характеристик продукта за каждый месяц, так что любое изменение будет динамически влиять на прогнозы модели. Это позволит нам быстро оценить последствия тех или иных решений и принять оптимальную стратегию развития.
Загрузить данные
Мы считаем, что все операции делаем в Google Colab. Прежде всего мы воспользуемся модулем kaggle для загрузки необходимого набора данных. Более подробно о модуле и о том, как получить Kaggle API Token, вы можете прочитать по этой ссылке.
Описание набора данных: https://www.kaggle.com/c/online-sales/data.
!pip install kaggle
Поскольку мы используем Google Colab, мы подключимся к Google Drive, чтобы скопировать учетные данные Kaggle.
from google.colab import drive drive.mount(‘/content/drive/’)
Установите рабочий каталог с сохраненными учетными данными (в нашем случае каталог называется «Colab Notebooks»).
import os os.chdir(“/content/drive/My Drive/Colab Notebooks”)
Скопируйте учетные данные для Kaggle API.
import os os.chdir(“/content/drive/My Drive/Colab Notebooks”)
Загрузите набор данных.
!kaggle competitions download -c online-sales
Загрузите набор данных в память и замените нулевые значения нулями.
import pandas as pd import numpy as np from matplotlib import pyplot as plt df = pd.read_csv(“TrainingDataset.csv”) df = df.replace(np.nan, 0, regex=True)
Теперь мы можем предварительно просмотреть наш набор данных.
Мы разделим наш набор данных на обучающую часть (на которой мы будем обучать нашу модель) и тестовую часть (на которой мы будем проверять правильность нашей модели).
from sklearn.model_selection import train_test_split df_train, df_test = train_test_split(df, test_size=0.2) print(df_train.shape) print(df_test.shape)
Исследовательский анализ данных
Давайте визуализируем наши данные. Покажем динамику изменения цен на 10 случайных товаров.
import random indexes = random.sample(range(len(df)), 10) df_plot = pd.DataFrame() for i in indexes: df_plot[“product_”+str(i)] = df.iloc[i, 0:12] df_plot.plot();
Как видим, в большинстве случаев продажи в течение года снижаются.
Подготовить данные
Нам нужно специальным образом подготовить наши данные для загрузки в нашу модель. Мы построим модель, которая прогнозирует результат в будущем месяце на основе предыдущих значений. Для каждого месяца модель будет анализировать характеристики продукта и информацию об итогах предыдущего месяца.
Во-первых, мы разделим характеристики продукта и информацию о результатах за месяц.
y_train_real = df_train.iloc[:, 0:12].values print(y_train_real.shape) y_test_real = df_test.iloc[:, 0:12].values print(y_test_real.shape) x_train_real = df_train.iloc[:, 12:].values x_test_real = df_test.iloc[:, 12:].values print(x_train_real.shape) print(x_test_real.shape)
Масштабируйте значения в одном диапазоне для более точных прогнозов.
from sklearn.preprocessing import MinMaxScaler #scale datasets x_scaler = MinMaxScaler() x_scaler = x_scaler.fit(x_train_real) x_train = x_scaler.transform(x_train_real) x_test = x_scaler.transform(x_test_real) y_scaler = MinMaxScaler() y_scaler = y_scaler.fit(y_train_real) y_train = y_scaler.transform(y_train_real) y_test = y_scaler.transform(y_test_real)
Теперь перейдем к самому важному этапу этого процесса: преобразованию истории цен в многомерные временные ряды. Для каждого продукта мы создадим TimeSeries с 1–12 временными шагами с информацией о характеристиках продукта и результатах предыдущего временного шага. Нам неизвестен предыдущий результат для первого временного шага, поэтому мы просто возьмем ноль.
Здесь мы создаем списки для обучающих и тестовых данных, каждый список будет содержать 12 трехмерных массивов numpy. Второе измерение для каждого массива будет представлять временные шаги и постепенно увеличивается на 1.
x_train_series = [] x_test_series = [] for k in range(len(y_train[0])): x_train_series.append(np.zeros((x_train.shape[0], k+1, x_train.shape[1]+1))) for k in range(len(y_test[0])): x_test_series.append(np.zeros((x_test.shape[0], k+1, x_test.shape[1]+1)))
Добавьте к каждому временному шагу информацию о характеристиках продукта и результат предыдущего временного шага. Теперь мы используем одни и те же функции продукта для каждого временного шага, но модель позволяет отслеживать изменения функций на каждом временном шаге, чтобы делать более точные прогнозы.
for k in range(len(y_train[0])): for i in range(len(x_train)): for j in range(k + 1): shifted_index = j - 1 if shifted_index < 0: x_train_series[k][i, j] = np.append(x_train[i], 0) else: x_train_series[k][i, j] = np.append(x_train[i], y_train[i, shifted_index])
Такое же преобразование временных шагов для тестовых данных.
for k in range(len(y_test[0])): for i in range(len(x_test)): for j in range(k + 1): shifted_index = j - 1 if shifted_index < 0: x_test_series[k][i, j] = np.append(x_test[i], 0) else: x_test_series[k][i, j] = np.append(x_test[i], y_test[i, shifted_index])
Составьте 12 списков с информацией о результатах для TimeSerie, для каждого продукта.
y_train_series = [] y_test_series = [] for k in range(len(y_train[0])): y_train_series.append(np.zeros((len(y_train), 1))) y_test_series.append(np.zeros((len(y_test), 1))) for k in range(len(y_train[0])): y_train_series[k] = y_train[:, k].reshape(-1, 1) y_test_series[k] = y_test[:, k].reshape(-1, 1)
Построение нейронной сети LSTM
Мы будем использовать сеть с долговременной краткосрочной памятью (LSTM) Рекуррентной нейронной сети (RNN). Вы можете прочитать больше об этих типах NN здесь:
Http://colah.github.io/posts/2015-08-Understanding-LSTMs/
Мы используем фреймворк Keras для глубокого обучения. Наша модель состоит только из одного слоя LSTM с 256 единицами, одного плотного слоя с 128 единицами и плотно связанного выходного слоя с одним нейроном. Мы также добавили один слой Dropout, чтобы избежать переобучения. Модель остается простой и быстрой, но при этом позволяет делать полезные прогнозы.
from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM from keras.layers import Dropout model = Sequential() model.add(LSTM(256, input_shape=(None, x_train.shape[1]+1))) model.add(Dropout(0.5)) model.add(Dense(128, activation = "relu")) model.add(Dense(1)) model.summary()
model.compile(loss='mse', optimizer='rmsprop')
Обучите нашу модель:
for i in range(len(x_train_series)): print(i) model.fit(x_train_series[i], y_train_series[i], epochs=10, validation_split=0.2)
Оцените модель для прогнозирования результата через несколько месяцев.
for i in range(len(x_test_series)): accr = model.evaluate(x_test_series[i], y_test_series[i]) print("Predicting outcome after {} months. MSE:".format(i), accr)
Функция прогнозирования результатов
Мы будем использовать нашу модель для создания рекурсивной функции, которая будет получать информацию о характеристиках продукта и истории результатов в течение нескольких месяцев. В результате эта функция будет предсказывать будущий результат на столько месяцев, сколько вы пожелаете.
def predictor(features, history, future): ''' features: list of product features history: list with outcome per month future: int, number of months to predict outcome ''' if future == 0: return history p_serie = np.zeros((1, len(history), len(features)+1)) for j in range(len(history)): shifted_index = j - 1 if shifted_index < 0: p_serie[0, j] = np.append(features, 0) else: p_serie[0, j] = np.append(features, history[shifted_index]) prediction = model.predict(p_serie) history.append(prediction[0][0]) future -= 1 return predictor(features, history, future)
Мы протестируем нашу функцию на случайном продукте n. Создадим два списка. Первый - с историей результатов за первые m месяцев, второй - с характеристиками продукта.
import random n = random.choice(range(len(x_test)-1)) m = 6 future = 6 features = x_test[n].tolist() history = y_test[n, 0:m].tolist()
Постройте результаты прогноза по сравнению с реальными данными
prediction = predictor(features, history, future) plt.plot(y_scaler.inverse_transform([prediction])[0]) plt.plot(y_scaler.inverse_transform([y_test[n, :m+future]])[0]) plt.title('Predicted and real outcome') plt.legend(['predicted', 'real'], loc='upper left') axes = plt.gca() plt.show()
Как видим, это достаточно точно показало общую тенденцию изменения продаж. Неплохой результат для сравнительно простой модели.
Отображение прогнозов в Google Data Studio
Теперь, когда у нас есть прогнозируемые данные, мы можем отобразить их в Google Data Studio, решении Google Business Intelligence. Одним из преимуществ этого инструмента является то, что его можно бесплатно использовать для создания настраиваемых отчетов и информационных панелей.
Google Data Studio может подключать несколько источников данных для отчетов. Google Таблицы как источник данных подходят для наших целей. Мы сохраним наши прогнозы в виде таблицы Google, и Google Data Studio отобразит данные из нее на панели инструментов. Таким образом, мы можем легко интегрировать Google Colaboratory и Data Studio.
Я не буду подробно объяснять функциональность Google Data Studio. Вы можете узнать об этом в официальной документации https://developers.google.com/datastudio/.
Мы возьмем три случайных продукта, сохраним прогнозы и историю результатов для каждого. Чтобы сохранить наши данные в Google Spreadsheet, мы будем использовать библиотеку gspread.
Нам понадобится клиентский ключ для записи в Google Spreadsheet. Как получить ключ описано здесь https://gspread.readthedocs.io/en/latest/oauth2.html.
!pip install — upgrade oauth2client gspread
Подключитесь к Google Таблицам.
import gspread from oauth2client.service_account import ServiceAccountCredentials scope = ['https://spreadsheets.google.com/feeds', 'https://www.googleapis.com/auth/drive'] credentials = ServiceAccountCredentials.from_json_keyfile_name('spreadkey.json', scope) gc = gspread.authorize(credentials)
Составьте списки с реальной и прогнозируемой историей результатов для трех случайных продуктов. В целях тестирования мы используем данные из тестового набора данных, но в реальном сценарии вы можете вставить любые изменения функций продукта в Google Таблицы, загрузить данные из Google Таблиц и сделать прогноз.
real_data = [] predicted_data = [] for i in range(3): n = random.choice(range(len(x_test)-1)) m = 6 future = 6 features = x_test[n].tolist() history = y_test[n, 0:m].tolist() prediction = predictor(features, history, future) predicted_data.append(y_scaler.inverse_transform([prediction])[0]) real_data.append(y_scaler.inverse_transform([y_test[n, :m+future]])[0])
Откройте Google Sheet для сохранения реальных и прогнозируемых данных. У нас есть два листа: «реальный» для реальных данных, «прогнозируемый» для прогнозируемых данных.
ws = gc.open('TrainingDataset2') ws_predicted = ws.worksheet("predicted") ws_real = ws.worksheet("real")
Запишите наши реальные и прогнозируемые данные в Google Таблицы. Мы будем писать, начиная со второй строки, оставляя первую строку для имен столбцов (Product1, Product2, Product3).
for j in range(len(real_data)): for i in range(len(real_data[0])): ws_predicted.update_cell(i+2, j+1, float(predicted_data[j][i])) ws_real.update_cell(i+2, j+1, float(real_data[j][i])) for i in range(len(real_data[0])): # add index column ws_predicted.update_cell(i+2, len(real_data)+1, i) ws_real.update_cell(i+2, len(real_data)+1, i)
Просмотрите наши данные в Google Таблицах
ws_real.get_all_records()[6:11]
Поскольку у нас есть Google Таблицы, заполненные реальным и прогнозируемым результатом, теперь мы можем подключить Google Таблицы в качестве источника данных в Google Data Studio.
В Google Data Studio создайте новую панель управления и создайте для нее источник данных. Вы найдете Google Таблицы в списке источников. Добавьте свою таблицу Google в качестве источника данных.
На основе данных из «прогнозируемых» и «реальных» рабочих листов мы можем построить диаграммы, показывающие изменение результатов.
Вот и все! Теперь у вас есть панель управления на базе искусственного интеллекта, на которой отображаются прогнозы будущих результатов!
Вывод
Основная идея этой статьи заключается в том, что бизнес-аналитика даже с некоторыми функциями искусственного интеллекта более доступна, чем мы думаем. Вы можете создавать расширенную аналитику, встраивать предложенные графики в аналитические отчеты и иметь представление как о текущей ситуации, так и о ближайшем будущем. Все изменения, которые вы хотите проверить, можно быстро вставить в Google Таблицы, прогнозируемые последствия будут рассчитаны в Google Colab и показаны в Google Data Studio.
По этой ссылке вы можете найти Блокнот Google Colab со всем описанным кодом.