Free

Машинное обучение доступным языком

Text
Mark as finished
Font:Smaller АаLarger Aa

Изображения

Здесь единицей является отдельная картинка. Видео рассматривается как набор картинок.


Датасет рукописных цифр

Перед дата-сайентистами часто встает вопрос: где взять данные?

Студентам проще: у некоторых обширных библиотек вроде Scikit-learn встречаются собственные встроенные датасеты, прекрасно подходящие для обучения:

from sklearn.datasets import load_digits

digits = load_digits()

Помимо таких встроенных коллекций, данные предоставляют бесплатно еще и ресурсы вроде kaggle.com.

А вот на рабочей ниве требования к информации куда специфичнее. Порой проще и лучше собрать свой набор, и в таком случае мы обращаемся к инструментам ETL.

ETL



(extract, transform, load – извлечь, преобразовать и загрузить) группа процессов, происходящих при переносе данных из нескольких систем в одно хранилище.

Если у вас есть данные из нескольких источников, вам необходимо:

• Извлекать данные из исходного источника

• Преобразовывать информацию путем очистки, объединения и других способов подготовки

• Загружать результат в целевое хранилище

Как правило, один инструмент ETL выполняет все три шага. Пожалуй, самый популярный сегодня представитель такого программного обеспечения – это Hadoop.

ETL уходит своими корнями в 1970-е годы к появлению централизованных хранилищ данных. Но только в конце 1980-х и начале 1990-х годов, когда они заняли центральное место, мир ощутил потребность в специализированных загрузочных инструментах. Первым пользователям нужен был способ извлекать информацию из разрозненных систем, преобразовывать ее в целевой формат и загружать в конечное место хранения. Первые инструменты ETL были примитивными, и объем данных, которые они обрабатывали, был скромным по сегодняшним меркам.

По мере роста объема данных росли и хранилища данных, а программные инструменты ETL множились и становились все более сложными. Но до конца 20-го века хранение и преобразование данных осуществлялось в основном в локальных хранилищах. Однако произошло нечто, навсегда изменившее наш взгляд на хранение и обработку.

Облачные вычисления

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

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

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

Преобразования и моделирование данных часто выполняются с помощью SQL – языка запросов к базе данных.

Конечная точка ETL – хранилище данных (DWH).

DWH



(data warehouse – хранилище данных) предназначено исключительно для выполнения запросов и часто содержит большие объемы исторических данных. Данные в хранилище обычно поступают из широкого круга источников, таких как:

• Логи приложений

• Сведения, собираемые с форм на сайте

• Записи различных устройств, вроде видеокамер и датчиков температуры

Хранилище объединяет большие объемы данных из нескольких источников. Это позволяет генерировать ценные инсайты2 и улучшать процесс принятия решений. С ростом объема и качества DWH становится бесценным объектом для бизнес-аналитики. Типичное хранилище данных часто включает следующие элементы:

• Реляционная база данных

• ПО для ETL

• Инструменты анализа и визуализации

• Модели машинного обучения

К популярным хранилищам можно отнести Amazon Redshift, Google BigQuery и Greenplum.

Стоит отличать DWH от так называемого озера данных (data lake). Хранилище содержит очищенные и структурированные данные, готовые к анализу на основе предопределенных потребностей бизнеса. В озере же все содержится в необработанном, неструктурированном виде.

Когда команда ML получает доступ к такому хранилищу, то предваряет моделирование целой серией действий – разведочным анализом данных (EDA).

EDA



(exploratory data analysis – разведочный анализ данных) предварительное исследование датасета с целью определения его основных характеристик, взаимосвязей между признаками, а также сужения набора методов, используемых для создания модели.

Давайте рассмотрим, на какие этапы разбивают EDA. Для этого мы используем данные3 банка, который продает кредитные продукты своим клиентам. Возьмет ли клиент кредит или нет?

Мы располагаем обширным набором переменных (столбцов):



Это не сам датасет, а только описание столбцов


Столбец Y назван так неслучайно: это общепринятое обозначение целевой переменной (target variable). Изучив 40 тысяч записей о клиентах, модель автоматически сможет предсказывать, возьмет новый клиент кредит или не возьмет.

Довольно увесистый датасет: записей в нем более 40 тысяч. Для начала4 импортируем датасет и посмотрим на "шапку". С помощью метода head() мы отобразим шапку датафрейма и первые пять записей:

df = pd.read_csv('https://www.dropbox.com/s/62xm9ymoaunnfg6/bank-full.csv?dl=1', sep=';')

df.head()

Параметр sep используется, чтобы задать нестандартный разделитель данных по столбцам, в данном случае – точку с запятой.



Все столбцы мы отображать здесь, конечно, не будем

Удаление дубликатов

(duplicates removing) Повторяющиеся записи искажают статистические показатели. Всего несколько повторов – и среднее значение столбца сместится в их пользу. Дубликаты также снижают качество обучения модели. Для начала уточним, сколько у нас строк с помощью df.shape. Затем удалим повторы с помощью drop_duplicates() и обновим данные о размере данных:

print(df.shape)

df.drop_duplicates(inplace=True)

print(df.shape)

Библиотека pandas вообще сопровождает любителей и профессионалов на каждом шагу, так что у некоторых ее компонентов параметры одинаковые. Чтобы удалить повторы “на месте”, без излишнего перекопирования датафрейма, дополняем drop_duplicates() параметром inplace, равным True.

Ячейка выдает, что удалила 41188 – 41176 = 12 дубликатов:

(41188, 21)

(41176, 21)

Хоть число и небольшое, все же качество набора мы повысили.

Обработка пропусков

(omission handling) Если пропусков у признака-столбца слишком много (более 70%), такой признак удаляют. Проверим, насколько разрежены наши признаки:

df.isnull().mean() * 100

Метод isnull() пройдется по каждой ячейке каждого столбца и определит, кто пуст, а кто нет. Метод mean() определит концентрацию пропусков в каждом столбце. На 100 мы умножаем, чтобы получить значение в процентах:

Возраст 0.000000

Работа 0.801438

Семейный статус 0.194288

Образование 4.201477

Кредитный дефолт 0.000000

Ипотека 0.000000

Займ 0.000000

Контакт 0.000000

Месяц 0.000000

День недели 0.000000

Длительность 0.000000

Кампания 0.000000

День 96.320672

Предыдущий контакт 0.000000

Доходность 0.000000

Колебание уровня безработицы 0.000000

Индекс потребительских цен 0.000000

Индекс потребительской уверенности 0.000000

Европейская межбанковская ставка 0.000000

Количество сотрудников в компании 0.000000

y 0.000000

Среди всех признаков слишком много пропусков оказалось у фактора “День” (более 96%). Он подлежит удалению с помощью drop():

df = df.drop(columns=['День'])

Разберемся для начала с категориальными переменными, объединив их в один вектор. Метод pandas.unique() выделит уникальные значения из всего перечня столбцов column_values. pandas принято сокращать псевдонимом до pd.

column_values = df[['Работа', 'Семейный статус', 'Образование', 'Контакт', 'Месяц', 'День недели', 'Доходность']].values.ravel()

 

unique_values = pd.unique(column_values)

print(unique_values)

Список получится совсем уж нелогичный, но это здесь не столь важно. Мы лишь ищем способы обозначения пропусков. Они обозначаются словом "Неизвестно":

['Самозанятый', 'Не женат / не замужем', 'Университетская степень', 'Городской телефон', 'Октябрь', 'Пятница', 'Отсутствует', 'Предприниматель', 'Женат / замужем', 'Голубой воротничок', 'Базовое (9 классов)', 'Менеджер',

'Высшая школа', 'Базовое (4 класса)', 'Техник', 'Профессиональный курс', 'Разведен(-а)', 'Неизвестно', 'Сотовый телефон', 'Август', 'Понедельник', 'Студент', 'Домохозяйка', 'Обслуживающий персонал', 'Базовое (6 классов)',

'Пенсионер', 'Четверг', 'Вторник', 'Не присутствует', 'Июль', 'Среда', 'Июнь',

'Неграмотный', 'Май', 'Ноябрь', 'Присутствует', 'Cамозанятый', 'Декабрь', 'Март', 'Апрель', 'Сентябрь']

Процесс обработки пропусков можно сократить с помощью sklearn.impute.SimpleImputer. Мы выбираем все категориальные переменные и применяем стратегию "вставить вместо пропуска самое распространенное значение":

imputer = SimpleImputer(missing_values = np.nan, strategy = 'most_frequent')

categorical_columns = ["Работа", "Семейный статус", "Образование", "Месяц", "День недели", "Доходность"]

df[categorical_columns] = imputer.fit_transform(df[categorical_columns].values)

Признаки, принадлежащие к булевому типу данных, обрабатываются алгоритмом тем же образом:

imputer = SimpleImputer(missing_values = np.nan, strategy = 'most_frequent')

boolean_columns = ["Кредитный дефолт", "Ипотека", "Займ"]

df[boolean_columns] = imputer.fit_transform(df[boolean_columns].values)

Целевую переменную y мы не обрабатываем (если в этом столбце есть пропуски, их стоит удалить).

Подобным образом заполняются пустоты в числовых переменных, только стратегия теперь – "вставить среднее значение":

imputer = SimpleImputer(missing_values = np.nan, strategy = 'mean')

numeric_columns = ["Возраст", "Длительность", "Кампания", 'Предыдущий контакт', "Колебание уровня безработицы", "Индекс потребительских цен", "Индекс потребительской уверенности", "Европейская межбанковская ставка", "Количество сотрудников в компании"]

2Решение задачи
3Исходная англоязычная версия датасета: kaggle.com/datasets/volodymyrgavrysh/bank-marketing-campaigns-dataset
4Здесь и далее ячейка с импортом библиотек будет пропущена. С полной версией кода можно ознакомиться в конце главы по QR-коду со ссылкой.