{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Лабораторная работа 2\n", "\n", "## Общая информация\n", "\n", "Дата выдачи: 09.02.2016\n", "\n", "Срок сдачи: 1.03.2016 09:00MSK \n", "\n", "### О задании\n", "Лабораторная работа №2 направлена на реализацию одного из методов решения задачи линейной регрессии. \n", "\n", "### Оценивание и штрафы\n", "Каждая из задач имеет определенную «стоимость» (указана в скобках около задачи). Максимально допустимая оценка за работу — 10 баллов. **Обратите внимание, что только за реализацию функций без подтверждения их корректной работы оценка выставляться не будет.**\n", "\n", "Сдавать задание после указанного срока сдачи нельзя. При выставлении неполного балла за задание в связи с наличием ошибок на усмотрение проверяющего предусмотрена возможность исправить задание на указанных в ответном письме условиях.\n", "\n", "Задание выполняется САМОСТОЯТЕЛЬНО. «Похожие» решения считаются плагиатом и все задействованные студенты (в том числе те, у кого списали) не могут получить за него больше 0 баллов. Если вы нашли решение какого-то из заданий в открытом источнике, необходимо прислать ссылку на этот источник (скорее всего вы будете не единственным, кто это нашел, поэтому чтобы исключить подозрение в плагиате, необходима ссылка на источник). \n", "\n", "Если вы будете решать задание на виртуальной машине, учтите, что его могут видеть все. К тому же недоступность виртуальной машины не является уважительной причиной для продления дедлайна.\n", "\n", "### Формат сдачи\n", "Для сдачи задания переименуйте получившийся файл \\*.ipynb в соответствии со следующим форматом: *Username_(group)_Lab2.ipynb*, где Username — ваша фамилия на латинице, group — название группы (например, Kozlova_IAD-11_Lab1.ipynb). Далее отправьте этот файл на используемую в Вашей группе почту курса (hse.minor.dm@gmail.com) c темой письма *[ИАД-NN] - Лабораторная работа 2 - Фамилия Имя Отчество*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Задание\n", "\n", "### Постановка задачи\n", "\n", "В данном задании вам будет предложено реализовать метод градиентного спуска для задачи линейной регрессии. Подробное описание самого метода можно найти в материалах лекций и семинаров.\n", "\n", "Задание будет состоять из двух частей: вам будет необходимо реализовать градиентный спуск и протестировать его на небольших данных, после чего решить задачу линейной регрессии для реальных данных.\n", "\n", "Во всех частях задания будет использоваться квадратичный функционал качества:\n", "\n", "$$Q(w) = \\sum_{i=1}^l(\\langle w, x_i \\rangle - y_i)^2$$\n", "\n", "### Вспомогательные функции\n", "Для начала вам необходимо будет реализовать вспомогательные функции:\n", " - q_grad(X, y, w) — функция, принимающая на вход X — матрицу \"объекты-признаки\", y — столбец ответов, и w — вектор весов и возвращающая усредненное по всем элементам выборки значение градиента для квадратичной функции потерь\n", " - const_step(iter) — функция, возвращающая констатный размер шага\n", " - decreasing_step(iter) — функция, которой передается номер итерации и размер шага, обратно пропорциональный номеру итерации (обратите внимание, чтобы в данном месте не происходило деления на 0)\n", "\n", "Далее реализуйте функцию градиентного спуска *grad_descent(X, y, w, step, grad, iters)*, параметры которой:\n", " - X — матрица \"объекты-признаки\"\n", " - y — ответы на объектах\n", " - w — начальное значение вектора весов\n", " - step — одна из функций *const_step* или *decreasing_step*.\n", " - grad — функция q_grad\n", " - iters — максимальное число итераций \n", " \n", "Функция должна находить последовательно оптимальный вектор методом градиентного спуска, пока не будет выполнено хотя бы одно из условий:\n", " - достигнуто заданное количество итераций\n", " - евклидова норма разности текущего и нового векторов весов стала меньше чем 1e-5\n", "\n", "Функиця должна возвращать два параметра: \n", " - обученный вектор весов\n", " - качество модели на каждой итерации обучения\n", "\n", "Обратите внимание, что реализация не должна напрямую зависеть от числа признаков (чтобы ее можно было использовать в дальнейшем).\n", " \n", "### Задачи\n", "\n", "**(4 балла) Линейная регрессия. Отладка градиентного метода**\n", "![](http://i.imgur.com/O2FrddB.png)\n", "1. Сгенерируйте 200 точек с помощью функции generate_linear_data, на вход которой передается количество точек. \n", " \n", " def generate_linear_data(n):\n", " np.random.seed(42)\n", " x = np.linspace(0, 10, n) + np.random.normal(0, 3, n)\n", " y = 2 * x + 5 + np.random.normal(0, 2, n)\n", " return x, y\n", "2. Протестируйте вашу реализацию на сгенерированных точках. Не забудьте добавить констатный признак к данным (вы же помните, что мы хотим найти уравнение вида y = ax + b?). Ограничьте количество итераций 10000. Начальный вектор весов — нулевой. Протестируйте обе функции: *const_step* и *decreasing_step* что они работают корректно. Для функции *const_step* подберите оптимальный шаг из списка [1.0, 0.1, 0.01, 0.001]. Оптимальным шагом в данном случае будем считать тот, на котором достигается наименьшее значение квадратичного функционала качества. Обратите внимание, что в решении должны присутствовать код и комментарии, по которым можно понять как вы подобрали оптимальный шаг.\n", "3. Для оптимального шага из предыдущего пункта постройте два графика:\n", " - зависимость качества модели от номера итерации (обратите внимание, что качество должно убывать)\n", " - на котором будут изображены сгенерированные точки, а так же предсказанная линия \n", " \n", "Для построения графиков можно воспользоваться функциями scatter и plot.\n", "\n", "**Как понять что ваша реализация работает корректно?**\n", " - значение функционала качества с ростом числа итераций уменьшается\n", " - получается адекватный график, который очень похож на график выше\n", " - вектор весов +/-напоминает вектор (2, 5) (скорее всего вы не получите точно этого значения, однако получившийся вектор весов должен быть примерно близок к нему)\n", " \n", " Если не выполнено хотя бы одно из этих условий, то рекомендуется больше времени уделить этой части задания, пока все пункты не будут выполнены.\n", " \n", "*Выставление баллов по этому заданию:*\n", " - написанная реализация работает корректно и не зависит напрямую от количества признаков — 2 балла\n", " - подобран оптимальный шаг и есть код и комментарии, подтверждающие это — 1 балл\n", " - построен график зависимости качества от номера итерации — 0.5 балла\n", " - построен график предсказанной линии — 0.5 балла\n", " \n", "**(6 баллов) Предсказание качества вина**\n", "\n", "1. Загрузите с помощью pandas набор данных *wines_quality.csv*. Этот датасет содержит некоторые химические свойства вина, а также оценку качества, данную экспертом. Список признаков, с которыми вам нужно будет работать: \n", " - type — тип вина (красное/белое)\n", " - volatile acidity\n", " - citric acid\n", " - residual sugar\n", " - chlorides\n", " - free sulfur dioxide\n", " - other sulfur dioxide\n", " - total sulfur dioxide\n", " - density\n", " - pH\n", " - sulphates\n", " - alcohol\n", " \n", " А также *quality* — эмпирическая оценка (от 0 до 10), которую необходимо предсказать.\n", "2. Преобразуйте данные к типу numpy.array (поле values у датафрейма) и сразу же к типу np.float32 (функция astype(np.float32)).\n", "3. Выделите целевую переменную, которая находится в последней колонке, в переменную y, а все признаки — в numpy.array X.\n", "4. Убедитесь, что среди признаков нет зависимых. Если вы нашли такие признаки, то удалите их.\n", "5. Запустите градиентный спуск для данной выборке при максимальном числе итераций 10000. Начальный вектор весов — нулевой. Попробуйте разный шаг: константный в интервале [0.001, 0.0001, 0.00001, 0.000001], а так же убывающий с номером итерации. \n", "6. Найдите при каком шаге достигается наименьшее значение функционала качества и постройте график зависимости качества от номера итерации.\n", "7. Какой признак имеет наибольший вес для наилучшей модели?\n", "8. Посчитайте корреляцию Пирсона для исходных данных (для этого можно воспользоваться функциями numpy или методами датафрейма). Какой признак лучше всего коррелирует с целевой переменной? Согласуется ли это с тем, что вы получили в предыдущем пункте? Верно ли, что признаки, имеющие больший вес, имеют более высокую корреляцию с целевой переменной? Если вы пропустили пункт 4, попробуйте посмотреть внимательней на коэффициенты корреляции и в случае чего вернитесь к пункту 4. \n", "\n", "*Выставление баллов по этому заданию:*\n", " - работа с признаками — 1 балл\n", " - градиентный метод из предыдущего пункта по-прежнему работает корректно (см. первый критерий корректности) — 1 балл\n", " - подобран оптимальный шаг и есть код и комментарии, подтверждающие это — 1.5 балла\n", " - построен график зависимости качества от номера итерации — 0.5 балла\n", " - найден признак, имеющий больший вес — 0.5 балла.\n", " - проанализированы результаты коэффициентов корреляции Пирсона и дан подробный ответ на 8 пункт — 1.5 балла." ] } ], "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.10" } }, "nbformat": 4, "nbformat_minor": 0 }