Этот пост - первая из серии статей по машинному обучению, которую я написал, чтобы поделиться / обобщить то, что я узнал. Я предполагаю, что вы знакомы с языком программирования Python и средой Jupyter-notebook. Вы можете установить библиотеки, которые мы будем использовать в проектах, набрав в терминале формат «pip install libraryname». Блокноты в моем репозитории GitHub пока только на турецком языке, но если вы последуете за блокнотом с этой статьей Medium, я думаю, у вас не возникнет проблем.

Если вы не турок, пропустите этот абзац.

Бу yazı, öğrendiklerimi paylaşmak / pekiştirmek amacıyla kaleme aldığım Машинное обучение yazı dizisinin ilkidir. Python programlama diline ve Jupyter-notebook ortamına aşinalığınız olduğunu varsayarak anlatıyorum. Projeler içerisinde kullanacağımız kütüphaneleri terminalinizden «pip install kutuphaneadi» formatında yazarak yükleyebilirsiniz.

Yazının Türkçe versiyonu için: Ссылка

Что такое машинное обучение?

Мы можем просто определить это как предоставление компьютерам возможности принимать решения на основе данных. При этом мы форматируем данные соответствующим образом и передаем их в качестве входных данных модели / алгоритму, который будет выполнять процесс обучения. Таким образом, если у нас достаточно данных, мы можем решить некоторые сложные проблемы, не кодируя их шаг за шагом.

Например:

* Как определить, является ли письмо спамом
* Категоризация содержания Википедии по темам

Они являются примером проблем с машинным обучением. Машинное обучение в основном делится на три:

Обучение с учителем: учится делать выводы на основе данных с тегами.

Неконтролируемое обучение: учится делать выводы на основе немаркированных данных.

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

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

Обучение с учителем

Он основан на логике прогнозирования целевого свойства, которое не задается путем вывода из ряда входных свойств. Он имеет два подтипа: классификация и регрессия.

Классификация: целевая переменная состоит из категорий.

Регрессия: целевая переменная - это непрерывный тип данных, который нельзя разделить на категории. Например, когда вы разрабатываете регрессионную модель, которая оценивает стоимость дома, целевая переменная изменяется динамически в соответствии с функциями, которые вы предоставляете в качестве входных данных, поэтому ее нельзя классифицировать.

До сих пор можно увидеть термины с разными названиями в разных источниках. Если мы дадим вам краткую информацию для ознакомления,

Свойства = переменные-предикторы = независимые переменные

Целевая переменная = зависимая переменная = переменная ответа

Здесь вы видите четыре переменных-предиктора и одну целевую переменную, которую модель прогнозирует, изучая эти переменные. Вы можете создать приложение, которое классифицирует цветок, которому принадлежит фотография, в соответствии с данными о длине и ширине лепестков и чашелистиков цветов в наборе данных. Этот набор данных встроен в библиотеку scikit-learn, очень эффективную библиотеку Python, которую мы также будем использовать. Чтобы позвонить, просто запустите команды

from sklearn import datasets
iris = datasets.load_iris()

в среде Jupyter Notebook. Между прочим, я считаю документацию библиотеки scikit-learn неплохой. Если вы хотите изучить другие встроенные наборы данных, вы можете изучить наборы данных scikit-learn.

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

Начнем с включения наших необходимых библиотек для очистки, обработки и визуализации данных.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

Numpy: NumPy (Numerical Python) - математическая библиотека, которая позволяет нам быстро выполнять научные вычисления.

Matplotlib: это базовая библиотека Python, которую мы будем использовать для визуализации данных.

Seaborn: это библиотека визуализации статистических данных на основе Matplotlib, преимущества визуализации данных мы увидим в следующем разделе.

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

df = pd.read_csv('house-votes-84.data')

Я получил набор данных отсюда. Этот кластер содержит протоколы голосования на сессии Конгресса США 1984 года. Мы пытаемся угадать, к какой партии принадлежат члены партии, исходя из того, к какому заголовку они голосуют да или нет, демократ или республиканец.

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

Мы включили библиотеку Pandas с сокращением pd. Вам не обязательно делать это таким образом, вы не можете использовать какие-либо сокращения или включать другие сокращения, но полезно соблюдать глобальные шаблоны использования (в дополнение к этим типам стандартов есть также некоторые стандарты, которые вы должны соблюдать. будьте осторожны при написании кода. Эти правила известны как стандарты PEP-8, и если вы используете IDE, ваша IDE поможет вам напишите свой код в соответствии с этими стандартами. Я напишу об этом более подробную статью. Продолжаем.)

EDA - Исследовательский анализ данных

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

Числовой EDA

Это подход к числовому обобщению данных. Для этого мы используем несколько методов панд.

df.info()

df.info () - один из них, он позволяет нам получить обзор данных. Здесь мы можем увидеть названия функций, сколько строк и столбцов у нас есть в наборе данных. У нас есть набор данных из 435 строк и 17 столбцов. Мы будем использовать 16 переменных в этом наборе в качестве предикторов и 1 переменную («party») в качестве целевой переменной. Мы видим, что все данные 435x17 не равны нулю, что важно, потому что библиотеки, такие как numpy, pandas, scikit-learn, должны быть ненулевыми и одного типа для библиотек, таких как numpy, pandas, scikit-learn, для правильной работы .

df.describe()

df.describe () предоставляет еще одно краткое изложение общей информации, которую мы получаем вместе с info. Например, сколько каждой переменной или сколько значений этих переменных зарезервировано. Здесь обращает на себя внимание то, что, хотя для слова «партия» есть 2 уникальных значения (демократ, республиканец), в других названиях есть 3 значения.

Это означает, что даже если среди значений свойств тип не равен «null» или «NaN», существуют данные, требующие предварительной обработки. Давайте подробнее рассмотрим данные.

С помощью команды df.head () по умолчанию мы можем видеть данные в первых 5 строках. Если мы не можем найти ответ, который ищем в этих данных, и нам нужно больше данных, мы можем увидеть больше данных, введя желаемое число в команду. Например;

Так мы увидели первые 10 строк. Следует обратить внимание на то, что некоторые значения указаны как «?». На следующем этапе, после визуального анализа, мы сосредоточимся на этой проблеме.

Визуальный EDA

Давайте визуально посмотрим на наш набор данных, который мы видели в числовом виде на предыдущем шаге. Например, давайте посмотрим на распределение голосов за «иммиграцию».

Подтверждая информацию, полученную на предыдущем шаге, мы видим третий образец голосования, отличный от «да» или «нет». Это данные в виде «?» Это нам нужно решить. Чтобы решить эту проблему, мы используем метод SimpleImputer библиотеки scikit-learn.

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(missing_values='?', strategy='most_frequent')

Мы создали переменную под названием imputer из объекта SimpleImputer. Мы присвоили параметру missing_values ​​строковое значение «?» которое мы принимаем как пропущенное значение и хотим изменить. По умолчанию для этого параметра установлено значение «NaN» (не число). Мы устанавливаем параметр стратегии как «most_frequent». Таким образом, значения, обозначенные «?», Будут равны любому значению, которое является наибольшим в этом столбце (т. Е. В соответствии с частотой, если «нет» голосов больше всего, «n» или «да» будут «y»).

Примечание. В вашем собственном исследовании вы можете увидеть, что в некоторых источниках в Интернете для этого процесса выполняется вызов из sklearn.preprocessing import Imputer. Однако в новой версии этот метод был удален и заменен используемым нами методом sklearn.impute.SimpleImputer.

Далее следует определение и обучение нашей модели. Поскольку это проблема классификации, мы можем использовать алгоритм k-NN (k-Nearest Neighbours / k-Nearest Neighborhood) для решения этой проблемы. Если говорить о принципах работы этого алгоритма;

Он смотрит на классы ближайших k точек

К какому бы классу ни принадлежало большинство этих k точек, алгоритм определяет класс точки, которую он исследует как этот класс.

Предположим, у нас есть набор данных из красных и зеленых точек. И у нас есть момент, когда мы еще не знаем, к какому классу он принадлежит. Если мы установим значение нашего параметра k равным 3,

Наш алгоритм смотрит на эти 3 ближайшие точки, видит, что большинство из них красные, и назначает красный цвет неназначенной точке. Если мы выберем значение k равным 5,

На этот раз, поскольку большинство из них зеленые, наш алгоритм решит, что искомый класс зеленый.

Алгоритм kNN исследует обучающий набор, ища ближайших соседей во всем наборе данных, чтобы сделать прогнозы. Теперь давайте включим наш алгоритм в нашу рабочую среду.

from sklearn.neighbors import KNeighborsClassifier
knn_model = KNeighborsClassifier(n_neighbors=2)

Опять же, используя библиотеку scikit-learn, мы вызвали наш алгоритм kNN и определили переменную, которую мы называем knn_model, установив параметр n_neighbors, который указывает значение соседства, которое будет использоваться при принятии решения, как 2. Далее мы создадим наши шаги.

steps = [(‘imputation’, imputer),(‘knn’, knn_model)]

Таким образом, мы сгруппировали наши шаги в список кортежей Python. Мы будем использовать переменную шагов, которую мы определили, для создания конвейера вместо пошагового кодирования процесса предположения.

from sklearn.pipeline import Pipeline
pipeline = Pipeline(steps)

Используя метод sklearn.pipeline, вы можете сгруппировать свой алгоритм, параметры и шаги предварительной обработки данных в одну переменную (мы называем шаги ) и напишите более компактный код.

Давайте поговорим о создании обучающих и тестовых наборов из имеющегося у нас набора данных. Для этого воспользуемся методом train_test_split. Кроме того, мы определим функцию "вечеринки" в качестве цели, а другие функции - в качестве предикторов.

from sklearn.model_selection import train_test_split
y=df['party'].values
X=df.drop('party', axis=1).values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

Мы присваиваем "партийные" значения для каждой информации в нашем наборе данных переменной y. Затем мы вычитаем эти значения из нашего набора данных и присваиваем оставшиеся значения переменной X. Таким образом, мы создали наши предикторные и целевые переменные.

Затем мы разделили наши данные на обучающие и тестовые с помощью метода train_test_split. При разделении мы устанавливаем размер нашего тестового набора равным 30% всех данных с помощью параметра test_size. Остальное мы разделили как данные поезда.

random_state - это просто целочисленный параметр, который мы используем для перемешивания данных перед их разделением. В таких материалах, как обучение и документы, которые вы изучаете, вы обычно видите, что этот параметр равен 42.

Наконец, еще один важный момент, который нам необходимо знать, - это то, что наша модель / алгоритм не может обрабатывать данные строкового типа. Как мы видим на визуальном представлении алгоритма kNN, вся операция основана на вычислении расстояния (евклидова расстояния) в векторном пространстве. Чтобы математически смоделировать каждую точку в нашем наборе данных, мы меняем значения, указанные как 'n' и 'y' на 0 и 1. Поскольку я хочу коснуться некоторых из наиболее популярных библиотек и приложений Python, я не буду включать много математических объяснений в этой серии статей. Затем алгоритм изучает данные и делает выводы.

from sklearn.metrics import accuracy_score
knn_pipeline = pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
accuracy_score(y_test, y_pred)

Мы создали конвейер с этапами предварительной обработки данных и обучения. На этом этапе, если вы хотите работать без использования pipeline, вы также можете сделать вывод модели из данных напрямую с помощью knn_model.fit ( ). Обратите внимание, что в этом случае вам придется кодировать предыдущие шаги шаг за шагом.

Затем мы передаем набор входных данных, которые мы зарезервировали для тестирования, методу прогноз, чтобы сделать прогнозы. Наконец, мы можем видеть, что наш показатель успеха составляет примерно % 92,37, используя метод precision_score, который мы включили из библиотеки scikit-learn.

Что же мы можем сделать, чтобы этот показатель еще больше увеличился? Что могло привести к тому, что наш успех оказался ниже, чем он мог бы быть?

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

Второй момент - это данные, разделенные как поезд / тест. Мы выделили 30% данных как тестовые, но имейте в виду, что выделенные данные выбираются случайным образом. Возможно, результат был бы другим, если бы мы установили другие 30% в качестве тестовых данных, то есть если бы мы тренировали наш алгоритм с другими 70%. Как мы можем решить эти две проблемы?

Наше первое решение - перекрестная проверка. Этот метод основан на различии между тренировками и тестами на каждом этапе и выборе наилучшего обучения. В качестве примера я основал демонстрацию, в которой данные поезда / теста разделяются в соотношении 80/20. Мы берем метрику, выбирая наборы поездов / тестов по-разному в каждом сплите. Какое из этих различий имеет наивысший балл, мы выбираем наше различие как это.

Основной метод, с которым мы будем комбинировать этот метод, - это перекрестная проверка поиска по сетке. Разделив наш набор данных на сетки, мы не только по-разному выбираем набор поездов / тестов на каждом шаге, но и пробуем его с другим параметром n_neighbor. Мы используем sklearn.model_selection.GridSearchCV для реализации этой техники в Python.

from sklearn.model_selection import GridSearchCV
parameters = {'knn__n_neighbors': np.arange(1, 50)}
cv = GridSearchCV(pipeline, param_grid=parameters, cv=5)

Мы будем оценивать параметр n_neighbors алгоритма knn от 1 до 50 с помощью numpy библиотека. Если вы хотите использовать другой параметр другого алгоритма, вы должны написать ‘имя_модели__параметр’. Сначала мы назначили наш конвейер методу GridSearchCV, а затем нашей переменной parameters, которую мы создали в Python тип словаря в качестве значения параметра param_grid. Введя количество различных способов разделения обучения и тестирования в параметр cv, мы вернемся к стадии подбора.

cv.fit(X_train, y_train)
print("Tuned KNN Parameters: {}".format(cv.best_params_))
print("Best score is {}".format(cv.best_score_))

Здесь наш алгоритм работал, обрабатывая данные 5 различными способами для каждого значения n_neighbor, определяя лучший параметр и оценку. С помощью метода cv.best_params_ мы увидели, что наилучшее значение n_neighbor было 6 , а с cv.best_score_ наш лучший результат составил около 93,76%.

В следующих темах серии статей Машинное обучение мы рассмотрим различные подходы ML к различным проблемам, различные методы, которые можно использовать для измерения производительности. Желаю, чтобы это было полезно.

Ресурсы

[1] https://archive.ics.uci.edu/ml/datasets/