Za darmo

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

Tekst
Oznacz jako przeczytane
Czcionka:Mniejsze АаWiększe Aa

plt.plot([0, 1], [0, 1], color='darkblue', linestyle='–', label = 'Случайная классификация')

plt.xlabel('Доля ложно положительных')

plt.ylabel('Доля истинно положительных')

plt.title('ROC-кривая MLP')

plt.legend(loc=”upper left”, props={‘size’: 10)

plt.show()

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

На этом закончим раздел классического моделирования в машинном обучении. Наука не стоит на месте, и в 2000-х стало популярно глубокое обучение.

Разница между машинным и глубоким обучением

Термины искусственный интеллект (artificial intelligence), машинное обучение и глубокое обучение (deep learning) даже используются взаимозаменяемо. Но каждый из них имеет свое особое значение.

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


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

Машинное обучение автоматически адаптируется к задаче с минимальным вмешательством человека.

Глубокое обучение использует искусственные нейронные сети для имитации обучения человеческого мозга.

Взгляните на эти ключевые отличия между ML и DL:



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

Глубокое обучение

Ключевой концепцией DL является многослойный перцептрон (multilayer perceptron). Это разновидность искусственной нейронной сети. Она состоит из нескольких уровней взаимосвязанных узлов, каждый из которых выполняет простые вычисления:



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

Последний уровень – это выходной слой (output layer). Он выдает окончательный результат вычислений – метки классов, преобразованные изображения и так далее.

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



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

Многослойный перцептрон

Создадим экземпляр класса MLPClassifier с сотней скрытых слоев и перемешиванием записей. Обучение будет проходить в не более чем 1000 итераций. random_state, как мы помним, может принимать любое значение. Он нужен, чтобы задавать стартовую точку при перемешивании и напрямую влияет на воспроизводимость результата в будущем. Обучим модель на тренировочных данных.

mlp = MLPClassifier(hidden_layer_sizes=(100), max_iter=1000, random_state=25, shuffle=True)

mlp.fit(X_train, y_train)

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

mlp_pred = mlp.predict(X_test)

cv_mlp=cross_val_score(mlp, X_train, y_train, cv=10).mean()

В предыдущей главе дерево решений показало хороший результат: F1-мера равнялась 93,5%. Посмотрим, составит ли MLP здесь конкуренцию дереву.

print('Доля правильных ответов: %.3f' % mlp.score(X_test, y_test))

print('Доля правильных ответов во время кросс-валидации: %0.3f' % cv_mlp)

print('Точность результата измерений: %.3f' % precision_score(y_test, mlp_pred))

print('Полнота: %.3f' % recall_score(y_test, mlp_pred))

print('Оценка F1: %.3f' % f1_score(y_test, mlp_pred))

Вполне составит! Даже в неотрегулированном виде на полпроцента обгоняет дерево решений!

Доля правильных ответов: 0.889

Доля правильных ответов во время кросс-валидации: 0.888

Точность результата измерений: 0.889

Отзыв: 1.000

Оценка F1: 0.941

Кстати, реальный мир с его многообразием данных, моделей и задач сложен. Так что единого порогового значения не существует. Однако по негласному соглашению диапазон 70% и выше считается индикатором жизнеспособности модели. Показатель выше 90% – хорошим. Модели с эффективность 95% и выше – отличные, даже превышающие возможности человека.

Аналогично дереву решений, соберем предсказания тестовой части данных и рассчитаем ROC-кривую.

mlp_probs = mlp.predict_proba(X_test)

mlp_probs = mlp_probs[:, 1]


auc_mlp = roc_auc_score(y_test, mlp_probs)

print('AUC: %.2f' % auc_mlp)

Взглянем снова на матрицу ошибок.

matrix = confusion_matrix(y_test, mlp_pred)

sns.set(font_scale=1.3)

plt.subplots(figsize=(8, 8))

sns.heatmap(matrix, annot=True, cbar=False, cmap='Blues', linewidth=0.5, fmt="d")

plt.ylabel('Истинный класс')

plt.xlabel('Предсказанный класс')

plt.title('Матрица ошибок дерева решений')

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



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

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

Есть у модели и свой “дирижер”, он же солвер (solver). Он организует оптимизацию модели, координирует обновление параметров. Мы не ограничимся единственным и используем три, чтобы потом выбрать лучший:

• LBFGS

• Adam

• SGD

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

Для регуляризации MLP мы также применим GridSearchCV в 10 шагов кросс-валидации. np.arange() сгенерирует список от единицы до четырех.

Помните диаграмму многослойного перцептрона в начале главы? Дополним ее ключевым понятием DL – весами (weights). Их обозначают так: w0, w1 и так далее:



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

Веса стоит понимать, чтобы познакомиться с Альфой (alpha) – это субалгоритм регуляризации, который изменяет веса.

Альфа-параметр в данном случае получит несколько чисел 10, возведенных в степени от -1 до -4. Мы также вручную указываем размеры скрытых слоев в hidden_layer_sizes.

parameters = {'activation':['logistic','relu'],'solver': ['lbfgs','adam','sgd'], 'alpha':10.0 ** -np.arange(1,4),

'hidden_layer_sizes':[(20),(4),(10),(14,2),(4,1),(10,5),(11,3)]}


default_mlp = MLPClassifier(random_state=25)

gs_mlp = GridSearchCV(default_mlp, parameters, cv=10, n_jobs=-1, verbose=1)

gs_mlp.fit(X_train, y_train)

Теперь можно вычислить улучшенные предсказания:

gs_mlp_pred=gs_mlp.predict(X_test)

Отобразим плоды наших трудов – наилучшие параметры MLP и обновленные метрики ее эффективности:

print("Лучшие параметры MLP: {}".format(gs_mlp.best_params_))

print('Доля правильных ответов во время кросс-валидации: %0.3f' % gs_mlp.best_score_)

print('Доля правильных ответов: %0.3f' % (gs_mlp.score(X_test,y_test)))

print('Точность результата измерений: %.3f' % precision_score(y_test, gs_mlp_pred))

print('Полнота: %.3f' % recall_score(y_test, gs_mlp_pred))

print(‘F1-мера: %.3f' % f1_score(y_test, gs_mlp_pred))

Регуляризация помогает:

Лучшие параметры MLP: {'activation': 'logistic', 'alpha': 0.001, 'hidden_layer_sizes': 10, 'solver': 'lbfgs'}

 

Доля правильных ответов во время кросс-валидации: 0.906

Доля правильных ответов: 0.904

Точность результата измерений: 0.947

Отзыв: 0.945

Оценка F1: 0.946

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

gs_mlp_probs = gs_mlp.predict_proba(X_test)

gs_mlp_probs = gs_mlp_probs[:, 1]


gs_mlp_auc = roc_auc_score(y_test, gs_mlp_probs)

print('AUC: %.2f' % gs_mlp_auc)

Площадь здесь равна 0.92. Достойный результат. Скоро мы сравним кривые визуально еще раз.

AUC: 0.92

Тем же кодом отрисуем ROC-кривые для первой и второй версий многослойного перцептрона:

gs_mlp_fpr, gs_mlp_tpr, gs_mlp_thresholds = roc_curve(y_test, gs_mlp_probs)

mlp_fpr, mlp_tpr, mlp_thresholds = roc_curve(y_test, mlp_probs)


plt.figure(figsize=(8,8))

plt.plot(mlp_fpr, mlp_tpr, color='red', label='MLP ROC (AUC= %0.2f)'% auc_mlp)

plt.plot(gs_mlp_fpr, gs_mlp_tpr, color='green', label='GridSearch+MLP ROC (AUC= %0.2f)'% gs_mlp_auc)

plt.plot([0, 1], [0, 1], color='darkblue', linestyle='–',label='random')

plt.xlabel('Доля ложно положительных')

plt.ylabel('Доля истинно положительных')

plt.title('ROC-кривая MLP')

plt.legend()

plt.show()

Явно возросло число итераций: кривые больше сглажены. Битва за доли процентов не прекращалась, так что прирост в 1% – это огромный прогресс.



Запустить многослойный перцептрон можно в ноутбуке. Ссылка на раздел зашита в QR-код.



8Полный список функций активации можно найти здесь: helenkapatsa.ru/vidy-funktsii-aktivatsii.
9С полным списком оптимизаторов можно познакомиться подробнее в статье: helenkapatsa.ru/solver.