Data Science - Машинное Обучение с нуля на Python

Data science, или наука о данных, набирает все большую популярность среди самых востребованных профессий современного рынка. Специалист в этой области должен обладать глубокими разносторонними знаниями, как теоретическими, так и практическими. К услугам начинающих аналитиков данных предлагаются инструменты автоматизированного характера с уже заложенным функционалом, как, например, мощное программное обеспечение Weka. Однако, многие data scientist-ы, предпочитая широту и манёвренность действий, создают собственные инструменты и пайплайны. Язык программирования Python как нельзя лучше подходит для этих целей. Возможности Python позволяют написать программу для задач машинного обучения как с чистого листа, так и с использованием различных библиотек и инструментов. О последних мы и поговорим.

Обработка больших данных с помощью библиотек Pandas, CSV и OpenPyXL

Чаще всего в задачах для бизнеса исходные данные предоставляются в формате .xlsx или .xlsm, однако многие предпочитают формат .csv (файлы, в которых каждая строка представлена полями, разделенными каким-либо знаком — обычно запятой или точкой с запятой).

Библиотека Pandas — один из самых популярных инструментов Python для работы с данными, она поддерживает различные текстовые, бинарные и sql форматы файлов, в том числе .xlsx, .xls и .csv. Для работы с файлами Excel Pandas использует модули xlrd и xlwt.

Модуль CSV содержит утилиты для работы исключительно с csv-файлами. Однако, детали нотации создания csv-файлов в разных программах могут различаться (как, например, в Excel), и модуль CSV позволяет корректно читать большинство различных реализаций .csv без необходимости учитывать, какой программой и как был сгенерирован файл.

OpenPyXL — это библиотека для работы исключительно с Excel-файлами, такими как .xlsx, .xlsm, .xltx, .xltm для версий Excel от 2010 года и новее. OpenPyXL содержит инструменты для чтения, записи и обработки данных указанных форматов, а также для построения графиков.

Разберем на примерах базовые возможности этих инструментов. Мы будем использовать данные с портала Kaggle об участниках Олимпийских игр за 120 лет.

Считываем данные

import pandas as pd

data = pd.read_excel("athlete_events2.xlsx")

или

data2 = pd.read_csv("athlete_events.csv")

Получим таблицу такого вида:

pandas

Обращаться к ячейками можно по индексу:

Pandas Python

Pandas

Или по названию столбца:

Pandas

Несколько строк в Pandas можно выделить через двоеточие:

Pandas

Теперь откроем файлы с помощью библиотек CSV и OpenPyXL:

import csv

with open('athlete_events.csv', 'r', newline='') as file:

data3 = csv.reader(file)

Однако, вывод при таком считывании придется делать обычным для Python способом, либо, например, подключать структуру data frame из Pandas. В нашем случае получаем длинный текст такого вида:

for row in data3:

    print(','.join(row))

Pandas

import openpyxl

open_data = openpyxl.load_workbook('athlete_events2.xlsx')

Переменная open_data содержит объект класса рабочей книги excel со всеми существующими листами. Метод open_data.get_sheet_names() возвращает названия листов, которые можно использовать в дальнейшем для обращения к данным. Наши данные представлены только на одном листе:

names = open_data.get_sheet_names ()

print(names)

Результат:

sheet = open_data.get_sheet_by_name('Лист1')

Посмотрим значение ячейки на пересечении 2-ого столбца и 5-ой строки:

print(sheet.cell(row=5, column=2).value)

Результат:

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

several = sheet[A1:C3]

for row in several:

    for cell in row:

        print(cell.value)

Pandas

Запишем извлечённые данные в файлы .xlsx и .csv.

Pandas

data2.to_csv("new_file1.csv", sep= ',', index=False, header=False)

data2.to_excel("new_file2.xlsx", index=False)

CVS

with open("new_file3.csv", "w", newline='') as file:

    writer = csv.writer(file, delimiter=';')

        for line in data3:

            writer.writerow(line)

OpenPyXL

open_data.save("new_file4.xlsx")

Matplotlib и Seaborn — Визуализация данных

Библиотеку Matplotlib написал Джон Хантер для создания различных графиков и работы с изображениями. Seaborn — как бы «надстройка» над Matplotlib, которая при всем функционале библиотеки Matplotlib предоставляет лучшую графику и большее количество возможностей её настройки.

Рассмотрим применение этих библиотек на выборке (8000 образцов) из датасета об участниках олимпиады.

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

import matplotlib.pyplot as plt

import numpy as np

num_bins = 10

n, bins, patches = plt.hist(data2["Age"], num_bins, normed=1, facecolor='blue', alpha=0.5)

plt.xlabel('Возраст')

plt.ylabel('Вероятность')

plt.title(r'Гистограмма распределения возраста спортсменов')

plt.show()

Matplotlib

И сделаем это же с помощью библиотеки Seaborn:

import seaborn as sns

data2.Age.values

sns.distplot(data2.Age.dropna())

Seaborn Python

Как видно из этого примера, код при использовании библиотеки Seaborn выглядит намного короче и лаконичнее, к тому же distplot содержит много параметров по умолчанию, один из которых — построение кривой распределения (синяя линия на последнем графике), в то время как в Matplotlib её необходимо задавать отдельно (что требует ещё пары строчек кода и импорта дополнительного модуля из библиотеки).

С другой стороны, Matplotlib дает большую манёвренность в плане стиля и надстроек над базовым графиком, поэтому возможности Matplotlib часто используются в совокупности с функциями модуля Seaborn.

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

sns.countplot(x=data2.Age, data=data2)

plt.xticks(rotation=-45)

plt.savefig("plot.png")

Matplotlib Seaborn Python

С помощью средств Matplotlib мы сделали график заданного размера (figsize), повернули значение возраста на 45 градусов и сохранили картинку на компьютер.

Машинное обучение в SciKit-Learn

SciKit-Learn — это свободно распространяемая библиотека для работы с методами машинного обучения на Python. Она содержит реализации методов классификации, регрессии и кластеризации, а также нейронных сетей. SciKit предоставляет широкий набор инструментов для решения проблемы размерности данных, сравнения моделей машинного обучения и их производительности и для извлечения важных признаков.

Рассмотрим реализацию линейной регрессии, например, для проверки гипотезы о том, что вес спортсмена и его возраст взаимосвязаны.

from sklearn.linear_model import LinearRegression

import numpy as np

После импортирования необходимых библиотек избавимся от отсутствующих значений типа NA самым простым (но не самым лучшим) способом: удалим все строки, в которых в каком-либо столбце присутствуют NA:

data2 = data2.dropna(axis=0)

Зададим переменные для модели, зависимость которых мы собираемся исследовать:

x = np.array(data2.Age.values)

y = np.array(data2.Weight.values)

x = x.reshape((-1, 1))

Построим модель:

model = LinearRegression()

model.fit(x, y)

model = LinearRegression().fit(x, y)

И подсчитаем коэффициент линейной регрессии, чтобы оценить эффективность модели:

r_sq = model.score(x, y)

print('coefficient of determination:', r_sq)

Результат:

coefficient of determination: 0.024385595989105727

Коэффициент детерминации (или R2) очень низкий (для приемлемой модели он должен быть не менее 0,5), а значит, либо предобработка данных не была проведена должным образом (что верно, так как мы не учитывали разброс данных и другие характеристики), либо метод линейной регрессии в этом случае не подходит, и возраст и вес спортсменов никак не связаны (что тоже возможно).

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

y_pred = model.predict(x)

print('predicted response:', y_pred, sep='\n')

SciKit-Learn

Генераторы и Lambda-функции — «фишки» языка Python

Запутанные на первый взгляд, два этих инструмента Python полезны в любой из областей программирования, в том числе и в data science. Новички изучают их на курсах программирования на Python, например, на «Курсе по Python для веб-разработки полного цикла» в Skillfactory, но недооценивают лаконичность и эффективность этих методов.

Каждый, кто хоть раз пробовал запрограммировать последовательность действий, знает, что для этого нужно использовать цикл for или while.

Например, привычная реализация заполнения списка символами из строки на Python будет выглядеть так:

string = "123456erert,42,;432EkRRPPEW254"

spisok = []

for el in string:

    y = el*2

    spisok.append(y)

print(spisok)

Результат:

['11', '22', '33', '44', '55', '66', 'ee', 'rr', 'ee', 'rr', 'tt', ',,', '44', '22', ',,', ';;', '44', '33', '22', 'EE', 'kk', 'RR', 'RR', 'PP', 'PP', 'EE', 'WW', '22', '55', '44']

Генераторы позволяют записать данную операцию в одну строчку:

spisok = [el*2 for el in string]

print(spisok)

Результат:

['11', '22', '33', '44', '55', '66', 'ee', 'rr', 'ee', 'rr', 'tt', ',,', '44', '22', ',,', ';;', '44', '33', '22', 'EE', 'kk', 'RR', 'RR', 'PP', 'PP', 'EE', 'WW', '22', '55', '44']

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

Lambda-функции применяются с той же целью — сократить код — для функций. В случае, если функция содержит одну операцию или одно общее выражение, lambda-конструкция позволяет создать функцию без создания функции. Выглядит запутанно, поэтому разберём простейший пример. Допустим, мы хотим посчитать количество элементов списка:

def elements(list1):

    return len(list1)

print(elements(spisok))

Результат:

Теперь сделаем то же самое с помощью lambda:

elements = lambda x: len(x)

print(elements(spisok))

Результат:

Мы рассмотрели только 8 средств языка Python: и профессиональные библиотеки, и инструменты, которые пригодятся любому программисту для работы с данными. Для знакомства с широтой возможностей языка Python вы можете прослушать любой из курсов SkillFactory и углубиться в интересное для вас направление, если что-то покажется особенно интересным.

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.

E-mail: vasile.buldumac@ati.utm.md

Образование
Universitatea Tehnică a Moldovei (utm.md)

  • 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
  • 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»