diff --git a/ML17-fall/.DS_Store b/ML17-fall/.DS_Store new file mode 100644 index 0000000..33c540d Binary files /dev/null and b/ML17-fall/.DS_Store differ diff --git a/ML17-fall/homeworks-practice/.DS_Store b/ML17-fall/homeworks-practice/.DS_Store new file mode 100644 index 0000000..03d34d5 Binary files /dev/null and b/ML17-fall/homeworks-practice/.DS_Store differ diff --git a/ML17-fall/homeworks-practice/homework-practice-01/.ipynb_checkpoints/homework-practice-01-checkpoint.ipynb b/ML17-fall/homeworks-practice/homework-practice-01/.ipynb_checkpoints/homework-practice-01-checkpoint.ipynb new file mode 100644 index 0000000..7983908 --- /dev/null +++ b/ML17-fall/homeworks-practice/homework-practice-01/.ipynb_checkpoints/homework-practice-01-checkpoint.ipynb @@ -0,0 +1,421 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Машинное обучение, ФКН ВШЭ\n", + "\n", + "## Практическое задание 1\n", + "\n", + "### Общая информация\n", + "Дата выдачи: .09.2017 \n", + "\n", + "Мягкий дедлайн: 23:59MSK .09.2017 \n", + "\n", + "Жесткий дедлайн: 23:59MSK .09.2017 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### О задании\n", + "\n", + "__Первая часть__ задания посвящена получению студентами навыков работы с библиотекой векторного вычисления numpy и библиотеками для построения графиков matplotlib/plotly. Это задание сдается частично в Яндекс.Контест (см. информацию ниже).\n", + "\n", + "__Вторая часть__ задания посвящена работе с данными: их преобразованию в нужный формат и устранению проблем в них.\n", + "\n", + "\n", + "### Оценивание и штрафы\n", + "Каждая из задач имеет определенную «стоимость» (указана в скобках около задачи). Максимально допустимая оценка за работу — 10 баллов.\n", + "\n", + "Сдавать задание после указанного срока сдачи нельзя. При выставлении неполного балла за задание в связи с наличием ошибок на усмотрение проверяющего предусмотрена возможность исправить работу на указанных в ответном письме условиях.\n", + "\n", + "Задание выполняется самостоятельно. «Похожие» решения считаются плагиатом и все задействованные студенты (в том числе те, у кого списали) не могут получить за него больше 0 баллов (подробнее о плагиате см. на странице курса). Если вы нашли решение какого-то из заданий (или его часть) в открытом источнике, необходимо указать ссылку на этот источник в отдельном блоке в конце Вашей работы (скорее всего вы будете не единственным, кто это нашел, поэтому чтобы исключить подозрение в плагиате, необходима ссылка на источник).\n", + "\n", + "Неэффективная реализация кода может негативно отразиться на оценке.\n", + "\n", + "\n", + "### Формат сдачи\n", + "Для сдачи задания переименуйте получившийся файл *.ipynb в соответствии со следующим форматом: homework-practice-01-Username.ipynb, где Username — Ваша фамилия и имя на латинице именно в таком порядке (например, homework-practice-01-IvanovIvan.ipynb). Приложите модули с кодом functions.py и functions_vectorized.py и заархивируйте в zip формат. Имя архива должно быть homework-practice-01-Username.zip\n", + "\n", + "Далее отправьте этот файл на hse.cs.ml+<номер группы>@gmail.com (например, hse.cs.ml+141@gmail.com для студентов группы БПМИ-141).\n", + "\n", + "\n", + "Для удобства проверки самостоятельно посчитайте свою максимальную оценку (исходя из набора решенных задач) и укажите ниже." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Оценка:** ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Часть 1\n", + "\n", + "_Задачи позаимствованы из курса практикума кафедры ММП факультета ВМК МГУ_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задачи 1-6\n", + "__(4.5 балла)__\n", + "\n", + "Ниже приведены задачи на работу с numpy-массивами. Для каждой из задач нужно привести 2 реализации – одна без использования numpy (cчитайте, что там, где на входе или выходе должны быть numpy array, будут просто списки), а вторая полностью векторизованная (без использования питоновских циклов/map/list comprehension). Невекторизованная реализация каждой из задач оценивается в __0.25 балла__, векторизованная в __0.5 балла__.\n", + "\n", + "Реализации без использования векторизации нужно записать в файл functions.py, а векторизованные — в файл functions_vectorized.py (см. шаблоны). Далее эти файлы необходимо сдать в Яндекс.Контест: https://official.contest.yandex.ru/contest/5016/problems/ в соответствующие задачи. По техническим причинам тестирование проводится на этапе компиляции, поэтому в случае любой ошибки вы будете получать вердикт CE, и в логе компиляции можно будет посмотреть, в чем проблема. Частичное выполнение задания (не все задачи) будет оцениваться, хотя и будет получать вердикт CE. Для удобства проверки приложите в ячейке ниже ссылки на самые успешные посылки.\n", + "\n", + "\n", + "* __Задача 1__: Подсчитать произведение ненулевых элементов на диагонали прямоугольной матрицы. \n", + " Например, для X = np.array([[1, 0, 1], [2, 0, 2], [3, 0, 3], [4, 4, 4]]) ответ 3.\n", + " \n", + " \n", + "* __Задача 2__: Даны два вектора x и y. Проверить, задают ли они одно и то же мультимножество. \n", + " Например, для x = np.array([1, 2, 2, 4]), y = np.array([4, 2, 1, 2]) ответ True.\n", + " \n", + " \n", + "* __Задача 3__: Найти максимальный элемент в векторе x среди элементов, перед которыми стоит нулевой. \n", + " Например, для x = np.array([6, 2, 0, 3, 0, 0, 5, 7, 0]) ответ 5.\n", + " \n", + " \n", + "* __ Задача 4__: Дан трёхмерный массив, содержащий изображение, размера (height, width, numChannels), а также вектор длины numChannels. Сложить каналы изображения с указанными весами, и вернуть результат в виде матрицы размера (height, width). В ноутбуке приведите пример работы функции – преобразуйте цветное изображение в оттенки серого, использовав коэффициенты np.array([0.299, 0.587, 0.114]). Считать реальное изображение можно при помощи функции scipy.misc.imread (если изображение не в формате png, установите пакет pillow).\n", + "\n", + "\n", + "* __Задача 5__: Реализовать кодирование длин серий (Run-length encoding). Для некоторого вектора x необходимо вернуть кортеж из двух векторов одинаковой длины. Первый содержит числа, а второй - сколько раз их нужно повторить. \n", + " Например, для x = np.array([2, 2, 2, 3, 3, 3, 5]) ответ (np.array([2, 3, 5]), np.array([3, 3, 1])).\n", + " \n", + " \n", + "* __Задача 6__: Даны две выборки объектов - X и Y. Вычислить матрицу евклидовых расстояний между объектами. Сравните с функцией scipy.spatial.distance.cdist по скорости работы (сравнения приведите ниже в ноутбуке).\n", + "\n", + "__Замечание.__ Можно считать, что все указанные объекты непустые (к примеру, в __задаче 1__ на диагонали матрицы есть ненулевые элементы).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Посылка по невекторизованным функциям: ...\n", + "\n", + "Посылка по векторизованным функциям: ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 7\n", + "__(1.5 балла)__ \n", + "Для каждой задачи сравните скорость работы невекторизованной и векторизованной реализации. С помощью пакета matplotlib или plotly постройте графики времени работы в зависимости от размера данных. __Графики должны выглядеть опрятно!__ То есть должны быть подписаны оси, названия графиков, и т.д. Например, ниже представлены хороший и плохой графики:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "//anaconda/lib/python2.7/site-packages/matplotlib/figure.py:402: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n", + " \"matplotlib is currently using a non-GUI backend, \"\n" + ] + }, + { + "data": { + "image/png": "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\nrkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "%matplotlib inline\n", + "\n", + "data_size = np.array([10, 30, 70, 120])\n", + "time_non_vectorized = data_size ** 2 + 10\n", + "time_vectorized = data_size ** 1.5\n", + "\n", + "f, (ax1, ax2) = plt.subplots(1, 2, figsize=(13, 5))\n", + "\n", + "ax1.plot(data_size, time_non_vectorized)\n", + "ax1.plot(data_size, time_vectorized)\n", + "ax1.set_title(u\"Плохой график\")\n", + "ax1.set_xlabel(u\"Размер данных\")\n", + "ax1.set_ylabel(u\"Время\")\n", + "\n", + "ax2.plot(data_size, time_non_vectorized, label=u\"Невекторизованная\")\n", + "ax2.plot(data_size, time_vectorized, label=u\"Векторизованная\")\n", + "ax2.set_title(u\"Хороший график\")\n", + "ax2.set_xlabel(u\"Длина массива\")\n", + "ax2.set_ylabel(u\"Время (с)\")\n", + "ax2.grid()\n", + "ax2.legend()\n", + "\n", + "f.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Часть 2\n", + "\n", + "В данном задании мы рассмотрим набор данных об учащихся, собранный в 2006 году в одной из школ Португалии. Данные представлены в неудобном для машинного обучения виде, и содержат мусор. Ваша задача — привести их к надлежащему виду и обучить на них простую модель.\n", + "\n", + "**Внимание!** Хотя исходные данные для этого задания можно найти в интернете, делать это запрещается. Вся необходимая информация о данных содержится в задании. В случае затруднений обращайтесь к своему семинаристу(ке).\n", + "\n", + "Данные состоят из четырех файлов:\n", + "- data.csv — основная таблица с информацией о учащихся\n", + "- scores.csv — список финальных оценок по одному из предметов (20-балльная шкала переведенная в проценты)\n", + "- attendance.csv — таблица посещений занятий по этому предмету\n", + "- school_support.txt — список учащихся, которым оказывается финансовая поддержка\n", + "\n", + "Ваша задача — построить модель для предсказания финальных оценок исходя из всех остальных данных. Качество мы будем измерять по метрике RMSE.\n", + "\n", + "Расшифровка столбцов в data.csv для справки:\n", + "- age — возраст\n", + "- Medu — уровень образования матери (по некоторой условной шкале)\n", + "- Fedu — уровень образования отца (по некоторой условной шкале)\n", + "- traveltime — время в пути до школы (1 – < 15 мин., 2 – от 15 до 30 мин., 3 – от 30 мин. to 1 ч.\n", + "или 4 – > 1 ч.)\n", + "- studytime — время, затрачиваемое на занятия вне школы (1 – < 2 ч., 2 – от 2 до 5 ч., 3 – от 5 до 10 ч. или 4 – > 10 ч.)\n", + "- famrel — насколько хорошие отношения в семье у учащегося (по некоторой условной шкале)\n", + "- freetime — количество свободного времени вне школы (по некоторой условной шкале)\n", + "- goout — время, затрачиваемое на общение с друзьями (по некоторой условной шкале)\n", + "- Dalc — количество употребления алкоголя в учебные дни (по некоторой условной шкале)\n", + "- Walc — количество употребления алкоголя в неучебные дни (по некоторой условной шкале)\n", + "- health — уровень здоровья (по некоторой условной шкале)\n", + "- sex_M — пол: мужской (1) или женский (0)\n", + "- address_U — живет ли учащийся в городе (1) или в пригороде (0)\n", + "- famsize_LE3 — размер семьи: не больше 3 человек (1) или больше (0)\n", + "- Pstatus_T — живут ли родители вместе (1) или отдельно (0)\n", + "- nursery — посещал ли учащийся детский сад\n", + "- plans_university — планирует ли учащийся поступать в университет (-1 или 1)\n", + "- past_failures — количество неудовлетворительных оценок по другим предметам ранее (от 0 до 4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 1: пропуски в данных \n", + "__(0.5 балла)__\n", + "\n", + "Загрузите таблицу data.csv. Проверьте, есть ли в ней пропуски (значения NaN). Замените все пропущенные значения на среднее значение этого признака по столбцу.\n", + "\n", + "*Hint: изучите в pandas функции loc, isnull, а также передачу булевых массивов в качестве индексов.*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 2: кросс-валидация для исходных данных\n", + "__(0.5 балла)__\n", + "\n", + "Загрузите файл scores.csv и протестируйте, как линейная регрессия предсказывает ответ сейчас (с помощью кросс-валидации).\n", + "\n", + "*Hint: воспользуйтесь sklearn.linear_model и sklearn.model_selection.*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 3: полные данные\n", + "__(1 балл)__\n", + "\n", + "Воспользуйтесь файлами attendance.csv и school_support.txt для того, чтобы добавить новые признаки в данные. Желательно по максимуму использовать возможности pandas для упрощения преобразований." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 4: сломанный признак\n", + "__(0.5 балла)__\n", + "\n", + "Найдите в данных сломанный признак (он не соответствует описанию) и исправьте его." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 5: борьба с выбросами\n", + "__(1.5 балла)__\n", + "\n", + "Качество предсказания может ухудшаться, если в данных присутствуют корректные значения признаков (с точки зрения чтения данных и применения методов), но не соответствующие реальным объектам. Например, данные могли быть введены в неверном формате, а потом слишком грубо приведены к общему виду, из-за чего ошибка не была замечена.\n", + "Попробуем от такого избавиться — а для этого такие объекты нужно сначала найти. Конечно, нам еще недоступны многие продвинутые способы, но давайте попробуем обойтись простыми.\n", + "\n", + "Первый способ это сделать — посмотреть для каждого признака на распределение его значений и проверить крайние значения на правдоподобность.\n", + "\n", + "*Hint 1: используйте функцию DataFrame.hist*\n", + "\n", + "*Hint 2: в описании датасета выше есть информация, необходимая для восстановления правильных значений*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Другой простой способ найти выбросы — сделать предсказание на всех объектах и посмотреть на объекты с наибольшей ошибкой. Обратите внимание, что просто удалять все объекты с высокой ошибкой нельзя — это, конечно, хороший способ добиться меньшей ошибки (на данной выборке), но одновременно вы ухудшите обобщающую способность алгоритма. Вместо этого вам нужно найти однозначно ошибочные записи и их исправить.\n", + "\n", + "*Hint: возможно, все проблемы уже были найдены в прошлом пункте; для проверки — в обоих пунктах в сумме нужно исправить 3 проблемы.*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Финальное предсказание\n", + "\n", + "Проведите предсказание еще раз и сравните результат с исходным." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/ML17-fall/homeworks-practice/homework-practice-01/functions.py b/ML17-fall/homeworks-practice/homework-practice-01/functions.py new file mode 100644 index 0000000..d47308b --- /dev/null +++ b/ML17-fall/homeworks-practice/homework-practice-01/functions.py @@ -0,0 +1,83 @@ +def prod_non_zero_diag(x): + """Compute product of nonzero elements from matrix diagonal. + + input: + x -- 1-d numpy array + output: + product -- integer number + + + Not vectorized implementation. + """ + + pass + + +def are_multisets_equal(x, y): + """Return True if both vectors create equal multisets. + + input: + x, y -- 1-d numpy arrays + output: + True if multisets are equal, False otherwise -- boolean + + Not vectorized implementation. + """ + + pass + + +def max_after_zero(x): + """Find max element after zero in array. + + input: + x -- 1-d numpy array + output: + maximum element after zero -- integer number + + Not vectorized implementation. + """ + + pass + + +def run_length_encoding(x): + """Make run-length encoding. + + input: + x -- 1-d numpy array + output: + elements, counters -- integer iterables + + Not vectorized implementation. + """ + + pass + +def convert_image(img, coefs): + """Sum up image channels with weights from coefs array + + input: + img -- 3-d numpy array (H x W x 3) + coefs -- 1-d numpy array (length 3) + output: + img -- 2-d numpy array + + Not vectorized implementation. + """ + + pass + + +def pairwise_distance(x, y): + """Return pairwise object distance. + + input: + x, y -- 2d numpy arrays + output: + distance array -- 2d numpy array + + Not vectorized implementation. + """ + + pass diff --git a/ML17-fall/homeworks-practice/homework-practice-01/functions_vectorized.py b/ML17-fall/homeworks-practice/homework-practice-01/functions_vectorized.py new file mode 100644 index 0000000..96e85ce --- /dev/null +++ b/ML17-fall/homeworks-practice/homework-practice-01/functions_vectorized.py @@ -0,0 +1,85 @@ +import numpy as np + +def prod_non_zero_diag(x): + """Compute product of nonzero elements from matrix diagonal. + + input: + x -- 1-d numpy array + output: + product -- integer number + + + Vectorized implementation. + """ + + pass + + +def are_multisets_equal(x, y): + """Return True if both vectors create equal multisets. + + input: + x, y -- 1-d numpy arrays + output: + True if multisets are equal, False otherwise -- boolean + + Vectorized implementation. + """ + + pass + + +def max_after_zero(x): + """Find max element after zero in array. + + input: + x -- 1-d numpy array + output: + maximum element after zero -- integer number + + Vectorized implementation. + """ + + pass + + +def run_length_encoding(x): + """Make run-length encoding. + + input: + x -- 1-d numpy array + output: + elements, counters -- integer iterables + + Vectorized implementation. + """ + + pass + +def convert_image(img, coefs): + """Sum up image channels with weights from coefs array + + input: + img -- 3-d numpy array (H x W x 3) + coefs -- 1-d numpy array (length 3) + output: + img -- 2-d numpy array + + Vectorized implementation. + """ + + pass + + +def pairwise_distance(x, y): + """Return pairwise object distance. + + input: + x, y -- 2d numpy arrays + output: + distance array -- 2d numpy array + + Vctorized implementation. + """ + + pass diff --git a/ML17-fall/homeworks-practice/homework-practice-01/homework-practice-01.ipynb b/ML17-fall/homeworks-practice/homework-practice-01/homework-practice-01.ipynb new file mode 100644 index 0000000..92a13f7 --- /dev/null +++ b/ML17-fall/homeworks-practice/homework-practice-01/homework-practice-01.ipynb @@ -0,0 +1,421 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Машинное обучение, ВМК МГУ\n", + "\n", + "## Практическое задание 1\n", + "\n", + "### Общая информация\n", + "Дата выдачи: 18.09.2017 \n", + "\n", + "Мягкий дедлайн: 23:59MSK 01.09.2017 \n", + "\n", + "Жесткий дедлайн: 23:59MSK 08.09.2017 " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### О задании\n", + "\n", + "__Первая часть__ задания посвящена получению студентами навыков работы с библиотекой векторного вычисления numpy и библиотеками для построения графиков matplotlib/plotly. Это задание сдается частично в Яндекс.Контест (см. информацию ниже).\n", + "\n", + "__Вторая часть__ задания посвящена работе с данными: их преобразованию в нужный формат и устранению проблем в них.\n", + "\n", + "\n", + "### Оценивание и штрафы\n", + "Каждая из задач имеет определенную «стоимость» (указана в скобках около задачи). Максимально допустимая оценка за работу — 10 баллов.\n", + "\n", + "Сдавать задание после указанного срока сдачи нельзя. При выставлении неполного балла за задание в связи с наличием ошибок на усмотрение проверяющего предусмотрена возможность исправить работу на указанных в ответном письме условиях.\n", + "\n", + "Задание выполняется самостоятельно. «Похожие» решения считаются плагиатом и все задействованные студенты (в том числе те, у кого списали) не могут получить за него больше 0 баллов (подробнее о плагиате см. на странице курса). Если вы нашли решение какого-то из заданий (или его часть) в открытом источнике, необходимо указать ссылку на этот источник в отдельном блоке в конце Вашей работы (скорее всего вы будете не единственным, кто это нашел, поэтому чтобы исключить подозрение в плагиате, необходима ссылка на источник).\n", + "\n", + "Неэффективная реализация кода может негативно отразиться на оценке.\n", + "\n", + "\n", + "### Формат сдачи\n", + "Для сдачи задания переименуйте получившийся файл *.ipynb в соответствии со следующим форматом: homework-practice-01-Username.ipynb, где Username — Ваша фамилия и имя на латинице именно в таком порядке (например, homework-practice-01-IvanovIvan.ipynb). Приложите модули с кодом functions.py и functions_vectorized.py и заархивируйте в zip формат. Имя архива должно быть homework-practice-01-Username.zip\n", + "\n", + "Далее отправьте этот файл на hse.cs.ml+<номер группы>@gmail.com (например, hse.cs.ml+141@gmail.com для студентов группы БПМИ-141).\n", + "\n", + "\n", + "Для удобства проверки самостоятельно посчитайте свою максимальную оценку (исходя из набора решенных задач) и укажите ниже." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Оценка:** ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Часть 1\n", + "\n", + "_Задачи позаимствованы из курса практикума кафедры ММП факультета ВМК МГУ_" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задачи 1-6\n", + "__(4.5 балла)__\n", + "\n", + "Ниже приведены задачи на работу с numpy-массивами. Для каждой из задач нужно привести 2 реализации – одна без использования numpy (cчитайте, что там, где на входе или выходе должны быть numpy array, будут просто списки), а вторая полностью векторизованная (без использования питоновских циклов/map/list comprehension). Невекторизованная реализация каждой из задач оценивается в __0.25 балла__, векторизованная в __0.5 балла__.\n", + "\n", + "Реализации без использования векторизации нужно записать в файл functions.py, а векторизованные — в файл functions_vectorized.py (см. шаблоны). Далее эти файлы необходимо сдать в Яндекс.Контест: https://contest.yandex.ru/contest/5016/problems/ в соответствующие задачи. По техническим причинам тестирование проводится на этапе компиляции, поэтому в случае любой ошибки вы будете получать вердикт CE, и в логе компиляции можно будет посмотреть, в чем проблема. Частичное выполнение задания (не все задачи) будет оцениваться, хотя и будет получать вердикт CE. Для удобства проверки приложите в ячейке ниже ссылки на самые успешные посылки.\n", + "\n", + "\n", + "* __Задача 1__: Подсчитать произведение ненулевых элементов на диагонали прямоугольной матрицы. \n", + " Например, для X = np.array([[1, 0, 1], [2, 0, 2], [3, 0, 3], [4, 4, 4]]) ответ 3.\n", + " \n", + " \n", + "* __Задача 2__: Даны два вектора x и y. Проверить, задают ли они одно и то же мультимножество. \n", + " Например, для x = np.array([1, 2, 2, 4]), y = np.array([4, 2, 1, 2]) ответ True.\n", + " \n", + " \n", + "* __Задача 3__: Найти максимальный элемент в векторе x среди элементов, перед которыми стоит нулевой. \n", + " Например, для x = np.array([6, 2, 0, 3, 0, 0, 5, 7, 0]) ответ 5.\n", + " \n", + " \n", + "* __ Задача 4__: Дан трёхмерный массив, содержащий изображение, размера (height, width, numChannels), а также вектор длины numChannels. Сложить каналы изображения с указанными весами, и вернуть результат в виде матрицы размера (height, width). В ноутбуке приведите пример работы функции – преобразуйте цветное изображение в оттенки серого, использовав коэффициенты np.array([0.299, 0.587, 0.114]). Считать реальное изображение можно при помощи функции scipy.misc.imread (если изображение не в формате png, установите пакет pillow).\n", + "\n", + "\n", + "* __Задача 5__: Реализовать кодирование длин серий (Run-length encoding). Для некоторого вектора x необходимо вернуть кортеж из двух векторов одинаковой длины. Первый содержит числа, а второй - сколько раз их нужно повторить. \n", + " Например, для x = np.array([2, 2, 2, 3, 3, 3, 5]) ответ (np.array([2, 3, 5]), np.array([3, 3, 1])).\n", + " \n", + " \n", + "* __Задача 6__: Даны две выборки объектов - X и Y. Вычислить матрицу евклидовых расстояний между объектами. Сравните с функцией scipy.spatial.distance.cdist по скорости работы (сравнения приведите ниже в ноутбуке).\n", + "\n", + "__Замечание.__ Можно считать, что все указанные объекты непустые (к примеру, в __задаче 1__ на диагонали матрицы есть ненулевые элементы).\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Посылка по невекторизованным функциям: ...\n", + "\n", + "Посылка по векторизованным функциям: ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 7\n", + "__(1.5 балла)__ \n", + "Для каждой задачи сравните скорость работы невекторизованной и векторизованной реализации. С помощью пакета matplotlib или plotly постройте графики времени работы в зависимости от размера данных. __Графики должны выглядеть опрятно!__ То есть должны быть подписаны оси, названия графиков, и т.д. Например, ниже представлены хороший и плохой графики:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "//anaconda/lib/python2.7/site-packages/matplotlib/figure.py:402: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n", + " \"matplotlib is currently using a non-GUI backend, \"\n" + ] + }, + { + "data": { + "image/png": "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\nrkJggg==\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "%matplotlib inline\n", + "\n", + "data_size = np.array([10, 30, 70, 120])\n", + "time_non_vectorized = data_size ** 2 + 10\n", + "time_vectorized = data_size ** 1.5\n", + "\n", + "f, (ax1, ax2) = plt.subplots(1, 2, figsize=(13, 5))\n", + "\n", + "ax1.plot(data_size, time_non_vectorized)\n", + "ax1.plot(data_size, time_vectorized)\n", + "ax1.set_title(u\"Плохой график\")\n", + "ax1.set_xlabel(u\"Размер данных\")\n", + "ax1.set_ylabel(u\"Время\")\n", + "\n", + "ax2.plot(data_size, time_non_vectorized, label=u\"Невекторизованная\")\n", + "ax2.plot(data_size, time_vectorized, label=u\"Векторизованная\")\n", + "ax2.set_title(u\"Хороший график\")\n", + "ax2.set_xlabel(u\"Длина массива\")\n", + "ax2.set_ylabel(u\"Время (с)\")\n", + "ax2.grid()\n", + "ax2.legend()\n", + "\n", + "f.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Часть 2\n", + "\n", + "В данном задании мы рассмотрим набор данных об учащихся, собранный в 2006 году в одной из школ Португалии. Данные представлены в неудобном для машинного обучения виде, и содержат мусор. Ваша задача — привести их к надлежащему виду и обучить на них простую модель.\n", + "\n", + "**Внимание!** Хотя исходные данные для этого задания можно найти в интернете, делать это запрещается. Вся необходимая информация о данных содержится в задании. В случае затруднений обращайтесь к своему семинаристу(ке).\n", + "\n", + "Данные состоят из четырех файлов:\n", + "- data.csv — основная таблица с информацией о учащихся\n", + "- scores.csv — список финальных оценок по одному из предметов (20-балльная шкала переведенная в проценты)\n", + "- attendance.csv — таблица посещений занятий по этому предмету\n", + "- school_support.txt — список учащихся, которым оказывается финансовая поддержка\n", + "\n", + "Ваша задача — построить модель для предсказания финальных оценок исходя из всех остальных данных. Качество мы будем измерять по метрике RMSE.\n", + "\n", + "Расшифровка столбцов в data.csv для справки:\n", + "- age — возраст\n", + "- Medu — уровень образования матери (по некоторой условной шкале)\n", + "- Fedu — уровень образования отца (по некоторой условной шкале)\n", + "- traveltime — время в пути до школы (1 – < 15 мин., 2 – от 15 до 30 мин., 3 – от 30 мин. to 1 ч.\n", + "или 4 – > 1 ч.)\n", + "- studytime — время, затрачиваемое на занятия вне школы (1 – < 2 ч., 2 – от 2 до 5 ч., 3 – от 5 до 10 ч. или 4 – > 10 ч.)\n", + "- famrel — насколько хорошие отношения в семье у учащегося (по некоторой условной шкале)\n", + "- freetime — количество свободного времени вне школы (по некоторой условной шкале)\n", + "- goout — время, затрачиваемое на общение с друзьями (по некоторой условной шкале)\n", + "- Dalc — количество употребления алкоголя в учебные дни (по некоторой условной шкале)\n", + "- Walc — количество употребления алкоголя в неучебные дни (по некоторой условной шкале)\n", + "- health — уровень здоровья (по некоторой условной шкале)\n", + "- sex_M — пол: мужской (1) или женский (0)\n", + "- address_U — живет ли учащийся в городе (1) или в пригороде (0)\n", + "- famsize_LE3 — размер семьи: не больше 3 человек (1) или больше (0)\n", + "- Pstatus_T — живут ли родители вместе (1) или отдельно (0)\n", + "- nursery — посещал ли учащийся детский сад\n", + "- plans_university — планирует ли учащийся поступать в университет (-1 или 1)\n", + "- past_failures — количество неудовлетворительных оценок по другим предметам ранее (от 0 до 4)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 1: пропуски в данных \n", + "__(0.5 балла)__\n", + "\n", + "Загрузите таблицу data.csv. Проверьте, есть ли в ней пропуски (значения NaN). Замените все пропущенные значения на среднее значение этого признака по столбцу.\n", + "\n", + "*Hint: изучите в pandas функции loc, isnull, а также передачу булевых массивов в качестве индексов.*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 2: кросс-валидация для исходных данных\n", + "__(0.5 балла)__\n", + "\n", + "Загрузите файл scores.csv и протестируйте, как линейная регрессия предсказывает ответ сейчас (с помощью кросс-валидации).\n", + "\n", + "*Hint: воспользуйтесь sklearn.linear_model и sklearn.model_selection.*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 3: полные данные\n", + "__(1 балл)__\n", + "\n", + "Воспользуйтесь файлами attendance.csv и school_support.txt для того, чтобы добавить новые признаки в данные. Желательно по максимуму использовать возможности pandas для упрощения преобразований." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 4: сломанный признак\n", + "__(0.5 балла)__\n", + "\n", + "Найдите в данных сломанный признак (он не соответствует описанию) и исправьте его." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Задача 5: борьба с выбросами\n", + "__(1.5 балла)__\n", + "\n", + "Качество предсказания может ухудшаться, если в данных присутствуют корректные значения признаков (с точки зрения чтения данных и применения методов), но не соответствующие реальным объектам. Например, данные могли быть введены в неверном формате, а потом слишком грубо приведены к общему виду, из-за чего ошибка не была замечена.\n", + "Попробуем от такого избавиться — а для этого такие объекты нужно сначала найти. Конечно, нам еще недоступны многие продвинутые способы, но давайте попробуем обойтись простыми.\n", + "\n", + "Первый способ это сделать — посмотреть для каждого признака на распределение его значений и проверить крайние значения на правдоподобность.\n", + "\n", + "*Hint 1: используйте функцию DataFrame.hist*\n", + "\n", + "*Hint 2: в описании датасета выше есть информация, необходимая для восстановления правильных значений*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Другой простой способ найти выбросы — сделать предсказание на всех объектах и посмотреть на объекты с наибольшей ошибкой. Обратите внимание, что просто удалять все объекты с высокой ошибкой нельзя — это, конечно, хороший способ добиться меньшей ошибки (на данной выборке), но одновременно вы ухудшите обобщающую способность алгоритма. Вместо этого вам нужно найти однозначно ошибочные записи и их исправить.\n", + "\n", + "*Hint: возможно, все проблемы уже были найдены в прошлом пункте; для проверки — в обоих пунктах в сумме нужно исправить 3 проблемы.*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Финальное предсказание\n", + "\n", + "Проведите предсказание еще раз и сравните результат с исходным." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Your code here\n", + "# ..." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/ML17-fall/homeworks-theory/.DS_Store b/ML17-fall/homeworks-theory/.DS_Store new file mode 100644 index 0000000..e92fd2b Binary files /dev/null and b/ML17-fall/homeworks-theory/.DS_Store differ diff --git a/ML17-fall/homeworks-theory/homework-theory-1-differentiation.pdf b/ML17-fall/homeworks-theory/homework-theory-1-differentiation.pdf new file mode 100644 index 0000000..5630ea9 Binary files /dev/null and b/ML17-fall/homeworks-theory/homework-theory-1-differentiation.pdf differ diff --git a/README-16-17.md b/README-16-17.md new file mode 100644 index 0000000..f3dfbbf --- /dev/null +++ b/README-16-17.md @@ -0,0 +1,169 @@ +# Семинары по машинному обучению, ВМК МГУ + + + +Конспекты, код и прочие материалы к семинарам по машинному обучению, проводимым на ВМК МГУ. + +Почта для заданий: ml.cmc.msu@gmail.com + +[Страница курса на machinelearning.ru](http://www.machinelearning.ru/wiki/index.php?title=Машинное_обучение_%28семинары%2C_ВМК_МГУ%29) + +[Канал в telegram для объявлений](https://telegram.me/joinchat/A5rlQD_hqqV2n5AOWEVrVA) + +[Оценки за курс](https://docs.google.com/spreadsheets/d/1A5BJs_dJcmqY2KVBUCTWlXueTeFWNVT6Tbx5e3dN6_c/edit#gid=2044373835) + +На семинары и работу ассистента можно оставить отзыв: [[анонимно без регистрации и смс](https://docs.google.com/forms/d/1j8zMReMtl-BCeAVISxx_v42_y8GAVeolofFuAHQjHBc/viewform)] + +Курс лекций на ФКН ВШЭ: [[wiki](http://wiki.cs.hse.ru/Машинное_обучение_1)] [[материалы](https://github.com/esokolov/ml-course-hse)] + +## Правила выставления оценок + +**Итоговая контрольная работа:** + +1. На последней лекции будет проведена контрольная работа, которая затронет все темы, изученные в течение семестра. +2. Контрольная оценивается по двухбалльной шкале (зачет/незачет), незачет влечет за собой недопуск к экзамену. +3. Студент, не получивший допуск, переписывает на экзамене контрольную. В случае успеха он сдает экзамен на первой пересдаче. В случае незачета он снова переписывает контрольную на первой пересдаче, и так далее. + +**Семинары:** + +1. На семинарах по каждой пройденной теме будут проводиться проверочные работы. Каждая проверочная оценивается по пятибалльной шкале. В зависимости от оценки за проверочную, студент освобождается от части или от всех задач по этой теме на итоговой контрольной работе. +2. На семинарах будут выдаваться практические задания, которые будут оцениваться по десятибалльной шкале. +3. В течение семестра будут проводиться конкурсы по анализу данных. Правила выставления оценок для каждого конкурса указываются в условиях самого конкурса. +4. Оценка за работу в семестре равна сумме оценок за проверочные работы, практические задания и конкурсы. +5. Если оценка за работу в семестре не меньше 100% от максимальной оценки за проверочные и лабораторные работы, то студент освобождается от написания итоговой контрольной и получает допуск к экзамену автоматом. +6. Если оценка за работу в семестре не меньше 80% от максимальной оценки за проверочные и лабораторные работы и конкурсы, то студент получает +1 балл на экзамене (при условии получения положительной оценки). +7. В конце семестра разрешается переписать все проверочные, пропущенные по уважительной причине. + +## Занятия + +| Дата | Номер | Тема | Материалы | ДЗ | +| :---: | :---: | --- | --- | --- | +| 2 сентября | Семинар 1 | Вводное занятие: | [Конспект](ML16/lecture-notes/Sem01_intro.pdf) | | +| 16 сентября | Семинар 2 | Метрические методы: | [Конспект](ML16/lecture-notes/Sem02_knn.pdf)
[Notebook](ML16/src/Sem02_python_intro.ipynb) | | +| 23 сентября | Семинар 3 | Метрические методы: | [Конспект](ML16/lecture-notes/Sem03_knn.pdf)
[Notebook](ML16/src/Sem03_numpy_knn.ipynb) | [Домашнее задание](ML16/homeworks/Sem03_knn_hw.pdf) | +| 30 сентября | Семинар 4 | Решающие деревья: | [Конспект](ML16/lecture-notes/Sem04_trees.pdf) | [Домашнее задание](ML16/homeworks/Sem04_trees_hw.pdf) | +| 7 октября | Семинар 5 | Решающие деревья: | [Конспект](ML16/lecture-notes/Sem04_trees.pdf)
[Notebook](ML16/src/Sem05_trees.ipynb) | | +| 14 октября | Семинар 6 | Метрики качества: | Теория: [конспект](https://github.com/esokolov/ml-course-hse/blob/master/2016-fall/lecture-notes/lecture04-linclass.pdf), раздел 2

Практика: [конспект](https://github.com/esokolov/ml-course-hse/blob/master/2016-fall/seminars/sem05-linclass.pdf), задача 1.1 | | +| 21 октября | Семинар 7 | Метрики качества: | Теория: [конспект](https://github.com/esokolov/ml-course-hse/blob/master/2016-fall/lecture-notes/lecture04-linclass.pdf), раздел 2

Практика: [конспект](https://github.com/esokolov/ml-course-hse/blob/master/2016-fall/seminars/sem05-linclass.pdf), задачи 1.2, 1.3, 1.4 | [Домашнее задание](ML16/homeworks/Sem07_metrics_hw.pdf) | +| 28 октября | Семинар 8 | Линейная классификация: | Теория: [конспект](ML16/lecture-notes/Sem09_linear.pdf) | | +| 11 ноября | Семинар 9 | Линейная классификация: | Теория: [конспект](ML16/lecture-notes/Sem09_linear.pdf)

[конспект по разреженным моделям](https://github.com/esokolov/ml-course-hse/blob/master/2016-fall/lecture-notes/lecture03-linregr.pdf), раздел 5 | [Домашнее задание](ML16/homeworks/Sem09_linear_hw.pdf) | +| 18 ноября | Семинар 10 | Условная оптимизация: | Теория: [конспект](ML16/lecture-notes/Sem10_linear.pdf) | [Домашнее задание](ML16/homeworks/Sem10_linear_hw.pdf) | +| 25 ноября | Семинар 11 | Отчёты о соревнованиях: | | | +| 2 декабря | Семинар 12 | Линейные модели: | Теория: [конспект](ML16/lecture-notes/Sem11_linear.pdf) | [Домашнее задание](ML16/homeworks/Sem11_linear_hw.pdf) | +| 9 декабря | Семинар 13 | Линейные модели: | Теория: [конспект](ML16/lecture-notes/Sem12_linear.pdf) | [Домашнее задание](ML16/homeworks/Sem12_linear_hw.pdf) | +| 16 декабря | Семинар 14 | Байесовские методы: | Теория: [конспект](ML16/lecture-notes/Sem13_bayes.pdf) | | +| 16 февраля | Семинар 15 | Разложение ошибки на смещение и разброс | [Конспект](https://github.com/esokolov/ml-course-hse/blob/master/2016-fall/seminars/sem08-ensembles.pdf) | [Домашнее задание](ML16-spring/homeworks/Sem01_ensembles_hw.pdf) +| 2 марта | Семинар 16 | Композиции, случайные леса | [Конспект](https://github.com/esokolov/ml-course-hse/blob/master/2016-fall/lecture-notes/lecture08-ensembles.pdf) | +| 9 марта | Семинар 17 | Градиентный бустинг | [Теория](https://github.com/esokolov/ml-course-hse/blob/master/2016-fall/lecture-notes/lecture09-ensembles.pdf)
[Задачи](https://github.com/esokolov/ml-course-hse/blob/master/2016-fall/seminars/sem09-ensembles.pdf) | +| 16 марта | Семинар 18 | EM-алгоритм и смеси нормальных распределений | [Конспект](ML16-spring/lecture-notes/Sem04_em.pdf) (1.1-1.4) | [Домашнее задание](ML16-spring/homeworks/Sem04_em_hw.pdf) + +## Практические задания + +Если задание сдано и было проверено до дедлайна, то разрешается без штрафа внести исправления и прислать новую версию. +Новую версию необходимо прислать не позднее мягкого дедлайна. +Дальнейшие исправления возможны на усмотрение преподавателей. + +Чтобы мы точно успели проверить решение, рекомендуем присылать хотя бы за неделю до дедлайна. + +Обратите внимание, что по каждому заданию даётся два дедлайна: мягкий и жёсткий. +За сдачу задания после мягкого дедлайна оценка понижается на 0.05\*n\*(n + 1) баллов, где n — количество дней просрочки. +Оценка за задание не может быть отрицательной. + +### Задание 1: Pandas, kNN и решающие деревья + +[Условие](ML16/labs/lab01_pandas_knn_trees.ipynb) + +Дата выдачи: 16.10.2016 + +Мягкий дедлайн: 30.10.2016, 23:59 MSK + +Жёсткий дедлайн: 06.11.2016 23:59 MSK + +### Задание 2: решающие деревья + +[Условие](ML16/labs/lab02_trees.ipynb) + +Дата выдачи: 14.11.2016 + +Мягкий дедлайн: 05.12.2016, 05:59 MSK + +### Задание 3: EM-алгоритм +[Условие](ML16-spring/labs/lab-01-em.ipynb) + +Дата выдачи: 18.04.2017 + +Мягкий дедлайн: 07.05.2017, 05:59 MSK + +## Соревнования + +По каждому соревнованию в течение недели после его окончания необходимо прислать краткий отчёт о решении +и код, с помощью которого можно воспроизвести решение. + +### Соревнование 1: вероятность победы в Dota 2 + +Дата выдачи: 21.10.2016 + +Дедлайн для индивидуального участия: 6.11.2016 + +Старт командного участия: 7.11.2016 + +Дедлайн для командного участия: 20.11.2016 + +Соревнование: https://inclass.kaggle.com/c/cmc-msu-machine-learning-fall-2016-2017-competition-1 + +Ссылка для участия: [link](https://kaggle.com/join/cmc_msu_fall_contest_1_c83bd9mw) + +[Описание задачи](ML16/contests/contest01-dota-statement.ipynb) + +За первое, второе и третье место в индивидуальной части контеста ставится 10, 9 и 8 баллов соответственно. +За места с четвертого и по самое последнее выставляется от 7 до 1 баллов по равномерной сетке. +Участникам, которые не смогли преодолеть бейзлайн, оценка обнуляется. + +По окончании индивидуальной части участники делятся по рейтингу на 3 или 4 корзинки (в зависимости от их количества), +из которых собираются случайные равномерные по силе команды. +В командной части за места с первого по третье ставятся 4, 3 и 2 балла, а дальше по равномерной сетке до 1. +Также в каждой команде будет подсчитан процент улучшения качества относительно лучшего из участников; +исходя из этого рейтинга, будут проставлены дополнительные баллы по такому же принципу, как и в предыдущем предложении. +Следует помнить, что оценка в командной части для участников из нижних корзинок будет сильно зависить от их понимания решения (отчета и выступления). + +По окончании контестов участники, занявшие первые 3 места должны выступить с кратким рассказом о своем решении. Если все присланные группой решения будут тривиальными, то преподаватель имеет право снизить максимальную оценку до 10 или 5 баллов. + +**Альтернативное соревнование** + +[Sberbank Data Science Contest](https://sdsj.ru/contest.html) + +Правила выставления оценок аналогичны правилам по индивидуальной части соревнования по Dota. +Никаких ограничений на методы решения не накладывается. +Командное решение не предусмотрено. +Если студент участвовал и в индивидуальном соревновании по Dota, и в данном соревновании, +то ему будет выставлена максимальная из двух оценок, а не сумма. +Возможно решение сначала только контеста Сбербанка, а потом командное учебного по Dota, +но нужно заранее (за пару дней до начала командной части) уведомить об этом преподавателей. +В зависимости от количества участников контеста шкала может быть понижена и/или разрежена. +Также за высокие места среди всех участников в общем зачете или по каждой задаче могут выдаваться серьёзные бонусы. + +### Соревнование 2: Santander Product Recommendation + +Дата выдачи: 28.11.2016 + +Начало командной части: 7.12.2016 + +Дедлайн на образование команд: 14.12.2016 (позже этого числа kaggle не разрешит слияние) + +Оконачание контеста: 21.12.2016 + +Соревнование: https://www.kaggle.com/c/santander-product-recommendation + +[Рекомендации по соревнованию](ML16/contests/santander.ipynb) + +Для участия в командной части нужно занять достаточно высокое место на public leaderboard. +Ориентировочно потребуется занять место min(60, лучшее\_место\_лучшего\_скрипта - 5), +но ближе к началу командной части этот порог может быть изменен в ту или иную сторону по усмотрению преподавателей. +Всем, кто преодолеет этот порог, будут начислены 7 баллов. + +Для каждой команды будет выделен "куратор" — человек, +у которого есть опыт в решении контестов и который сможет помочь с идеями. +За хорошие места на private leaderboard будут поставлены дополнительные баллы. + +Пользоваться можно любыми алгоритмами машинного обучения, даже теми, что еще не были рассмотрены в курсе. +