{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Проект по анализу данных\n", "\n", "## Общая информация\n", "\n", "Дата выдачи: 05.06.2016\n", "\n", "Срок сдачи: 19.06.2016 09:00MSK\n", "\n", "### О задании\n", "В рамках курса \"Интеллектуальный анализ данных\" помимо выполнения контрольных и практических заданий вам также нужно выполнить проект. За каждый модуль ставится отдельная оценка. В этом модуле вы продолжите работу с данными, которую начали в прошлом модуле, построив модели для предсказания. \n", "\n", "Пустые ячейки оставлены там, где нужно написать код либо ответить на вопросы.\n", "\n", "### Оценивание и штрафы\n", "Каждая из задач имеет определенную «стоимость» (указана в скобках около задачи). Максимально допустимая оценка за работу — 10 баллов. Помимо кода вам также требуется написать развернутые ответы на вопросы.\n", "\n", "Сдавать задание после указанного срока сдачи нельзя. При выставлении неполного балла за задание в связи с наличием ошибок на усмотрение проверяющего предусмотрена возможность исправить задание на указанных в ответном письме условиях.\n", "\n", "Задание выполняется САМОСТОЯТЕЛЬНО. «Похожие» решения считаются плагиатом и все задействованные студенты (в том числе те, у кого списали) не могут получить за него больше 0 баллов. Если вы нашли решение какого-то из заданий в открытом источнике, необходимо прислать ссылку на этот источник (скорее всего вы будете не единственным, кто это нашел, поэтому чтобы исключить подозрение в плагиате, необходима ссылка на источник).\n", "\n", "Если вы будете решать задание на виртуальной машине, учтите, что его могут видеть все. К тому же недоступность виртуальной машины не является уважительной причиной для продления дедлайна.\n", "\n", "Обратите внимание, что на устном зачете в конце семестра некотоые вопросы могут быть связаны с проектом.\n", "\n", "### Доп. баллы\n", "В данном проекте вам будет предложено рассмотреть некоторые интересные закономерности в данных. Если вы обнаружите что-то интересное (например, в последнем пункте), либо у вас есть идеи как можно работать с данным датасетом — присылайте, это будет поощряться дополнительными баллами. Кроме того, вы можете выступить со своим личным исследованием на семинаре, это также не останется незамеченным.\n", "\n", "### Формат сдачи\n", "Для сдачи задания переименуйте получившийся файл *.ipynb в соответствии со следующим форматом: Username_(group)_Project.ipynb, где Username — ваша фамилия на латинице, group — название группы (например, Kozlova_IAD-11_Project.ipynb). Далее отправьте этот файл на используемую в Вашей группе почту курса (hse.minor.dm@gmail.com) c темой письма [ИАД-NN] - Проект - Фамилия Имя Отчество." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Определение итоговой оценки студента" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если вы не помните, с каким именно датасетом работали, то можете воспользоваться функцией *get_dataset_name*, на вход ей передав ваш адрес электронной почты." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def get_dataset_name(email):\n", " return 'student-mat.csv' if sum(ord(c) for c in email) % 2 else 'student-por.csv'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Выполните код ниже, передав на вход строку с адресом электронной почты:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "get_dataset_name('')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Датасеты имеют следующий набор признаков:\n", " - school - тип школы (\"GP\" - Gabriel Pereira или \"MS\" - Mousinho da Silveira)\n", " - sex - пол (\"F\" - female или \"M\" - male)\n", " - age - возраст (от 15 до 22)\n", " - address - откуда студент (\"U\" - urban или \"R\" - rural)\n", " - famsize - размер семьи (\"LE3\" - меньше или равно 3 или \"GT3\" - больше 3)\n", " - Pstatus - в каких отношениях родители (\"T\" - живут вместе \"A\" - раздельно)\n", " - Medu - образование матери (0 - никакого, 1 - начальное образование (4 класса), 2 – от 5 до 9 классов, 3 – среднеспециальное или 4 – высшее)\n", " - Fedu - образование отца (0 - никакого, 1 - начальное образование (4 класса), 2 – от 5 до 9 классов, 3 – среднеспециальное или 4 – высшее)\n", " - Mjob - работа матери (\"teacher\", \"health\" care related, civil \"services\" (e.g. administrative or police), \"at_home\" or \"other\")\n", " - Fjob - работа отца (\"teacher\", \"health\" care related, civil \"services\" (e.g. administrative or police), \"at_home\" or \"other\")\n", " - reason - причина выбора школы (близко к дому — \"home\", репутация школы — \"reputation\", \"course\" предпочтение некоторым предметам или \"other\")\n", " - guardian - опекун (\"mother\", \"father\" или \"other\")\n", " - traveltime - время от дома до школы (1 - меньше 15 мин., 2 - 15 до 30 мин., 3 - 30 мин. до 1 часа, или 4 - больше 1 часа)\n", " - studytime - количество часов обучения в неделю (1 - меньше 2 часов, 2 - от 2 до 5 часов, 3 - от 5 до 10 часов, или 4 - больше 10 часов)\n", " - failures - колисечтво ранее не сданных предметов (n if 1 <= n < 3, else 4)\n", " - schoolsup - дополнительные занятия (yes or no)\n", " - famsup - помощь от семьи при выполнении заданий (yes or no)\n", " - paid - дополнительные платные занятия (yes or no)\n", " - activities - внеклассная деятельность (yes or no)\n", " - nursery - посещал детский сад (yes or no)\n", " - higher - желание высшего образования (yes or no)\n", " - internet - домашний интернет (yes or no)\n", " - romantic - состоит в романтических отношениях (yes or no)\n", " - famrel - насколько хорошо отношения в семье (от 1 - очень плохие до 5 - превосходные)\n", " - freetime - наличие свободного времени после школы (от 1 - очень мало до 5 - очень много)\n", " - goout - гуляет с друзьями (от 1 - редко до 5 - очень часто)\n", " - Dalc - употребление алкоголя в будние дни (от 1 - очень редко до 5 - очень часто)\n", " - Walc - употребление алкоголя в выходные (от 1 - очень редко до 5 - очень часто)\n", " - health - текущее состояние здоровья (от 1 - очень плохое до 5 - очень хорошее)\n", " - absences - количество школьных пропусков (от 0 до 93)\n", "\n", "Признаки ниже связаны с курсом (математика/португальский)\n", " - G1 - оценка за первый семестр (от 0 до 20)\n", " - G2 - оценка за второй семестр (от 0 до 20)\n", " - [целевая переменная] G3 - итоговая оценка (от 0 до 20)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import scipy as sp\n", "import pylab as plt\n", "\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для начала загрузите данные. Обратите внимание, чтобы данные были загружены верно (был указан верный разделитель, а так же корректно отображались названия столбцов). Чтобы это проверить, а также посмотреть, что представляют из себя данные, можно вывести первые несколько строк загруженного датасета на экран." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Разделите признаки и целевую зависимость в две отдельные переменные *X* и *y*." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Как можно видеть (и как показали эксперименты ранее) в данных есть числовые признаки (например, *age*), а так же категориальные (*guardian*). Для начала поработает только с числовыми признаками. \n", "\n", "Создайте две новых матрицы с признаками: в первой будут только числовые признаки, во второй — все остальные. Для этого удобно воспользоваться методом датафрейма [select_dtypes](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.select_dtypes.html)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Для оценки качества выберете одну из метрик:\n", " - коэффициент детерминации [r2](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.r2_score.html)\n", " - [MAE](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_absolute_error.html)\n", " - [MSE](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mean_squared_error.html)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Теперь будем строить модели для предсказания, используя пока только числовые признаки. Вам нужно будет рассмотреть следующие модели:\n", " - линейную регрессию [LinearRegression](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html)\n", " - регуляризованную линейную регрессию — одну из моделей [Ridge](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html) или [Lasso](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Lasso.html)\n", " - случайный лес [RandomForest](http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestRegressor.html) со 100 деревьями\n", " - метод ближайших соседей [KNeighborsRegressor](http://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsRegressor.html)\n", " \n", "Для следующих моделей вам нужно подобрать оптимальные гиперпараметры с помощью 5-fold кросс-валидации:\n", " - коэффициент при регуляризаторе в случае Ridge и Lasso\n", " - максимальную глубину деревьев для RandomForest\n", " - количество соседей для KNeighborsRegressor\n", " \n", "Вы можете перебрать несколько (3-5) значений соответствующего параметра. Скорее всего вам удобно будет воспользоваться:\n", " - классом [KFold](http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.KFold.html) чтобы создать объект для кросс-валидации\n", " - классом [GridSearchCV](http://scikit-learn.org/stable/modules/generated/sklearn.grid_search.GridSearchCV.html) имеющим параметры:\n", " - *estimator* некоторая модель, например, *KNeighborsRegressor()*\n", " - *param_grid* — словарь с оптимизируемыми параметрыми, например, *{'n_neighbors': [1, 3, 5, 15]}*\n", " - *scoring* — название оптимизируемой метрики (*r2_score*, *mean_squared_error* либо *mean_absolute_error*) в зависимости от того, какую метрику вы выбрали\n", " - *cv* — схема кросс-валидации (здесь можно указать созданный ранее объект KFold)\n", " \n", " после создания объекта вам нужно вызвать метод *fit*, после чего у обученного объекта посмотреть поле *best\\_params\\_*, где будут сохранены оптимальные в данном случае параметры. [Пример использования](http://scikit-learn.org/stable/auto_examples/model_selection/grid_search_digits.html).\n", " \n", "**(4 балла)** Подберите оптимальные значения гиперпараметров для указанных выше моделей." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**(2 балла)** Теперь измерьте качество на кросс-валидации для каждой модели с оптимальными параметрами. Для этого удобно воспользоваться функцией [cross_val_score](http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.cross_val_score.html), имеющую параметры, аналогичные *GridSearchCV*." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**(1 балл)** Вернемся к отложенной матрице категориальных признаков. Так как алгоритмы не умеют работать со строковыми данными, преобразуйте их с помощью функции [get_dummies](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.get_dummies.html) в числовую матрицу, где значение каждого признака будет закодировано как бинарное. Сколько признаков теперь получилось? " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Объедините две матрицы: с числовыми признаками и закодированными категориальными в полную матрицу признаков. Для этого удобно воспользоваться функцией [concat](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.concat.html), указав первым аргументов массив датафреймов, а также *axis=1*." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**(1 балл)** Обучите модели с оптимальными параметрами из предыдущего пункта и измерьте качество на полной матрице признаков с помощью функции *cross\\_val\\_score*." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**(2 балла)** Ответьте на следующие вопросы:\n", " - какая из моделей имеет наилучшее качество в первом случае, а какая — во втором?\n", " - есть ли модели, для которых добавление категориальных признаков дало прирост в качестве?\n", " - какая из использованных моделей кажется вам наиболее сложной и почему?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**(1 дополнительный балл)** Обучите случайный лес на полной матрице признаков и найдите топ3 наиболее важных признаков. Можно ли дать интерпретацию почему эти признаки оказались наиболее информативными в рамках данной задачи?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "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.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }