Файл: 5 тарау. Кп абатты перцептрондар.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 22.11.2023

Просмотров: 125

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.


Для начала мы прочитаем и обработаем данные с помощью pandas, которые мы представили в Разделе 2.2. Итак, вам нужно убедиться, что у вас установлены панды, прежде чем продолжить. К счастью, если вы читаете в Jupyter, мы можем установить панды, даже не выходя из ноутбука.

# If pandas is not installed, please uncomment the following line:

# !pip install pandas

%matplotlib inline

from d2l import mxnet as d2l

from mxnet import gluon, autograd, init, np, npx

from mxnet.gluon import nn

import pandas as pd

npx.set_np()
Для удобства мы можем загрузить и кэшировать набор данных о жилье Kaggle, используя сценарий, который мы определили выше.

DATA_HUB['kaggle_house_train'] = ( #@save

DATA_URL + 'kaggle_house_pred_train.csv',

'585e9cc93e70b39160e7921475f9bcd7d31219ce')

DATA_HUB['kaggle_house_test'] = ( #@save

DATA_URL + 'kaggle_house_pred_test.csv',

'fa19780a7b011d9b009e8bff8e99922a8ee2eb90')
Мы используем pandas для загрузки двух файлов csv, содержащих данные для обучения и тестирования соответственно.

train_data = pd.read_csv(download('kaggle_house_train'))

test_data = pd.read_csv(download('kaggle_house_test'))

Downloading ../data/kaggle_house_pred_train.csv from http://d2l-data.s3-accelerate.amazonaws.

,→com/kaggle_house_pred_train.csv...

Downloading ../data/kaggle_house_pred_test.csv from http://d2l-data.s3-accelerate.amazonaws.

,→com/kaggle_house_pred_test.csv...
Набор обучающих данных включает 1460 примеров, 80 функций и 1 метку, а тестовые данные содержат 1459 примеров и 80 функций.

print(train_data.shape)

print(test_data.shape)

(1460, 81)

(1459, 80)
Давайте посмотрим на первые четыре и последние две функции, а также на метку (SalePrice) из первых четырех примеров.

print(train_data.iloc[0:4, [0, 1, 2, 3, -3, -2, -1]])




Иденти

фикатор

MSSub

Class

MSЗони

рование

ЛотФрон

тальная

Тип

продажи

Условия

Продажи

Цена

продажи

0

1

60

RL

65.0

WD

Normal

208500

1

2

20

RL

80.0

WD

Normal

181500

2

3

60

RL

68.0

WD

Normal

223500

3

4

70

RL

60.0

WD

Abnorml

140000


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


all_features = pd.concat((train_data.iloc[:, 1:-1], test_data.iloc[:, 1:]))

      1. Предварительная обработка данных

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

x ← (х - µ)/σ, (5.10.1)

Чтобы убедиться, что это действительно преобразует нашу функцию (переменную) таким образом, что она имеет нулевое среднее значение и единичную дисперсию, обратите внимание, что

E [(х-μ)/σ] = (µ − µ)/σ = 0 и что E [(x − µ)2] = (σ2 + µ2) -2μ2 + µ2 = σ2.

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

numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index

all_features[numeric_features] = all_features[numeric_features].apply(

lambda x: (x - x.mean()) / (x.std()))
# После стандартизации данных все средства исчезнут, поэтому мы можем установить пропущенные значения до 0
all_features [numeric_features] = all_features [numeric_features] .fillna (0)

Далее мы имеем дело с дискретными значениями. Сюда входят такие функции, как «MSZoning». Мы заменяем их быстрым кодированием таким же образом, как мы ранее преобразовывали метки мультиклассов в векторы (см. Раздел 3.4.1). Например, «MSZoning» принимает значения «RL» и «RM». При отказе от функции «MSZoning» создаются две новые функции индикатора «MSZoning_RL» и «MSZoning_RM» со значениями, равными 0 или 1. Согласно однократному кодированию, если исходным значением «MSZoning» является «RL», то « MSZoning_RL »равно 1, а« MSZoning_RM »- 0. Пакет pandas делает это автоматически за нас.

# `Dummy_na = True` считает" na "(отсутствующее значение) допустимым значением функции, и

# создает для него функцию индикатора all_features = pd.get_dummies (all_features, dummy_na = True)

all_features.shape


(2919, 331)
Вы можете видеть, что это преобразование увеличивает количество функций с 79 до 331. Наконец, с помощью атрибута values ​​мы можем извлечь формат NumPy из формата pandas и преобразовать его в формат тензорного представления для обучения.

n_train = train_data.shape [0]

train_features = np.array (all_features [: n_train] .values, dtype = np.float32)

test_features = np.array (all_features [n_train:]. values, dtype = np.float32)

train_labels = np.array (

train_data.SalePrice.values.reshape (-1, 1), dtype = np.float32)

      1. 1   2   3   4   5   6   7   8   9


Обучение

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

loss = gluon.loss.L2Loss()

def get_net():

net = nn.Sequential()

net.add(nn.Dense(1))

net.initialize()

return net
В отношении цен на жилье, как и в случае цен на акции, мы больше заботимся об относительных количествах, чем об абсолютных. Таким образом, мы склонны больше заботиться об относительной ошибке (y − yˆ)/y, чем об абсолютной ошибке y - yˆ.

Например, если наш прогноз не соответствует 100 000 долларов США при оценке цены дома в сельской местности Огайо, где стоимость типичного дома составляет 125 000 долларов США, то мы, вероятно, делаем ужасную работу.

С другой стороны, если мы ошибемся на эту сумму в Лос-Альтос-Хиллз, Калифорния, это может представлять потрясающе точный прогноз (там средняя цена дома превышает 4 миллиона долларов США).

Один из способов решения этой проблемы - измерить расхождение в логарифмах оценок цен. Фактически, это также официальная мера погрешности, используемая конкурентами для оценки качества представленных материалов. Ведь малое значение δ для | log y - log yˆ | ≤ δ переводится в e−δ ≤ yˆ/y ≤ eδ. Это приводит к следующей среднеквадратической ошибке между логарифмом прогнозируемой цены и логарифмом цены этикетки:

(1/n ∑ni = 1 (log yi - log yˆi)2)1/2, (5.10.2)

def log_rmse(net, features, labels):

# Для дальнейшей стабилизации значения после логарифмирования установите значение меньше 1 как 1

clipped_preds = np.clip(net(features), 1, float('inf'))

return np.sqrt(2 * loss(np.log(clipped_preds), np.log(labels)).mean())
В отличие от предыдущих разделов, наши обучающие функции будут полагаться на оптимизатор Adam (мы опишем его более подробно позже). Основная привлекательность этого оптимизатора заключается в том, что, несмотря на то, что он не работает лучше (а иногда и хуже) при неограниченных ресурсах для оптимизации гиперпараметров, люди склонны обнаруживать, что он значительно менее чувствителен к начальной скорости обучения.


def train (net, train_features, train_labels, test_features, test_labels,

num_epochs, learning_rate, weight_decay, batch_size):

train_ls, test_ls = [], []

train_iter = d2l.load_array ((train_features, train_labels), batch_size)

# Здесь используется алгоритм оптимизации Адама

trainer = gluon.Trainer(net.collect_params(), 'adam', {

'learning_rate': learning_rate, 'wd': weight_decay})

for epoch in range(num_epochs):

for X, y in train_iter:

with autograd.record():

l = loss(net(X), y)

l.backward()

trainer.step(batch_size)

train_ls.append(log_rmse(net, train_features, train_labels))

if test_labels is not None:

test_ls.append(log_rmse(net, test_features, test_labels))

return train_ls, test_ls


      1. Перекрестная проверка K-Fold

Как вы помните, мы представили K-кратную перекрестную проверку в разделе, где мы обсуждали, как работать с выбором модели (раздел 5.4). Мы применим это к выбору дизайна модели и корректировке гиперпараметров. Сначала нам нужна функция, которая возвращает i-ю кратность данных в K-кратной процедуре перекрестной проверки. Он продолжается путем вырезания i-го сегмента в качестве данных проверки и возврата остальных в качестве данных обучения. Обратите внимание, что это не самый эффективный способ обработки данных, и мы определенно сделали бы что-то более умное, если бы наш набор данных был значительно больше. Но эта дополнительная сложность может без надобности запутать наш код, поэтому мы можем спокойно опустить его здесь из-за простоты нашей проблемы.

def get_k_fold_data(k, i, X, y):

assert k > 1

fold_size = X.shape[0] // k

X_train, y_train = None, None

for j in range(k):

idx = slice(j * fold_size, (j + 1) * fold_size)

X_part, y_part = X[idx, :], y[idx]

if j == i:

X_valid, y_valid = X_part, y_part

elif X_train is None:

X_train, y_train = X_part, y_part

else:

X_train = np.concatenate([X_train, X_part], 0)

y_train = np.concatenate([y_train, y_part], 0)

return X_train, y_train, X_valid, y_valid
Средние значения ошибок обучения и проверки возвращаются, когда мы обучаем K раз в K-кратной перекрестной проверке.

def k_fold(k, X_train, y_train, num_epochs,

learning_rate, weight_decay, batch_size):

train_l_sum, valid_l_sum = 0, 0

for i in range(k):

data = get_k_fold_data(k, i, X_train, y_train)

net = get_net()

train_ls, valid_ls = train(net, *data, num_epochs, learning_rate,

weight_decay, batch_size)

train_l_sum += train_ls[-1]

valid_l_sum += valid_ls[-1]

if i == 0:

d2l.plot(list(range(1, num_epochs+1)), [train_ls, valid_ls],

xlabel='epoch', ylabel='rmse',

legend=['train', 'valid'], yscale='log')

print(f'fold {i + 1}, train log rmse {float(train_ls[-1]):f}, '

f'valid log rmse {float(valid_ls[-1]):f}')

return train_l_sum / k, valid_l_sum / k


      1. Выбор модели

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