{ "cells": [ { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "from scipy.sparse import csr_matrix\n", "import sklearn\n", "from sklearn.datasets import fetch_20newsgroups\n", "from sklearn.linear_model import LogisticRegression\n", "from sklearn.metrics import roc_auc_score\n", "from sklearn.cross_validation import train_test_split\n", "from sklearn.feature_extraction.text import TfidfTransformer, CountVectorizer, HashingVectorizer" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Работа с категориальными признками" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Все эксперименты в этой лабораторной работе предлагается проводить на данных соревнования Amazon Employee Access Challenge: https://www.kaggle.com/c/amazon-employee-access-challenge\n", "\n", "В данной задаче предлагается предсказать, будет ли одобрен запрос сотрудника на получение доступа к тому или иному ресурсу. Все признаки являются категориальными.\n", "\n", "Данные доступны по ссылке https://www.dropbox.com/s/q6fbs1vvhd5kvek/amazon.csv\n", "\n", "Для оценки качества используется ROC-AUC" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ACTIONRESOURCEMGR_IDROLE_ROLLUP_1ROLE_ROLLUP_2ROLE_DEPTNAMEROLE_TITLEROLE_FAMILY_DESCROLE_FAMILYROLE_CODE
013935385475117961118300123472117905117906290919117908
11171831540117961118343123125118536118536308574118539
21367241445711821911822011788411787926795219721117880
31361355396117961118343119993118321240983290919118322
4142680590511792911793011956911932312393219793119325
\n", "
" ], "text/plain": [ " ACTION RESOURCE MGR_ID ROLE_ROLLUP_1 ROLE_ROLLUP_2 ROLE_DEPTNAME \\\n", "0 1 39353 85475 117961 118300 123472 \n", "1 1 17183 1540 117961 118343 123125 \n", "2 1 36724 14457 118219 118220 117884 \n", "3 1 36135 5396 117961 118343 119993 \n", "4 1 42680 5905 117929 117930 119569 \n", "\n", " ROLE_TITLE ROLE_FAMILY_DESC ROLE_FAMILY ROLE_CODE \n", "0 117905 117906 290919 117908 \n", "1 118536 118536 308574 118539 \n", "2 117879 267952 19721 117880 \n", "3 118321 240983 290919 118322 \n", "4 119323 123932 19793 119325 " ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = pd.read_csv('amazon.csv')\n", "data.head()" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(32769, 10)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data.shape" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true }, "outputs": [], "source": [ "X_train, X_test, y_train, y_test = train_test_split(data.iloc[:, 1:], data.iloc[:, 0],\n", " test_size=0.3, random_state=241)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Подзадача 1.0 (Опционально)\n", "Воспользуйтесь любым известным вам методом классификации для предсказания на данных без предобработки. Какое максимальное качество (roc_auc_score) удаётся получить?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Подзадача 1.1\n", "Для каждого признака посчитайте число уникальных значений в датасете. Посчитайте также долю объектов каждого класса.\n", "\n", "Считайте статистики по оригинальному датасету, а не только по train части. \n", "\n", "Сохраните результат в dict" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Подзадача 1.2\n", "Напишите функцию one_hot_decode(), которая преобразовывает dataframe с категориальными признаками в sparse-матрицу (scipy.sparse.csr_matrix) с one_hot представлениями для всех признаков.\n", "\n", "Для создания разреженной матрицы необходимо воспользоваться наиболее эффективным конструктором csr_matrix, нигде не храня полную матрицу." ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[42 19]\n", " [17 0]]\n" ] } ], "source": [ "def one_hot_decode(X, vector_size_dict=None):\n", " return csr_matrix(([17, 19, 42], ([1, 0, 0], [0, 1, 0])))\n", "\n", "print(one_hot_decode(data.iloc[:, 1:]).todense())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Позадача 1.3\n", "Обучите логистическую регрессию на получившихся признаках. Попробуйте l1 и l2 резугялирзацию. Постройте график зависимости качества на обучающей и тестовой выборках в зависимости от значения коэффициента регуляризации. (Попробуйте значения от 0.001 до 1000 по лог-шкале) Какое наилучшее качество удалось получить на отложенной выборке?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Позадача 1.4 (Бонус)\n", "Напишите функцию feature_hashing_decode(), которая преобразовывает dataframe с категориальными признаками в sparse-матрицу (scipy.sparse.csr_matrix) с one-hot представлениями для всех признаков, где индекс единицы в one-hot представлении задаётся как хэш-функция от значения категориального признака по модулю $h$, где $h$ – индивидуально для каждого признака и задаётся словарём vector_size_dict." ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[42 19]\n", " [17 0]]\n" ] } ], "source": [ "def feature_hashing_decode(X, vector_size_dict=None):\n", " return csr_matrix(([17, 19, 42], ([1, 0, 0], [0, 1, 0])))\n", "\n", "print(feature_hashing_decode(data.iloc[:, 1:]).todense())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. Работа с текстами\n", "20 newsgroups – задача рубрикации текстов. \n", "\n", "Смысл в том, чтобы научиться по тексту новостного объвления предсказывать его рубрику. \n", "\n", "Информация о наличии или отсутствии тех или иных слов в тексте является информативным признаком о его рубрике." ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [], "source": [ "data = fetch_20newsgroups(remove=('headers', 'footers', 'quotes'))\n", "X_train, y_train = data['data'], data['target']\n", "data = fetch_20newsgroups(remove=('headers', 'footers', 'quotes'), subset='test')\n", "X_test, y_test = data['data'], data['target']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Рубрики" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['alt.atheism',\n", " 'comp.graphics',\n", " 'comp.os.ms-windows.misc',\n", " 'comp.sys.ibm.pc.hardware',\n", " 'comp.sys.mac.hardware',\n", " 'comp.windows.x',\n", " 'misc.forsale',\n", " 'rec.autos',\n", " 'rec.motorcycles',\n", " 'rec.sport.baseball',\n", " 'rec.sport.hockey',\n", " 'sci.crypt',\n", " 'sci.electronics',\n", " 'sci.med',\n", " 'sci.space',\n", " 'soc.religion.christian',\n", " 'talk.politics.guns',\n", " 'talk.politics.mideast',\n", " 'talk.politics.misc',\n", " 'talk.religion.misc']" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data['target_names']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Пример пары объект-рубрика в обучающей выборке" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sci.crypt\n", "----------\n", "\n", "Where? I honestly didn't see any...\n", "\n", "\n", "I disagree, if for no other reason than that there are already other \n", "standards in place. Besides, even if they restrict encryption on the NREN, \n", "who cares? Most of the Internet is commercial anyway. The NREN is only for \n", "geovernment and university research (read the proposals--it's a \"data \n", "superhighway\" for Cray users, not anything having to do with the Internet).\n", "\n" ] } ], "source": [ "object_idx = 117\n", "print(data['target_names'][y[object_idx]])\n", "print('----------')\n", "print(X[object_idx])" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "### Задание №2.1\n", "\n", "1. Перевести во всех документах все буквы в нижний регистр. Заменить во всех документах символы, не являющиеся буквами и цифрами, на пробелы. Полезные функции: .lower, .isalnum.\n", "2. Разбить каждый документ на термы по пробельным символам (пробелы, переносы строки). Полезная функция: .split()\n", "3. Преобразовать датасет в разреженную матрицу scipy.sparse.csr_matrix, где значение x в позиции (i, j) означает, что в документе i слово j встретилось x раз. (Воспользуйтесь sklearn.feature_extraction.text.CountVectorizer)\n", "5. Произвести tf-idf преобразование датасета при помощи sklearn.feature_extraction.text.TfidfTransformer. Используйте параметры по умолчанию.\n", "6. Обучите логистическую регрессию на получившихся признаках. Подберите коэффициент регуляризации по значению ошибки на тестовой выборке." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Задание № 2.2 (Бонус)\n", "\n", "Попробуйте улучшить качество с помощью каких-нибудь ещё признаков, посчитанных по данным. (Попробуйте, например, добавить усреднённые word2vec представления новостных заголовков)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "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.11" } }, "nbformat": 4, "nbformat_minor": 0 }