Машинное обучение, которое ускорит сайт

Машинное обучение, доступное каждому! В статье приведена реальная проблема некоторых сайтов и ее решение с использованием machine learning.

Я часто задумываюсь о производительности интернет-ресурсов: как получать сладкие 60FPS на медленных телефонах или прогружать страницы, автономно кэшируя все, что можно? Разумеется, это лишь малая часть пирога для каждого пользователя, ведь современные сайты позволяют совершать больше действий, используя полный функционал.

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

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

Суть проблемы

В качестве сайта-примера я взял тот, где пользователь может продать свой мусор, из которого другой человек выудит и купит сокровище.

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

Этот первый шаг – выбор категории – сбивает с толку. Во-первых, есть 674 варианта, и я действительно не знаю, к какому принадлежит моя байдарка (Стив Круг высказался об этом как нельзя лучше: «Не заставляйте меня думать»).

Во-вторых, даже когда становится ясно, к какой категории / подкатегории / под-подкатегории относится моя вещь, процесс все равно занимает около 12 секунд.

А если бы я сказал вам, что могу сократить время загрузки страницы на 12 секунд? Вот почему бы просто не сэкономить это время на что-нибудь более продуктивное?

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

Машинное обучение или почему вы должны перестать убегать и вернуться сюда

Когда это началось, я абсолютно ничего не знал о machine learning, кроме того факта, что это помогало создавать видеоигры. Поэтому я решил узнать все, что нужно было знать. Следующие шаги заняли менее часа:

  1. Гуглил «Машинное обучение»
  2. Много кликал
  3. Ознакомился с Amazon Machine Learning
  4. Понял, что мне ничего не нужно знать об этом
  5. Расслабился

О процессе в двух словах

Amazon создал документацию по ML. Если вы заинтересовались, выделите 5 часов или около того на ее прочтение: я не буду пытаться обобщить такое количество информации здесь.

После прочтения документации я сформировал план, и выглядел он следующим образом:

  • Оформить данные в CSV-файл. Каждая строка должна быть отдельным товаром (например, моей байдаркой), а столбцы – заголовком, описанием, ценой и категорией.
  • Загрузите это на AWS S3.
  • Запустите машину с этими данными (это делается с помощью UI-мастера). Маленький облачный робот должен знать, как определить категорию на основе названия, описания и цены.
  • Добавьте к интерфейсу код, который берет данные, введенные пользователем, отправляет это в конечную точку «предсказания» (это было автоматически создано Amazon) и выводит прогнозируемую категорию на экран.

Макет сайта

Я собрал великолепную форму, которая имитирует ключевые аспекты этого процесса. Давайте попробуем продать холодильник:

Или аквариум:

Маленький облачный робот знает, что такое аквариум! И это здорово, правда?

Если вам интересно, как была создана форма, я использовал React, Redux, jQuery, MobX, RxJS, Bluebird, Bootstrap, Sass, Compass, NodeJS, Express, Lodash и WebPack. Готовая вещь «весит» чуть больше 1 Мб.

Я хотел около 10 000 предметов в нескольких десятках категорий. Я нашел локальный торговый сайт, посмотрел URL-адреса и DOM, а затем написал небольшой скрапер, который выводил результаты в CSV. Это заняло около четырех часов – половину от времени, затраченного на то, чтобы все это работало.

Когда у меня уже был CSV, я загрузил его на AWS S3 и так же задействовал мастер, чтобы настроить и обучить модель. Само машинное обучение составило около трех минут. Интерфейс имеет область отображения вносимых изменений, поэтому я всегда могу проверить, что именно получу, если передам определенные параметры.

Так, все работает. Отлично!

Бэкенд

Общий принцип довольно прост: я передаю API идентификатор модели и некоторые данные, после чего получаю прогноз.

const AWS = require('aws-sdk');

const machineLearning = new AWS.MachineLearning();

const params = {
  MLModelId: 'some-model-id',
  PredictEndpoint: 'some-endpoint',
  Record: {},
};

machineLearning.predict(params, (err, prediction) =>; {
  // we have a prediction!
});

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

Record является объектом JSON, где свойства – это то, чему я обучил модель (название, описание, цена). Я не хочу быть тем, кто предоставляет не совсем полный код, так что вот весь мой файл server.js:

const express = require('express');
const bodyParser = require('body-parser');
const AWS = require('aws-sdk');

const app = express();
app.use(express.static('public'));
app.use(bodyParser.json());

AWS.config.loadFromPath('./private/aws-credentials.json');

const machineLearning = new AWS.MachineLearning();

app.post('/predict', (req, res) => {
  const params = {
    MLModelId: 'my-model-id',
    PredictEndpoint: 'https://realtime.machinelearning.us-east-1.amazonaws.com',
    Record: req.body,
  };

  machineLearning.predict(params, (err, data) =>; {
    if (err) {
      console.log(err);
    } else {
      res.json({ category: data.Prediction.predictedLabel });
    }
  });
});

app.listen(8080);

И содержимое aws-credentials.json:

{
  "accessKeyId": "my-access-key-id",
  "secretAccessKey": "shhh-secret-squirrel",
  "region": "us-east-1"
}

Хорошо, с бэкендом закончили.

Фронтенд

Код довольно прост. Он делает это:

  • Прослушивает событие размытия в соответствующих полях.
  • Получает значения из элементов формы.
  • Отправляет их в конечную точку /predict, созданную в приведенном выше коде.
  • Помещает полученное предсказание в поле категории и показывает раздел.
(function() {
  const titleEl = document.getElementById('title-input');
  const descriptionEl = document.getElementById('desc-input');
  const priceEl = document.getElementById('price-input');
  const catSuggestionsEl = document.getElementById('cat-suggestions');
  const catSuggestionEl = document.getElementById('suggested-category');

  function predictCategory() {
    const fetchOptions = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        title: titleEl.value,
        description: descriptionEl.value,
        price: priceEl.value,
      })
    };

    fetch('/predict', fetchOptions)
      .then(response => response.json())
      .then(prediction => {
        catSuggestionEl.textContent = prediction.category;
        catSuggestionsEl.style.display = 'block';
      });
  }

  document.querySelectorAll('.user-input').forEach(el => {
    el.addEventListener('blur', predictCategory);
  });
})();

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

Shut up and take my money!

Но все это не бесплатно.

Модель, которую я использовал для вышеперечисленного (она тренировалась на 10000 строках / 4 столбцах), выльется в 6,3 Мб. Хотя у меня есть конечная точка, ожидающая получения запросов, я понесу плату за память на 6,3 Мб. Стоимость составляет $0.0001/час. Или около восьми баксов в год. Я трачу больше на рукавицы.

За каждый прогноз также взимается плата в размере $0,0001. Итак, вы знаете, не ходите предсказывать вещи волей-неволей.

Конечно, можно использовать не только Amazon, но я протестировал еще 2 варианта, и они мне не так сильно понравились. У Google есть TensorFlow, но они потеряли меня уже после первой строки в начальном руководстве. Microsoft также предлагает машинное обучение, но я все еще злюсь на них за IE6.

Но если говорить начистоту, Microsoft Azure Machine Learning значительно превосходит Amazon. Итерация намного быстрее, потому что вы можете добавлять/удалять столбцы, не загружая файлы повторно. Мое обучение, которое занимает 11 минут на Amazon, занимает 23 секунды на Azure. Кроме всего прочего, приложение очень хорошо скроено с точки зрения интерфейса.

Подведем итоги

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

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

admin
14 июля 2017

Пишем свою нейросеть: пошаговое руководство

Отличный гайд про нейросеть от теории к практике. Вы узнаете из каких элеме...