{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Финальное задание" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Предметная область: Игра Dota 2\n", "\n", "[Dota 2](https://ru.wikipedia.org/wiki/Dota_2) — многопользовательская компьютерная игра жанра [MOBA](https://ru.wikipedia.org/wiki/MOBA). Игроки играют между собой матчи. В каждом матче участвует две команды, 5 человек в каждой. Одна команда играет за светлую сторону (The Radiant), другая — за тёмную (The Dire). Цель каждой команды — уничтожить главное здание базы противника (трон).\n", "\n", "Существуют [разные режимы игры](http://dota2.gamepedia.com/Game_modes/ru), мы будем рассматривать режим [Captain's Mode](http://dota2.gamepedia.com/Game_modes/ru#Captain.27s_Mode), в формате которого происходит большая часть киберспортивных мероприятий по Dota 2.\n", "\n", "### Как проходит матч\n", "\n", "#### 1. Игроки выбирают героев\n", "\n", "Всего в игре чуть более 100 различных героев (персонажей). В начале игры, команды в определенном порядке выбирают героев себе и запрещают выбирать определенных героев противнику (баны). Каждый игрок будет управлять одним героем, в рамках одного матча не может быть несколько одинаковых героев. Герои различаются между собой своими характеристиками и способностями. От комбинации выбранных героев во многом зависит успех команды.\n", "\n", "![](http://imgur.com/XFr4HYE.jpg)\n", "\n", "#### 2. Основная часть\n", "\n", "Игроки могут получать золото и опыт за убийство чужих героев или прочих юнитов. Накопленный опыт влияет на уровень героя, который в свою очередь позволяет улучшать способности. За накопленное золото игроки покупают предметы, которые улучшают характеристики героев или дают им новые способности.\n", "\n", "После смерти герой отправляется в \"таверну\" и возрождается только по прошествии некоторого времени, таким образом команда на некоторое время теряет игрока, однако игрок может досрочно выкупить героя из таверны за определенную сумму золота.\n", "\n", "В течение игры команды развивают своих героев, обороняют свою часть поля и нападают на вражескую.\n", "\n", "![](http://imgur.com/5b0SlQb.jpg)\n", "\n", "#### 3. Конец игры\n", "\n", "Игра заканчивается, когда одна из команд разрушет определенное число \"башен\" противника и уничтожает трон.\n", "\n", "![](http://imgur.com/Du79Kzf.jpg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Задача: предсказание победы по данным о первых 5 минутах игры\n", "\n", "По первым 5 минутам игры предсказать, какая из команд победит: Radiant или Dire?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Набор данных\n", "\n", "Набор данных с матчами записан в файле `matches.jsonlines.bz2`.\n", "В каталоге `dictionaries` приведены расшифровки идентификаторов, которые присутствуют в записях матчей." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Чтение информации о матчах\n", "\n", "Информация о матчах записана в сжатом текстовом файле `matches.jsonlines.bz2`, каждая строчка которого содержит объект в формате [JSON](https://ru.wikipedia.org/wiki/JSON). Запись в формате JSON преобразуется в python-объект при помощи стандартного модуля `json`. Пример чтения матчей:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import json\n", "import bz2\n", "\n", "with bz2.BZ2File('./matches.jsonlines.bz2') as matches_file:\n", " for line in matches_file:\n", " match = json.loads(line)\n", " \n", " # Обработка матча\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Описание полей в записи матча\n", "\n", "```python\n", "{\n", " \"match_id\": 247, # идентификатор матча\n", " \"start_time\": 1430514316, # дата/время начала матча, unixtime\n", " \"lobby_type\": 0, # тип комнаты, в которой собираются игроки \n", " # (расшифровка в dictionaries/lobbies.csv)\n", " \n", " # стадия выбора героев\n", " \"picks_bans\": [\n", " {\n", " \"order\": 0, # порядковый номер действия\n", " \"is_pick\": false, # true если команда выбирает героя, false — если банит\n", " \"team\": 1, # команда, совершающая действие (0 — Radiant, 1 — Dire)\n", " \"hero_id\": 95 # герой, связанный с действием \n", " # (расшифровка в dictionaries/heroes.csv)\n", " }, \n", " ...\n", " ],\n", "\n", " # информация про каждого игрока, список ровно из 10 элементов\n", " # игроки с индексами от 0 до 4 — из команды Radiant, от 5 до 9 — Dire\n", " \"players\": [ \n", " { \n", " \n", " # герой игрока (расшифровка в dictionaries/heroes.csv)\n", " \"hero_id\": 67, \n", "\n", " # временные ряды (отсчеты указаны в поле \"times\")\n", " \"xp_t\": [0, 13, 115, 177, 335, ...], # опыт\n", " \"gold_t\": [0, 99, 243, 343, 499, ...], # золото + стоимость всех купленных вещей (net worth)\n", " \"lh_t\": [0, 0, 2, 2, 2, ...], # количество убитых юнитов (не героев) противника\n", "\n", " # список событий: улучшение способностей героя\n", " \"ability_upgrades\": [\n", " {\n", " \"time\": 51, # игровое время\n", " \"level\": 1, # уровень игрока, на котором произошло улучшение\n", " \"ability\": 5334 # способность, которая была улучшена \n", " # (расшифровка в dictionaries/abilities.csv)\n", " }, \n", " ...\n", " ],\n", "\n", " # список событий: убийства\n", " \"kills_log\": [\n", " {\n", " \"time\": 831, # игровое время\n", " \"player\": 7, # индекс игрока, чей герой был убит \n", " # (не заполнено, если был убит не герой)\n", " \"unit\": \"npc_dota_hero_viper\" # тип убитого юнита\n", " }, \n", " ...\n", " ],\n", "\n", " # список событий: покупка предметов\n", " \"purchase_log\": [\n", " {\n", " \"time\": -73, # игровое время\n", " # точка отсчета игрового времени (ноль) начинается через\n", " # несколько минут после фактического начала матча, поэтому\n", " # время некоторых событий может быть отрицательным\n", " \"item_id\": 44 # купленный предмер (расшифровка в dictionaries/items.csv)\n", " }, \n", " ...\n", " ]\n", "\n", " # список событий: выкуп героя из таверны\n", " \"buyback_log\": [\n", " {\"time\": 2507},\n", " ...\n", " ],\n", "\n", " # список событий: установка героем \"наблюдателей\", позволяющих команде \n", " # следить за чатью игрового поля на некотором расстоянии от точки установки\n", " \"obs_log\": [\n", " {\n", " \"time\": 1711, # игровое время установки\n", " \"xy\": [111, 130] # координаты игрового поля\n", " }, \n", " ...\n", " ],\n", " \"sen_log\": [], # аналогично полю obs_log, другой тип \"наблюдателя\"\n", "\n", " },\n", " ...\n", " ],\n", " \n", " # отсчеты игрового времени, в которые вычисляются значения временных рядов\n", " \"times\": [0, 60, 120, 180, ...],\n", "\n", " # ключевые события игры\n", " \"objectives\": [\n", " {\n", " \"time\": 198, # время события\n", " \"type\": \"firstblood\", # тип события\n", " \"player1\": 6, # параметры события, могут содержать\n", " \"player2\": 1 # индексы игроков (player), \n", " # номер команды (team, 0 — Radiant, 1 — Dire)\n", " }, \n", " {\n", " \"time\": 765, \n", " \"type\": \"tower_kill\", \n", " \"player\": 7, \n", " \"team\": 1\n", " }, \n", " ...\n", " ]\n", " \n", " # итог матча (отсутствует в тестовых матчах)\n", " \"finish\": {\n", " \"duration\": 2980, # длительность в секундах\n", " \"radiant_win\": false, # true, если победила команда Radiant\n", " \"tower_status_radiant\": 0, # состояние башен у команд к концу игры\n", " \"tower_status_dire\": 1972, # (см. описание битовой маски)\n", " \"barracks_status_dire\": 63, # состояние бараков у команд к концу игры\n", " \"barracks_status_radiant\": 0 # (см. описание битовой маски)\n", " }\n", "}\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Описание полей состояния башен и бараков\n", "\n", "Состояние башен к концу игры задается целым числом, закодировано в битах:\n", "\n", "```\n", "┌─┬─┬─┬─┬─────────────────────── Not used.\n", "│ │ │ │ │ ┌───────────────────── Ancient Bottom\n", "│ │ │ │ │ │ ┌─────────────────── Ancient Top\n", "│ │ │ │ │ │ │ ┌───────────────── Bottom Tier 3\n", "│ │ │ │ │ │ │ │ ┌─────────────── Bottom Tier 2\n", "│ │ │ │ │ │ │ │ │ ┌───────────── Bottom Tier 1\n", "│ │ │ │ │ │ │ │ │ │ ┌─────────── Middle Tier 3\n", "│ │ │ │ │ │ │ │ │ │ │ ┌───────── Middle Tier 2\n", "│ │ │ │ │ │ │ │ │ │ │ │ ┌─────── Middle Tier 1\n", "│ │ │ │ │ │ │ │ │ │ │ │ │ ┌───── Top Tier 3\n", "│ │ │ │ │ │ │ │ │ │ │ │ │ │ ┌─── Top Tier 2\n", "│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┌─ Top Tier 1\n", "│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │\n", "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n", "```\n", "\n", "Состояние бараков к концу игры закодировано в битах целого числа:\n", "\n", "```\n", "┌─┬───────────── Not used.\n", "│ │ ┌─────────── Bottom Ranged\n", "│ │ │ ┌───────── Bottom Melee\n", "│ │ │ │ ┌─────── Middle Ranged\n", "│ │ │ │ │ ┌───── Middle Melee\n", "│ │ │ │ │ │ ┌─── Top Ranged\n", "│ │ │ │ │ │ │ ┌─ Top Melee\n", "│ │ │ │ │ │ │ │\n", "0 0 0 0 0 0 0 0\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Извлечение признаков\n", "\n", "Скрипт extract_features.py производит извлечение признаков из известной информации о матче за первые 5 игровых минут, составляет из них таблицу. Таблица поможет вам быстрее сформировать матрицу объект-признак, вектор ответов и начать применять методы машинного обучения для решения поставленной задачи.\n", "\n", "Признаки, представленные в таблице `features.csv`, по мнению экспертов в предметной области являются наиболее важными для решения задачи предсказания победы команды. Тем не менее, не обязательно использовать эти признаки в исходном виде для применения методов машинного обучения — вы можете сделать новые признаки из имеющихся. Более того, признаки в файле `features.csv` содержат не всю информацию, известную про матч за первые 5 игровых минут. Вы можете использовать скрипт `extract_features.py` как пример и добавлять свои признаки для улучшения качества предсказания." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Пример чтения файла с признаками" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", " | start_time | \n", "lobby_type | \n", "r1_hero | \n", "r1_level | \n", "r1_xp | \n", "r1_gold | \n", "r1_lh | \n", "r1_kills | \n", "r1_deaths | \n", "r1_items | \n", "... | \n", "dire_boots_count | \n", "dire_ward_observer_count | \n", "dire_ward_sentry_count | \n", "dire_first_ward_time | \n", "duration | \n", "radiant_win | \n", "tower_status_radiant | \n", "tower_status_dire | \n", "barracks_status_radiant | \n", "barracks_status_dire | \n", "
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
match_id | \n", "\n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " |
0 | \n", "1430198770 | \n", "7 | \n", "11 | \n", "5 | \n", "2098 | \n", "1489 | \n", "20 | \n", "0 | \n", "0 | \n", "7 | \n", "... | \n", "4 | \n", "2 | \n", "2 | \n", "-52 | \n", "2874 | \n", "1 | \n", "1796 | \n", "0 | \n", "51 | \n", "0 | \n", "
1 | \n", "1430220345 | \n", "0 | \n", "42 | \n", "4 | \n", "1188 | \n", "1033 | \n", "9 | \n", "0 | \n", "1 | \n", "12 | \n", "... | \n", "4 | \n", "3 | \n", "1 | \n", "-5 | \n", "2463 | \n", "1 | \n", "1974 | \n", "0 | \n", "63 | \n", "1 | \n", "
2 | \n", "1430227081 | \n", "7 | \n", "33 | \n", "4 | \n", "1319 | \n", "1270 | \n", "22 | \n", "0 | \n", "0 | \n", "12 | \n", "... | \n", "4 | \n", "3 | \n", "1 | \n", "13 | \n", "2130 | \n", "0 | \n", "0 | \n", "1830 | \n", "0 | \n", "63 | \n", "
3 | \n", "1430263531 | \n", "1 | \n", "29 | \n", "4 | \n", "1779 | \n", "1056 | \n", "14 | \n", "0 | \n", "0 | \n", "5 | \n", "... | \n", "4 | \n", "2 | \n", "0 | \n", "27 | \n", "1459 | \n", "0 | \n", "1920 | \n", "2047 | \n", "50 | \n", "63 | \n", "
4 | \n", "1430282290 | \n", "7 | \n", "13 | \n", "4 | \n", "1431 | \n", "1090 | \n", "8 | \n", "1 | \n", "0 | \n", "8 | \n", "... | \n", "3 | \n", "3 | \n", "0 | \n", "-16 | \n", "2449 | \n", "0 | \n", "4 | \n", "1974 | \n", "3 | \n", "63 | \n", "
5 rows × 108 columns
\n", "