В этой серии статей вы познакомитесь с Введение в машинное обучение для программистов от fast.ai. Я вкратце объясню вам уроки, а также объясню код и то, что происходит за кулисами. Спасибо Джереми и Рэйчел, которые создали лучшее руководство для всех программистов.

Уроки: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12

Это Часть 1/12 Лекционные заметки - ВВЕДЕНИЕ В СЛУЧАЙНЫЕ ЛЕСА

Урок 1 покажет вам, как создать «случайный лес» - возможно, наиболее широко применяемую модель машинного обучения - для создания решения для конкурса Kaggle «Книга быков для бульдозеров», который поможет вам попасть в 25% лучших в рейтинге. таблица лидеров. Вы узнаете, как использовать Jupyter Notebook для построения и анализа моделей, как загружать данные и другие базовые навыки, необходимые для практического использования машинного обучения.

Настройка среды

Если вы используете PaperSpace, используйте скрипт, приведенный здесь. Предполагая, что у вас есть графический процессор и установка Anaconda (предпочтительно CUDA ≥9):

Conda install for GPU :
conda install -c pytorch pytorch-nightly cuda92
conda install -c fastai torchvision-nightly
conda install -c fastai fastai
Conda install for CPU :
conda install -c pytorch pytorch-nightly-cpu
conda install -c fastai torchvision-nightly-cpu
conda install -c fastai fastai

Начало работы с Кодексом

Вы можете найти мою записную книжку здесь (добавленные комментарии и пояснения) и найти набор данных Kaggle здесь.

Импорт необходимых библиотек

%load_ext autoreload
%autoreload 2
%matplotlib inline
  • autoreload : автоматически перезагружает модули перед входом в выполнение.
  • %matplotlib inline : - волшебная функция, которая устанавливает бэкэнд matplotlib как «встроенный» бэкэнд. С помощью этого внутреннего интерфейса вывод команд построения графиков отображается внутри записной книжки Jupyter.
from fastai.imports import *
from fastai.structured import *
from pandas_summary import DataFrameSummary
from sklearn.ensemble import RandomForestRegressor,      RandomForestClassifier
from IPython.display import display
from sklearn import metrics
  • fastai.structured: этот модуль работает с Pandas DataFrames, не зависит от PyTorch и может использоваться отдельно от остальной части библиотеки fastai для обработки и работы с табличными данными.
  • fastai.imports : этот модуль содержит все базовые + необходимые библиотеки.
  • DataFrameSummary: ожидайте, что панды DataFrame подведут итоги.
  • RandomForestRegressor: метаоценка, которая соответствует ряду классических деревьев решений по различным подвыборкам набора данных и использует усреднение для повышения точности прогнозов и контроля избыточного подбора.
  • metrics: этот модуль включает функции оценки, показатели производительности, попарные показатели и вычисления расстояний.

Теперь, если вы хотите знать, что делает конкретная библиотека и какой код работает за ней, выполните следующие действия. Если вы хотите получить описание библиотеки и ее функции, введите

?ImportModuleName или ShiftTab

Если вы хотите просмотреть исходный код модуля, введите

??ImportModuleName или ShiftTab ShiftTab

О наборе данных

Мы рассмотрим «Синюю книгу для конкурса Bulldozers Kaggle Competition»: «Цель конкурса - предсказать цену продажи конкретной единицы тяжелой техники на аукционе в зависимости от ее использования, типа и конфигурации оборудования. Данные получены из сообщений о результатах аукционов и включают информацию об использовании и конфигурации оборудования ». Это очень распространенный тип проблем с набором данных и прогнозирования, который похож на то, что вы можете увидеть в своем проекте или на рабочем месте.

Чтение набора данных

Обычно данные, которые мы получаем, находятся в формате CSV, мы можем прочитать данные с помощью команды оболочки

!head Data/Train.csv

Но это трудно читать, поэтому мы используем Pandas .pandas - самая важная библиотека, когда вы работаете со структурированными данными, которые обычно импортируются как pd.

df_raw = pd.read_csv(f'{PATH}Train.csv', low_memory=False, 
                     parse_dates=["saledate"])
  • parse_dates: анализирует список столбцов, содержащих даты.
  • low_memory=False —Внутренняя обработка файла фрагментами, что приводит к меньшему использованию памяти при синтаксическом анализе. Чтобы гарантировать отсутствие смешанных типов, установите значение False или укажите тип с помощью параметра dtype.

Оценка

Важно отметить, какой показатель используется для проекта. Как правило, выбор показателей является важной частью настройки проекта. Однако в этом случае Kaggle сообщает нам, какую метрику использовать: RMSLE (среднеквадратичная ошибка журнала) между фактической и прогнозируемой аукционной ценой. Поэтому мы ведем журнал цен, чтобы RMSE предоставила нам то, что нам нужно.

df_raw.SalePrice = np.log(df_raw.SalePrice)
  • np - Numpy позволяет нам обрабатывать массивы, матрицы, векторы, многомерные тензоры, как если бы они были переменными Python.

Предварительная обработка

Этот набор данных содержит сочетание непрерывных и категориальных переменных.

  • непрерывный - числа, значение которых является числовым, например цена.
  • категориальные - числа, значение которых не является непрерывным, например почтовый индекс, или строка, такая как «большой», «средний», «маленький».
add_datepart(df_raw, 'saledate')

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

df_raw.head()

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

train_cats(df_raw)
df_raw.UsageBand.cat.set_categories(['High', 'Medium', 'Low'], ordered=True, inplace=True)

В Pandas есть понятие типа данных категории, но по умолчанию он ничего не превращает для вас в категорию. Fast.ai предоставляет функцию train_cats, которая создает категориальные переменные для всего, что является строкой. За кулисами он создает столбец, который является целым числом, и будет хранить сопоставление целых чисел со строками. train_cats называется «поездом», потому что он зависит от данных обучения. Важно, чтобы наборы для проверки и тестирования использовали одни и те же сопоставления категорий (другими словами, если вы использовали 1 для «высокого» значения для набора обучающих данных, то 1 также должно быть для «высокого» в наборах данных для проверки и тестирования). Для проверки и тестового набора данных используйте вместо этого apply_cats.

  • df_raw.UsageBand.cat - .cat дает вам доступ к вещам, предполагая, что что-то является категорией.

Порядок не имеет большого значения, но поскольку мы собираемся создать дерево решений, которое разделяет вещи в одной точке (т.е. High против Low и Medium, High и Low против Medium), это немного странно.

  • inplace попросит Pandas изменить существующий фрейм данных вместо того, чтобы возвращать новый.

Существует разновидность категориальной переменной, называемой «порядковой». Порядковая категориальная переменная имеет какой-то порядок (например, «Низкий» ‹« Средний »‹ «Высокий»). Случайные леса не особо чувствительны к этому факту, но стоит отметить.

df_raw.dtypes

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

Обработка пустых / нулевых значений - одна из важных задач предварительной обработки.

display_all(df_raw.isnull().sum().sort_index()/len(df_raw))

Вышеупомянутое добавит несколько пустых значений для каждой серии, мы сортируем их по индексу (pandas.Series.sort_index) и разделим на количество наборов данных.

Сохранение работы

Чтение CSV заняло около 10 секунд, а обработка заняла еще 10 секунд, поэтому, если мы не хотим снова ждать, рекомендуется сохранить их. Здесь мы сохраним его в формате пера. Что это будет делать, так это сохранить его на диск в том же базовом формате, что и в ОЗУ. Это, безусловно, самый быстрый способ сохранить что-либо, а также прочитать это. Формат Feather становится стандартом не только для Pandas, но и для Java, Apache Spark и т. Д.

os.makedirs('tmp', exist_ok=True)
df_raw.to_feather('tmp/bulldozers-raw')

Мы можем прочитать это так:

df_raw = pd.read_feather('tmp/raw')

Исправление отсутствующих значений и категориальной переменной

proc_df создаст копию фрейма данных, отделит зависимую переменную, а затем исправит отсутствующие значения и категориальную переменную. После выполнения df будет содержать все строки, которые являются числовыми, а y имеет цену SalePrice.

df, y, nas = proc_df(df_raw, 'SalePrice')

Функция proc_df внутри Structured.fastai выполняет следующие действия:

  • Берет копию df
  • Возьмите зависимый столбец.
  • Зависимый столбец удален.
  • Недостающие значения исправлены.
  • Исправить отсутствующие
    - Числовые значения: если в нем отсутствуют значения, создайте новый столбец с именем Col_na (логический столбец) и замените _na на медианное значение
    - Нечисловые и категориальные: замените кодом и добавить 1.

Что такое случайный лес?

Случайный лес - универсальный метод машинного обучения.

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

Запуск регрессора

scikit-learn

Самый популярный и важный пакет для машинного обучения на Python. Он не лучший во всем (например, XGBoost лучше, чем Gradient Boosting Tree), но довольно хорош почти во всем. RandomForestRegressor импортируется из модуля sclearn.ensemble в scikit-learn.

m = RandomForestRegressor(n_jobs=-1)
m.fit(df, y)
m.score(df,y)
  • n_jobs = 1 использует 100% ЦП одного из ядер. Каждый процесс выполняется в отдельном ядре. В linux с 4 ядрами я четко вижу использование процессора: (100%, ~ 5%, ~ 5%, ~ 5%), когда я запускаю n_jobs = 1 и (100%, 100%, 100%, 100%) < br /> при работе с n_jobs = -1. Каждый процесс использует 100% заданного ядра, но если у вас n_jobs = 1, используется только одно ядро.
  • RandomForestRegressor: создаст модель, и метод подгонки подгонит к ней данные.
  • Score: возвращает коэффициент детерминации R² прогноза.
def rmse(x,y): return math.sqrt(((x-y)**2).mean())
def print_score(m):
    res = [rmse(m.predict(X_train), y_train), rmse(m.predict(X_valid), y_valid),
                m.score(X_train, y_train), m.score(X_valid, y_valid)]
    if hasattr(m, 'oob_score_'): res.append(m.oob_score_)
    print(res)

Проверка переобучения

Здесь мы проверяем только обучающий набор, который тоже со всеми обучаемыми данными. Обычно мы разделяем train.csv на набор для обучения, тестирования и проверки, а затем используем метод model.predict на фактическом наборе тестов (test.csv Эта часть будет рассмотрена в следующей части серии.

  • Мы можем создать набор данных проверки, отсортированный по дате, самые последние 12000 дат будут набором проверки.
def split_vals(a,n): return a[:n].copy(), a[n:].copy()
n_valid = 12000  # same as Kaggle's test set size
n_trn = len(df)-n_valid
raw_train, raw_valid = split_vals(df_raw, n_trn)
X_train, X_valid = split_vals(df, n_trn)
y_train, y_valid = split_vals(y, n_trn)
m = RandomForestRegressor(n_jobs=-1)
%time m.fit(X_train, y_train)
print_score(m)
CPU times: user 1min 3s, sys: 356 ms, total: 1min 3s
Wall time: 8.46 s
[0.09044244804386327, 0.2508166961122146, 0.98290459302099709, 0.88765316048270615]

Последняя строка дает нам оценки [обучение rmse, проверка rmse, r² для обучающего набора, r² для набора проверки]

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

Если вы нашли эту статью полезной и хотели бы оставаться на связи, вы можете найти меня в Twitter, linkedin.

Уроки: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12