Разбиране на математическия аспект на линейната регресия

Линейната регресия обикновено е отправната точка за всеки курс за машинно обучение. Целта е да се предвиди линейна връзка между входна променлива и целева променлива.

Наивният случай е правата линия, която минава през началото на пространството. Тук сме ограничени до 2 измерения в пространството, следователно декартова равнина. Нека се развиваме постепенно от нулата, започвайки с формат y=mx и след това регресия y=mx+c.

Опростен сценарий на y=mx

В този случай знаем, че ще напаснем линия към данни, които минават през произхода. Това е наивният случай, който може да бъде добра отправна точка. Нека развием нашите функции за загуба и да видим как се държи. Нека пренапишем нашата оценка, както следва.

Имайте предвид, че използваме квадратната грешка, разделена на 2m, където m е броят на точките с данни, които имаме. Следователно можем да считаме това за средна стойност. Точно това е половината от средната квадратна грешка. Интуицията зад делението на 2 ще бъде видима, когато получим производната на функцията на загубите. Това ни помага да имаме по-опростена производна за функцията на загубата. Нека разгледаме следния набор от точки.

Генерирах тези точки с помощта на графикатаy=5x с добавен шум. Така че в идеалния случай нашата оценка за θ трябва да има по-близка стойност за 5. Сега, ако начертаем функцията на загубите за различни θстойности, ще получим нещо като по-долу.

Обърнете внимание, че имаме минимум за функцията на загуба, по-близо до θ=5. Нека видим как можем да стигнем до този конкретен минимум изчислително.

Обърнете внимание на оранжево оцветената допирателна линия и нейния градиент. Това е положителен градиент, който ни дава идеята, че трябва да отидем в обратната посока, за да намерим по-ниска стойност.

Градиентното спускане

Идеята на градиентното спускане, както обикновено се обяснява, е да се премине надолу по непознат терен, като се използва само познаването на околните склонове. Така че в този пример целта е да се намери посоката за преминаване с помощта на градиента на наклона и да се вземе решение за размера на стъпката за движение.

Ясно е, че трябва да вървим наляво. Какво ще кажете за размера на стъпката? Тук се намесва скоростта на обучение. Това се обозначава като . Колкото по-малка е стъпката, толкова по-бавна е. Въпреки това, предприемането на по-голяма стъпка може да ви накара да пропуснете минимумите (да си представим, че преминавате от θ=7 до θ=1, няма смисъл). Така че можем да формулираме промяната на θкакто следва.

Тъй като този сценарий на линейна регресия е независим от данните, това може да се използва като стандартно уравнение за изчисляване на загуба и за извършване на градиентно спускане. Това трябва да подчертае факта, че винаги се придържаме към стандартните функции за загуба, без да създаваме собствена. Много е лесно да се приложи това в Python. Използваме len(x) за m и 0,001 като ⍺. xи yса наборът от данни за обучение или наборът от точки, които искаме да оценим.

#Loss function
(1/2* len(x)) * sum([(theta* x[i] - y[i])**2 for i in range(len(x))])
#Change of theta
theta - 0.0001 * (1/len(x)) * sum([x[i]*(theta*x[i] - y[i]) for i in range(len(x))])

Можем да правим градиентното спускане итеративно, докато достигнем минимум или докато функцията на загубите е под определен праг. Можем също да вземем решение за редица повторения. Тъй като ни е гарантирано, че имаме минимум в линейната регресия, можем да приложим спускането по следния начин.

loss = float('inf')
theta = 8

while True:
    theta = descend(theta)
    
    if loss > loss_function(theta, x, y):
        loss = loss_function(theta, x, y)
    else:
        break

Функцията descend връща следващата θстойност, а loss_function връща загубата на стойност θ. Можем да визуализираме преминаването на градиента по следния начин.

Пълен сценарий y=mx+c

Това е продължение на предишния случай и можем да моделираме изчисленото уравнение и функцията на загубите, както следва.

Следват набор от точки, които бих се опитал да напасна към линия. Генерирах това с помощта на функцията y=5 + 3x с малко шум.

Сега, когато имаме функция на загуба с 2 променливи, нашата функция на загуба ще бъде 3D диаграма с третата ос, съответстваща на стойността на загубата. Диаграмно можем да го илюстрираме по следния начин.

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

Обърнете внимание, че градиентите трябва да се актуализират едновременно, така че актуализирането на една стойност θ да не засегне другата. В Python тази операция ще изглежда по следния начин.

theta1_new = theta1 - 0.01 * (1/len(x)) * sum([theta1 + theta2*x[i] - y[i] for i in range(len(x))])
theta2_new = theta2 - 0.01 * (1/len(x)) * sum([x[i]*(theta1 + theta2*x[i] - y[i]) for i in range(len(x))])
theta1, theta2 = theta1_new, theta2_new

Функцията на загубите е както следва. Единствената актуализация от предишния ни сценарий е, че сега имаме втората променлива θ2.

(1/2* len(x)) * sum([(theta1 + theta2* x[i] - y[i])**2 for i in range(len(x))])

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

loss = float('inf')
theta1 = 10
theta2 = -1

while True:
    theta1, theta2 = descend(theta1, theta2)
    
    if loss > loss_function(theta1, theta2, x, y) and \
            abs(loss - loss_function(theta1, theta2, x, y)) > 0.001:
        loss = loss_function(theta1, theta2, x, y)
    else:
        break

Можем да визуализираме спускането върху градиента на функцията на загубата, както следва.

Докато нашите тета стойности се променят, нашата регресия се съгласува добре със стойностите в таблицата. Ще изглежда по следния начин.

Получаваме стойностите6,5 и 2,7съответно за отсечката и градиента в окончателното напасване, което е разумно предвид шума в данните.

Благодаря за четенето. наздраве!