Руководство для начинающих/ ML Boot Camp. Часть 1

Полный туториал доступен на нашем сайте
Полный туториал доступен на нашем сайте

«Поехали!»

Обычно в задаче анализа данных имеется некоторая прямоугольная таблица. Ее строки соответствуют объектам, а столбцы – признакам этих объектов. Объекты также называются наблюдениями или примерами (samples), а признаки – атрибутами (features).

Признаки бывают количественными (как, например, доход в рублях или рост в сантиметрах и т.д.) или категориальными (как, например, марка автомобиля, модель телефона и т.д.).

Один из признаков (столбцов) выделен. Этот признак называется ответом. Остальные признаки – входные. Требуется по имеющейся таблице научиться по новому объекту, которого нет в таблице, но для которого известны значения входных признаков, по возможности с небольшой ошибкой предсказывать значение выделенного признака (ответа).

Если ответ количественный, то задача называется задачей восстановления регрессии. Если ответ категориальный, то задача называется задачей классификации.

Здесь мы будем предполагать, что читатель знаком с python. Для решения задачи анализа данных воспользуемся библиотеками numpy, pandas и scikit-learn. Библиотека numpy содержит реализации многомерных массивов и алгоритмов линейной алгебры. Библиотека pandas предоставляет широкий спектр функций по обработке табличных данных. Библиотека scikit-learn реализует множество алгоритмов машинного обучения. Кроме того, нам понадобится библиотека matplotlib для научной визуализации.

Наиболее простой способ получить все требуемые библиотеки в python – установить дистрибутив anaconda. Приведенный ниже код тестировался на дистрибутиве anaconda 2.2.0 (с python версии 2.7). Далее будем предполагать, что все требующееся программное обеспечение установлено.

Вначале подключим библиотеки:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('ggplot')
%matplotlib inline

Загружаем данные

В качестве примера рассмотрим задачу определения кредитной платежеспособности (кредитного скрининга). Пусть имеются данные о клиентах, обратившихся за кредитом. Здесь объектами являются клиенты, а признаками могут являться их пол, уровень дохода, образование, информация о том, имеется или отсутствует у них положительная кредитная история и т.д.

В качестве выделенного признака (ответа) выступает информация о том, вернул ли клиент кредит в банк или нет. По этим данным требуется научиться предсказывать, вернет ли кредит новый клиент, обратившийся в банк.

Таким образом, речь идет о задаче классификации: требуется определить, какому классу: положительному (кредит будет возвращен) или отрицательному (кредит не будет возвращен) – принадлежит клиент.

В качестве модельных данных возьмем Credit Approval Data Set из коллекции UCI Machine Learning Repository.

Данные имеют формат csv и их можно скачать по указанному ниже адресу:

url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/credit-screening/crx.data'
data = pd.read_csv(url, header=None, na_values='?')

Параметр header = None означает, что таблица не содержит заголовка (т.е. не содержит названий столбцов), а na_values = '?' означает, что данные содержат пропущенные значения, обозначенные символом ?.

Заметим, что данные можно загрузить вручную с сайта, а затем воспользоваться командой:

data = pd.read_csv('путь/crx.data', header=None, na_values='?')

Итак, мы загрузили данные в таблицу data. Объект data имеет тип DataFrame – это основной тип данных в библиотеке pandas, предназначенный для представления табличных данных.

Анализируем данные

Данные загружены. Попытаемся вначале их качественно проанализировать.

Узнаем размеры таблицы:

data.shape
(690, 16)

Итак, таблица содержит 690 строк (объектов) и 16 столбцов (признаков), включая выходной (целевой) признак.

Мы можем посмотреть на несколько первых и несколько последних строк этой таблицы, чтобы получить представление об имеющихся данных:

data.head()
Руководство для начинающих/ ML Boot Camp. Часть 1, image #2
data.tail()
Руководство для начинающих/ ML Boot Camp. Часть 1, image #3

Строки таблицы пронумерованы числами от 0 до 689. Столбцы не имеют каких-либо осмысленных имен и тоже просто пронумерованы.

Согласно описанию рассматриваемой задачи данные содержат информацию о клиентах, запрашивающих кредит. Для сохранения конфиденциальности данные обезличены, все значения категориальных признаков заменены символами, a числовые признаки приведены к другому масштабу. Последний столбец содержит символы + и -, соответствующие тому, вернул клиент кредит или нет.

Для удобства зададим столбцам имена:

data.columns = ['A' + str(i) for i in range(1, 16)] + ['class']
data.head()
Руководство для начинающих/ ML Boot Camp. Часть 1, image #4

К элементам таблицы можно обращаться, например, так:

data['A5'][687]
'p'

Обратите внимание на порядок следования имен (или номеров) строк и столбцов: вначале в квадратных сокбках указывается имя столбца, а затем – строки. Дело в том, что data['A5'] – это весь столбец A5, поэтому data['A5'][687]– 687-й (при нумерации начиная с 0) элемент этого столбца.

Можно обращаться и по-другому:

data.at[687, 'A5']
'p'

С помощью метода describe() получим некоторую сводную информацию по всей таблице. По умолчанию будет выдана информация только для количественных признаков. Это общее их количество (count), среднее значение (mean), стандартное отклонение (std), минимальное (min), макcимальное (max) значения, медиана (50%) и значения нижнего (25%) и верхнего (75%) квартилей:

data.describe()
Руководство для начинающих/ ML Boot Camp. Часть 1, image #5

Заметим, что количество элементов в столбцах A2, A14 меньше общего количества объектов (690), что говорит о том, что эти столбцы содержат пропущенные значения.

Выделим числовые и категориальные признаки:

categorical_columns = [c for c in data.columns if data[c].dtype.name == 'object']
numerical_columns   = [c for c in data.columns if data[c].dtype.name != 'object']
print categorical_columns
print numerical_columns
['A1', 'A4', 'A5', 'A6', 'A7', 'A9', 'A10', 'A12', 'A13', 'class']
['A2', 'A3', 'A8', 'A11', 'A14', 'A15']

Теперь мы можем получить некоторую общую информацию по категориальным признакам:

data[categorical_columns].describe()
Руководство для начинающих/ ML Boot Camp. Часть 1, image #6

В таблице для каждого категориального признака приведено общее число заполненных ячеек (count), количество значений, которые принимает данный признак (unique), самое популярное (часто встречающееся) значение этого признака (top) и количество объектов, в которых встречается самое частое значение данного признака (freq).

Вот немного другой способ получить ту же информацию:

data.describe(include=[object])
Руководство для начинающих/ ML Boot Camp. Часть 1, image #7

Определить полный перечень значений категориальных признаков можно, например, так:

for c in categorical_columns:
    print data[c].unique()
['b' 'a' nan]
['u' 'y' nan 'l']
['g' 'p' nan 'gg']
['w' 'q' 'm' 'r' 'cc' 'k' 'c' 'd' 'x' 'i' 'e' 'aa' 'ff' 'j' nan]
['v' 'h' 'bb' 'ff' 'j' 'z' nan 'o' 'dd' 'n']
['t' 'f']
['t' 'f']
['f' 't']
['g' 's' 'p']
['+' '-']

Здесь nan означают пропущенные значения.

Функция scatter_matrix из модуля pandas.tools.plotting позволяет построить для каждой количественной переменной гистограмму, а для каждой пары таких переменных – диаграмму рассеяния:

from pandas.tools.plotting import scatter_matrix
scatter_matrix(data, alpha=0.05, figsize=(10, 10));
Руководство для начинающих/ ML Boot Camp. Часть 1, image #8

Из построенных диаграмм видно, что признаки не сильно коррелируют между собой, что впрочем можно также легко установить, посмотрев на корреляционную матрицу. Все ее недиагональные значения по модулю не превосходят 0.4:

data.corr()
Руководство для начинающих/ ML Boot Camp. Часть 1, image #9

Можно выбрать любую пару признаков и нарисовать диаграмму рассеяния для этой пары признаков, изображая точки, соответствующие объектам из разных классов разным цветом: + – красный, - – синий.

Например, для пары признаков A2, A11 получаем следующую диаграмму:

col1 = 'A2'
col2 = 'A11'

plt.figure(figsize=(10, 6))

plt.scatter(data[col1][data['class'] == '+'],
            data[col2][data['class'] == '+'],
            alpha=0.75,
            color='red',
            label='+')

plt.scatter(data[col1][data['class'] == '-'],
            data[col2][data['class'] == '-'],
            alpha=0.75,
            color='blue',
            label='-')

plt.xlabel(col1)
plt.ylabel(col2)
plt.legend(loc='best');
Руководство для начинающих/ ML Boot Camp. Часть 1, image #10

Из диаграммы, в частности, видно, что признак A11 является существенным: как правило, красные точки имеют большое значение этого признака, а синие – маленькое. Иными словами, визуально наблюдается хорошая корреляция между признаками A11 и class. Признак A2, напротив, несет гораздо меньше информации о принадлежности объекта интересующему нас классу.

Вы можете сами попробовать изобразить такие диаграммы рассеяния для других пар признаков и проанализировать их значимость.

Алгоритмы машинного обучения из библиотеки scikit-learn не работают напрямую с категориальными признаками и данными, в которых имеются пропущенные значения. Поэтому в следующей статье подготовим наши данные.

Полный туториал доступен на нашем сайте

Сейчас проходит чемпионат ML Boot Camp VI «Прогноз отклика аудитории на интернет-опрос»!

Соревнование пройдёт с 25 июня по 25 июля 2018.

Регистрируйтесь на нашем портале и поборитесь за ценные призы:

  • Toп1: Apple MacBook Pro 13
  • Toп2: Apple MacBook Air 13
  • Toп3: Western Digital My Cloud Mirror
  • Toп4-5-6: Western Digital My Passport 4 TB

Как и всегда, топ-50 получат майки с символикой чемпионата, а участники с наиболее интересными решениями будут приглашены на собеседование в Mail.Ru Group на позиции Data Scientists.

Подробнее о чемпионате вы можете прочитать здесь.

Желаем удачи!

96 views·5 shares