Стандартизация и возврат весов

Когда признаки измерены в очень разных масштабах, обучение идёт плохо: по одному направлению ошибка меняется резко, по другому еле-еле, а шаг приходится брать один на всех. Такую вытянутую задачу называют оврагом.

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

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

Подробно: Все веса сразу.

 


Задание

База выполненных заказов. Три первых числа в строке — признаки заказа: километры, светофоры, свободные курьеры рядом. Четвёртое — сколько заказ ехал на самом деле, в минутах. Это и есть то, что модель учится предсказывать.

База вписана в тест, объявлять её в решении не нужно.

baza = [(4.0, 2, 6, 20.0), (2.0, 5, 4, 19.5), (6.0, 1, 2, 26.5), (1.5, 3, 8, 13.0),
        (5.0, 0, 5, 20.5), (3.0, 4, 1, 22.5), (7.5, 2, 3, 32.0), (2.5, 6, 7, 21.0)]

Напишите две функции

def standardize(baza):
    # возвращает (новая база, список средних, список разбросов)
    ...

def unscale(p, sredn, razbros):
    # возвращает четыре веса в исходных единицах
    ...

Формула стандартизации признака:

x′ = (x − среднее) / разброс

В standardize трогаем только три признака, время остаётся как есть. Разброс — корень из среднего квадрата отклонений от среднего.

Формулы возврата:

w_j = w'_j / s_j
b   = b' − сумма( w'_j · mu_j / s_j )

Как проверить себя

После стандартизации среднее каждого признака обязано стать нулём, а разброс — единицей: это самая быстрая проверка первой функции.

Вторую проверяйте так: обучите модель на стандартизованных данных с lr = 0.3 за 120 шагов, получите четыре числа, в которых ничего не прочитать, примените unscale — и выйдут ровно 3, 1.5, −0.5 и 8. Без этого шага задание было бы бессмысленным: подумайте, почему.

Числа сравниваются с допуском, а не как строки: достаточно совпадения в первых четырёх знаках. Печатать ничего не надо — функция возвращает значение.


Напишите программу
Auto
       

time 10000 ms
memory 256 Mb
Правила оформления программ и список ошибок при автоматической проверке задач

Статистика успешных решений по компиляторам
 Кол-во
Python1