Автор оригинала: Rahul Agarwal.
Я до сих пор помню, как впервые прочитал код машинного обучения от эксперта и почувствовал себя беспомощной жертвой. Когда я открыл его, на меня обрушились огромные куски кода без каких-либо комментариев, убив любое чувство энтузиазма, которое я, возможно, испытывал.
Что ж, есть и хорошие новости: создание модели машинного обучения на Python не должно быть таким уж сложным делом. Имея в своем распоряжении необходимые навыки и инструменты, вы можете легко создать полностью работающую модель с высокой точностью — и все это без огромных бюджетов или найма подрядчиков.
Что там в посте?
Мы собираемся предсказать вид цветка Ириса, используя Случайный лесной классификатор. Зависимая переменная (вид) содержит три возможных значения: Setosa, Versicolor и Virginica. Это классический случай многоклассовой проблемы классификации, так как число видов, которые должны быть предсказаны, больше двух. Мы будем использовать встроенную функцию классификатора случайных лесов в библиотеке Scikit-learn для прогнозирования вида.
Почему проблема многоклассовой классификации с использованием scikit?
Большинство реальных приложений машинного обучения основаны на многоклассовых алгоритмах классификации (т. Обнаружение Объектов, Обработка Естественного Языка, Рекомендации по Продукту).
Для новичков в машинном обучении и/или системах кодирования scikit-library предоставляет простые в использовании функции для выполнения сложных задач, связанных с машинным обучением, таких как расчет функции стоимости, градиентный спуск и вычисления важности функций, что помогает пользователям понять приложения машинного обучения, не углубляясь в математику и вычисления.
Хотя понимание лежащей в основе математики важно для понимания алгоритмов машинного обучения, с помощью доступных библиотек оно не является необходимым для реализации.
Как мы решаем эту проблему?
Хороший алгоритм машинного обучения многоклассовой классификации включает в себя следующие шаги:
- Импорт библиотек
- Извлечение набора данных
- Создание класса зависимых переменных
- Извлечение функций и выходных данных
- Разделение набора данных Train-Test (может также включать набор данных проверки)
- Масштабирование объектов
- Обучение модели
- Вычисление оценки модели с использованием метрики, признанной подходящей на основе задачи
- Сохранение модели для дальнейшего использования
1/9. Импорт библиотек
Мы собираемся импортировать три библиотеки для нашего кода:
- Панды: Одна из самых популярных библиотек для обработки и хранения данных. Он используется для чтения/записи набора данных и хранения его в объекте dataframe. Библиотека также предоставляет различные методы преобразования фреймов данных.
- Numpy: Библиотека, используемая для научных вычислений. Здесь мы используем функцию vectorize для реверсирования факторизации наших классов в текст.
- Sklearn: Библиотека используется для широкого спектра задач, таких как разбиение набора данных на тестовые и обучающие, обучение случайного леса и создание матрицы путаницы.
#Importing Libraries import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import confusion_matrix from sklearn.externals import joblib print('Libraries Imported')
Импортированные библиотеки
2/9. Выборка набора данных
Я использовал набор данных iris из here для классификации. Я переименовал набор данных из ‘iris.data’ в ‘iris.data.csv’ и сохранил его в той же папке, что и скрипт Python. Приведенный ниже код будет выполнять следующие функции:
- Храните данные без colnames в dataframe с именем “dataset”.
- Переименуйте столбцы в [‘длина лепестка в см’, ‘ширина лепестка в см’,’длина лепестка в см’,’ширина лепестка в см’,’вид’].
- Покажите первые пять записей набора данных.
#Creating Dataset and including the first row by setting no header as input dataset = pd.read_csv('iris.data.csv', header = None) #Renaming the columns dataset.columns = ['sepal length in cm', 'sepal width in cm','petal length in cm','petal width in cm','species'] print('Shape of the dataset: ' + str(dataset.shape)) print(dataset.head())
Форма набора данных: (150, 5)
Ирис-сетоза | 0 | 0.2 | 3.5 | 1.4 | 5.1 |
Ирис-сетоза | 1 | 0.2 | 3.0 | 1.4 | 4.9 |
Ирис-сетоза | 2 | 0.2 | 3.2 | 1.3 | 4.7 |
Ирис-сетоза | 3 | 0.2 | 3.1 | 1.5 | 4.6 |
Ирис-сетоза | 4 | 0.2 | 3.6 | 1.4 | 5.0 |
3/9. Создание класса зависимых переменных
Мы в основном преобразуем значения столбцов видов из [‘Iris-setosa’,’Iris-versicolor’,’Iris-virginica’] в [0,1,2]. Это важный шаг, поскольку Случайный лес scikit-learn не может предсказывать текст — он может предсказывать только числа.
Кроме того, нам нужно сохранить факторные преобразования, чтобы запомнить, какое число заменяет текст. Приведенный ниже код будет выполнять следующие действия:
- Используйте функцию pandas factorize для факторизации столбца видов в наборе данных. Это создаст как факторы, так и определения для факторов.
- Храните факторизованный столбец как вид.
- Сохраните определения для факторов.
- Покажите первые пять строк для столбца видов и массива определений.
#Creating the dependent variable class factor = pd.factorize(dataset['species']) dataset.species = factor[0] definitions = factor[1] print(dataset.species.head()) print(definitions)
0 | 0 |
1 | 0 |
2 | 0 |
3 | 0 |
4 | 0 |
Название: вид, dtype: int64 Index([‘Iris-setosa’, ‘Iris-versicolor’, ‘Iris-virginica’],)
4/9. Извлечение функций и выходных данных
Нам нужно разделить набор данных на независимые и зависимые переменные. В нашем наборе данных первые четыре столбца являются независимыми переменными, тогда как последний столбец, “вид”, является зависимой переменной. Кроме того, нам нужно преобразовать эти значения из фрейма данных в массив для дальнейшего использования.
#Splitting the data into independent and dependent variables X = dataset.iloc[:,0:4].values y = dataset.iloc[:,4].values print('The independent features set: ') print(X[:5,:]) print('The dependent variable: ') print(y[:5])
Набор независимых функций: [[5.1 3.5 1.4 0.2] [4.9 3. 1.4 0.2] [4.7 3.2 1.3 0.2] [4.6 3.1 1.5 0.2] [5. 3.6 1.4 0.2]] Зависимая переменная: [0 0 0 0 0]
5/9. Разделение данных Поезд-Тест
Мы собираемся использовать 75% данных для обучения, а остальные 25% – в качестве тестовых данных (то есть 75% из 150 строк-112 строк для обучения и 38 строк для тестирования). Мы не собираемся создавать наборы данных перекрестной проверки, поскольку они используются при обучении гиперпараметрам.
Кроме того, причина такого большого количества процентов тестовых случаев связана с меньшим количеством строк для модели. Как правило, правило 80/20 для train-test используется, когда данные достаточно высоки.
Приведенный ниже код использует предварительно построенную функцию train_test_split в библиотеке sklearn для создания массивов train и test как для независимой, так и для зависимой переменной. Также назначается для случайного распределения данных.
# Creating the Training and Test set from data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 21)
6/9. Масштабирование функций
Это очень важный шаг в машинном обучении. Это помогает алгоритму быстро найти лучшее решение проблемы.
Мы будем использовать стандартную шкалу, предоставленную в библиотеке sklearn. Он вычитает среднее значение наблюдения и затем делит его на единицу дисперсии наблюдения. Мы выполним следующие шаги:
- Определите скалер, вызвав функцию из библиотеки sklearn.
- Преобразуйте набор объектов train (X_train) и установите скалер на набор объектов train.
- Используйте скалер для преобразования набора тестовых объектов (X_test).
# Feature Scaling scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test)
7/9. Обучение модели
Мы определяем параметры обучения случайного леса следующим образом:
- n_estimators: Это число деревьев в классификации случайных лесов. Мы определили 10 деревьев в нашем случайном лесу.
- критерий: Это функция потерь, используемая для измерения качества разделения. В sklearn есть два доступных варианта — джини и энтропия. Мы использовали энтропию.
- random_state: Это начальное значение, используемое генератором случайных состояний для рандомизации набора данных.
Затем мы используем обучающий набор данных (как зависимый, так и независимый) для обучения случайного леса)
# Fitting Random Forest Classification to the Training set classifier = RandomForestClassifier(n_estimators = 10, criterion = 'entropy', random_state = 42) classifier.fit(X_train, y_train)
RandomForestClassifier(bootstrap=True,,, ,,, .0,,,, .0,,, ,,,)
8/9. Оценка эффективности
Оценка эффективности обучаемой модели состоит из следующих этапов:
- Прогнозирование класса видов тестовых данных с помощью набора тестовых функций (X_test). Мы будем использовать функцию прогнозирования классификатора случайных лесов для прогнозирования классов.
- Преобразование числовых классов прогнозируемых значений и тестовых фактических значений в текстовый эквивалент. Это включает в себя следующие шаги:
- Создание словаря для сопоставления таблиц из класса в текст — мы используем функцию dict вместе с zip для создания необходимого словаря.
- Преобразование базы данных test-actual и test-predict из числовых классов в текстовые.
- Оценка производительности классификатора с использованием матрицы путаницы.
# Predicting the Test set results y_pred = classifier.predict(X_test) #Reverse factorize (converting y_pred from 0s,1s and 2s to Iris-setosa, Iris-versicolor and Iris-virginica reversefactor = dict(zip(range(3),definitions)) y_test = np.vectorize(reversefactor.get)(y_test) y_pred = np.vectorize(reversefactor.get)(y_pred) # Making the Confusion Matrix print(pd.crosstab(y_test, y_pred, rownames=['Actual Species'], colnames=['Predicted Species']))
Фактические виды | |||
13 | 0 | 0 | Ирис-сетоза |
0 | 3 | 12 | Ирис-версиколор |
0 | 10 | 0 | Ирис-виргиния |
9/9. Хранение обученной модели
Мы будем наблюдать важность для каждого из признаков, а затем хранить классификатор случайных лесов, используя функцию joblib sklearn.
print(list(zip(dataset.columns[0:4], classifier.feature_importances_))) joblib.dump(classifier, 'randomforestmodel.pkl')
[(‘длина лепестка в см’, 0.13838770253303928), (‘ширина лепестка в см’, 0.006840004111259038), (‘длина лепестка в см’, 0.43430955033126234), (‘ширина лепестка в см’, 0.4204627430244394)]