Продолжая с того места, где мы остановились, мы углубимся в то, как разрабатывать алгоритмы машинного обучения (ML) с помощью TensorFlow с точки зрения разработчика scikit-learn. Если вы хотите узнать причины перехода на TensorFlow, мотивацию, прочтите мой предыдущий пост Причины перехода на TensorFlow и простую программу классификации, которая подчеркивает сходство разработки для scikit-learn и TensorFlow.

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

Использование машинного обучения

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

Если все, что у вас есть, это молоток, все выглядит как гвоздь

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

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

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

Эта проблема

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

Весь код, описанный в этом посте, доступен в моем репозитории GitHub здесь.

Обработка данных - Scikit-learn

Мы используем эффективные инструменты загрузки данных Scikit-learn для получения наших данных. Набор данных по раку груди доступен здесь. Список других наборов данных, которые Scikit-learn позволяет нам загружать, можно найти здесь. Давайте загрузим набор данных и просмотрим некоторые атрибуты данных.

from sklearn.datasets import load_breast_cancer
cancer_data = load_breast_cancer()
print("Number of instances in the dataset: %d" % len(cancer_data.target))
>> Number of instances in the dataset: 569

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

Эксперимент первый: использование данных как есть [D1]

Мы используем данные из SKLearn как есть, просто загружая переменные с помощью встроенного поезда, тестового сплиттера.

from sklearn.model_selection import train_test_split
in_train, in_test, out_train, out_test = train_test_split(cancer_data[‘data’], 
 cancer_data[‘target’])

Эксперимент 2. Масштабирование данных [D2]

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

from sklearn.preprocessing import StandardScaler
data_scaler = StandardScaler()
# Fit train data 
data_scaler.fit(in_train)
in_train = data_scaler.transform(in_train)
in_test = data_scaler.transform(in_test)

Сеть - TensorFlow

Мы разрабатываем нейронную сеть, подобную моей предыдущей публикации, чтобы сохранить простой подход к сети и вместо этого понять эффекты предварительной обработки данных и переобучения. Мы используем DNNClassifier TensorFlow, который доступен в модуле contrib TensorFlow. Мы определяем сеть с тремя уровнями, каждый из которых имеет ‹units› количество скрытых единиц. В наших экспериментах мы сначала оцениваем производительность сети ниже, изменяя способ предварительной обработки входных данных, с units = 50. Затем выбираются наиболее эффективные входные данные для дальнейшего эксперимента, чтобы понять, где мы сохраняем данные постоянными (лучше всего среди D1 и D2) и меняем единицы. Структура сети описана ниже:

feature_columns = tf.contrib.learn.infer_real_valued_columns_from_input(in_train)
classifier_tf = tf.contrib.learn.DNNClassifier(feature_columns=feature_columns, 
 hidden_units=[units, units, units], 
 n_classes=2)
classifier_tf.fit(in_train, out_train, steps=1000)

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

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

Эксперимент третий: количество скрытых объектов [H1]

Цель этих двух экспериментов - понять влияние количества скрытых единиц на каждом уровне, что также даст представление о переобучении.

Для этого эксперимента мы сначала выбираем D1 или D2 (описано выше), а затем меняем количество скрытых единиц на каждом уровне сети. Количество скрытых единиц для этого эксперимента остается низким и составляет H1 = 10.

Эксперимент четвертый: количество скрытых единиц [H2]

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

Отчетность - Scikit-learn

Мы используем функции отчетов Scikit-learn, чтобы понять, как работает наш классификатор. Мы используем отчет о классификации и матрицу неточностей, чтобы понять, как работает наш классификатор.

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

report = metrics.classification_report(out_test, predictions, 
 target_names=cancer_data.target_names)
print(report)

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

# Plotting the confusion matrix using matplotlib
%matplotlib inline
confusion = metrics.confusion_matrix(out_test, predictions)
# Plot non-normalized confusion matrix
plt.figure()
plot_confusion_matrix(confusion, classes=cancer_data.target_names,
 title=’Confusion matrix, without normalization’)

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

Полученные результаты

Сначала мы проводим эксперимент, чтобы понять, помогает ли нормализация данных улучшить классификацию. Следовательно, мы выбираем H1 и экспериментируем с D1 и D2. Результаты представлены ниже:

Эффективность с H1 + D1

              precision    recall  f1-score   support

  malignant       0.94      0.88      0.91        51
     benign       0.94      0.97      0.95        92

avg / total       0.94      0.94      0.94       143
Prediction Accuracy: 0.937063

Эффективность с H1 + D2

              precision    recall  f1-score   support

  malignant       0.96      0.93      0.95        46
     benign       0.97      0.98      0.97        97

avg / total       0.96      0.97      0.96       143
Prediction Accuracy: 0.965035

Из наших экспериментов очевидно, что масштабирование данных обеспечивает повышение точности классификации на ~ 3%. Это позволяет нам выбрать D2 (данные с масштабированием) для наших экспериментов с H2.

Производительность с H2 + D2

              precision    recall  f1-score   support

  malignant       0.96      0.92      0.94        53
     benign       0.96      0.98      0.97        90

avg / total       0.96      0.96      0.96       143
Prediction Accuracy: 0.958042

Анализ производительности

Метрики производительности H1 + D2 и H2 + D2 не дают большого представления о том, как классификатор работает в других классах с точки зрения количества точек данных. Именно здесь матрица неточностей дает лучшую картину для дальнейшего анализа.

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

Заключение

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

Весь код, описанный в этом посте, доступен в моем репозитории GitHub здесь.

Дайте мне знать, какие темы вы хотите, чтобы я обсудил в моем следующем сообщении, в комментариях ниже. Я в Твиттере, на случай, если ты захочешь связаться со мной там!