Классификация машинного обучения Scikit-Learn 101

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

Прежде чем продолжить, давайте разберемся с целью этой статьи. В этой статье представлена ​​общая проблема машинного обучения, которая уже обсуждалась и решалась ранее. Мое главное намерение состоит не в том, чтобы снова решить проблему, а в том, чтобы объяснить процесс классификации машинного обучения в образовательных целях с использованием библиотеки Scikit-Learn Python.

Минимально необходимые сроки

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

Контролируемое обучение

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

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

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

Неконтролируемое обучение

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

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

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

Описание проблемы диафрагмы

Это очень распространенная проблема, которая хорошо задокументирована в Википедии. Набор данных цветков ириса или набор данных Ириса Фишера - это многомерный набор данных, представленный британским статистиком и биологом Рональдом Фишером в его статье 1936 года Использование множественных измерений в таксономических задачах как пример линейного дискриминантного анализа. / em>

Набор данных состоит из множества образцов каждого из трех видов цветов ириса (setosa, virginica и versicolor). Для каждого образца в см были измерены четыре характеристики:
1. Длина чашелистиков.
2. Длина лепестков.
3. Ширина чашелистиков.
4. Ширина лепестков.

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

Вы можете задать закономерный вопрос - в чем разница между лепестком цветка и чашелистиком? Чтобы ответить на этот вопрос, я обращаюсь к отличному ответу в Quora: основное различие между ними состоит в том, что лепестки образуют внутреннюю завитушку цветка, а чашелистики образуют внешнюю завитушку цветка, как показано ниже.

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

Процесс классификации

Чтобы выполнить классификацию для радужной оболочки глаза, мы сделаем следующие шаги:
1. Загрузка набора данных по радужной оболочке.
2. Разделение данных на обучающий и тестовый наборы.
3. Обучение модели на обучающей выборке.
4. Расчет точности модели.
5. Выполнение прогнозов по внешним входным данным.

Для выполнения всех этих шагов мы будем использовать библиотеку python scikit-learn:
https://scikit-learn.org

Библиотека scikit-learn - это очень мощная библиотека Python, которая предоставляет широкий спектр контролируемых и неконтролируемых алгоритмов обучения через согласованный API на Python. Он построен на SciPy и NumPy, которые необходимо установить перед установкой Sci-kit learn.

Используя python pip3, вы можете установить его, используя:

pip3 install -U numpy scipy scikit-learn

Теперь давайте подробно рассмотрим этапы классификации.

1. Загрузка набора данных

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

from sklearn.datasets import load_iris
iris = load_iris()
data = iris.data
target = iris.target
target_names = iris.target_names

iris.target_names относится к именам функций, как мы сказали во введении. У нас есть 4 функции для этой проблемы, поэтому, если мы напечатаем iris.target_names, мы получим следующий результат.

[‘setosa’ ‘versicolor’ ‘virginica’]

2. Разделение данных для обучения и тестирования

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

from sklearn.model_selection import train_test_split
data_train, data_test, target_train, target_test = train_test_split(self.data, self.target, test_size=0.3, random_state=12)

Используя train_test_split() API, и в одной строке это разделение данных может происходить, оно принимает следующие параметры:

1. Введите данные (self.data).
2. Целевые данные (self.target).
3. Тестовый размер, это указывает, какую часть всего набора данных мы хотим иметь в тестовом разбиении, если этот параметр имеет значение с плавающей запятой, он должен находиться в диапазоне от 0,0 до 1,0 и представлять долю набора данных, который нужно включить в тестовое разбиение (_11 _).
4. Состояние Случайное - это просто начальное число случайного числа (random_state=12).

3. Модель обучения

Теперь нам нужно приступить к обучению модели на обучающей выборке. Мы будем использовать классификатор K-Neighbors для выполнения этой классификации (подробное рассмотрение того, как работает этот классификатор, выходит за рамки этой вводной статьи):
https://scikit-learn.org/stable/modules/ сгенерировано / sklearn.neighbors.KNeighborsClassifier.html

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

from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier()
classifier.fit(data_train, target_train)

Мы обучаем модель, используя метод fit(), передавая входные данные обучения data_train в качестве первого параметра и целевые выходные данные target_train в качестве второго параметра.

4. Расчет точности модели

Чтобы вычислить точность модели, мы будем использовать тестовое разбиение data_test, которое будет предсказано построенной моделью на шаге № 3, а затем мы вычислим, насколько предсказанный результат target_pred далек от исходного правильного результата target_test, используя metrics.accuracy_score() API.

from sklearn import metrics
target_pred = classifier.predict(data_test)
accuracy = metrics.accuracy_score(target_test, target_pred)

accuracy_score() принимает исходный правильный результат target_test в качестве первого параметра, а во втором параметре принимает прогнозируемый результат target_pred. Наконец, accuracy_score() возвращает дробную часть от 0 до 1, где 1 относится к лучшей производительности, а 0 относится к худшей.

Если мы напечатаем переменную точности, мы найдем ее равной 0.9777777777777777, что является очень хорошей точностью.

5. Выполнение фактического прогноза

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

external_input_sample = [[5, 2, 4, 1], [6, 3, 5, 2], [5, 4, 1, 0.5]]
prediction_raw_values = classifier.predict(external_input_sample)
prediction_resolved_values = [target_names[p] for p in prediction_raw_values]

Если мы напечатаем prediction_resolved_values, мы обнаружим, что это:

[‘versicolor’, ‘virginica’, ‘setosa’]

Соединение всех частей и завершение

Фактически мы можем суммировать все предыдущие шаги классификации в два абстрактных шага:

1. Тренировка (с 1 по 4 шаг).
2. Прогнозирование (шаг 5).

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

После запуска этого класса Python у нас будет следующий результат.

Model Accuracy: 0.9777777777777777
Prediction for [[5, 2, 4, 1], [6, 3, 5, 2], [5, 4, 1, 0.5]] =>
[‘versicolor’, ‘virginica’, ‘setosa’]

Как вы могли заметить в конце, мы вызываем saveModel(), который сохраняет фактическую модель с помощью dump() API joblib. Также есть закомментированная строка, которая вызывает loadModel(), который может загружать модель с помощью load() API joblib. Этот шаг важен, если вы хотите избежать повторного обучения своей модели каждый раз, когда вы выполняете этот класс. Это означает, что мы можем просто сделать следующее, чтобы предсказать любой внешний вывод после того, как у вас будет упрощенная модель.

basic_iris_classifier.loadModel()
prediction = basic_iris_classifier.predict(external_input_sample)
print(“Prediction for {0} => \n{1}”.format(external_input_sample, prediction))

Обратите внимание, что этот код доступен в моем GitHub, не стесняйтесь проверять его, задавать вопросы и играть с ним, как хотите:
https://github.com/hazems/basic-knn-classifier-python

Удачного обучения :).

Спасибо @mohammed_nabil и Rao, Yogeswara.