Sadə xətti reqressiya tənliyinin həlli

Məqalədə sadə (cüt) reqressiya xəttinin riyazi tənliyini təyin etməyin bir neçə yolu müzakirə olunur.

Burada nəzərdən keçirilən tənliyin həllinin bütün üsulları ən kiçik kvadratlar üsuluna əsaslanır. Metodları aşağıdakı kimi qeyd edirik:

  • Analitik həll
  • gradient eniş
  • Stokastik Qradient Eniş

Düz xəttin tənliyini həll etmək yollarının hər biri üçün məqalədə əsasən kitabxanadan istifadə etmədən yazılanlara bölünən müxtəlif funksiyalar təqdim olunur. saysız və hesablamalar üçün istifadə olunanlar saysız. Məharətlə istifadə edildiyinə inanılır saysız hesablama xərclərini azaldacaq.

Bu məqalədəki bütün kodlar burada yazılmışdır piton 2.7 istifadə edərək Jupyter noutbuku. Mənbə kodu və nümunə məlumat faylı burada mövcuddur Github

Məqalə daha çox həm yeni başlayanlara, həm də süni intellektin çox geniş bölməsini – maşın öyrənməsini öyrənməyə tədricən yiyələnməyə başlayanlara yönəlib.

Materialı təsvir etmək üçün çox sadə bir nümunədən istifadə edək.

Nümunə şərtləri

Asılılığı xarakterizə edən beş dəyərimiz var Y etibarən X (Cədvəl №1):

Cədvəl №1 "Nümunənin şərtləri"

Sadə xətti reqressiya tənliyinin həlli

Biz bu dəyərləri fərz edəcəyik Sadə xətti reqressiya tənliyinin həlli ilin ayıdır və Sadə xətti reqressiya tənliyinin həlli - bu ay qazanc. Başqa sözlə, gəlir ilin ayından asılıdır və Sadə xətti reqressiya tənliyinin həlli - gəlirin asılı olduğu yeganə əlamət.

Məsələn, həm ilin ayından gəlirin şərti asılılığı, həm də dəyərlərin sayı baxımından belədir - onlardan çox azdır. Bununla belə, belə bir sadələşdirmə, barmaqlarda deyildiyi kimi, yeni başlayanlar tərəfindən mənimsənilən materialı həmişə asanlıqla deyil, izah etməyə imkan verəcəkdir. Həm də rəqəmlərin sadəliyi nümunəni "kağızda" əhəmiyyətli əmək xərcləri olmadan həll etmək istəyənlərə imkan verəcəkdir.

Tutaq ki, misalda verilmiş asılılıq formanın sadə (cüt) reqressiyası xəttinin riyazi tənliyi ilə kifayət qədər yaxşı yaxınlaşdırıla bilər:

Sadə xətti reqressiya tənliyinin həlli

hara Sadə xətti reqressiya tənliyinin həlli gəlirlərin alındığı aydır, Sadə xətti reqressiya tənliyinin həlli - aya uyğun gəlir; Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli təxmin edilən xəttin reqressiya əmsallarıdır.

Qeyd edək ki, əmsal Sadə xətti reqressiya tənliyinin həlli tez-tez təxmin edilən xəttin yamacı və ya qradiyenti kimi istinad edilir; olan məbləğdir Sadə xətti reqressiya tənliyinin həlli dəyişəndə Sadə xətti reqressiya tənliyinin həlli.

Aydındır ki, nümunədəki vəzifəmiz tənlikdə belə əmsalları seçməkdir Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli, bu zaman təxmin edilən gəlir dəyərlərinin aylar üzrə doğru cavablardan sapması, yəni. nümunədə təqdim olunan dəyərlər minimal olacaqdır.

Ən kiçik kvadrat üsulu

Ən kiçik kvadratlar metoduna görə, kənarlaşma onu kvadratlaşdırmaqla hesablanmalıdır. Belə bir texnika, əks əlamətlər olduqda, sapmaların qarşılıqlı ödənilməsinin qarşısını almağa imkan verir. Məsələn, əgər bir halda, sapma +5 (beş əlavə) və digərində -5 (mənfi beş), onda sapmaların cəmi qarşılıqlı olaraq ləğv ediləcək və 0 (sıfır) olacaqdır. Sapmanın kvadratı deyil, modul xüsusiyyətindən istifadə etmək olar və sonra bütün kənarlaşmalar müsbət olacaq və yığılacaq. Bu nöqtədə ətraflı dayanmayacağıq, sadəcə olaraq qeyd edirik ki, hesablamaların rahatlığı üçün sapmanın kvadratına qoyulması adətdir.

Formula belə görünür, onun köməyi ilə kvadrat sapmaların (səhvlərin) ən kiçik cəmini təyin edəcəyik:

Sadə xətti reqressiya tənliyinin həlli

hara Sadə xətti reqressiya tənliyinin həlli doğru cavabların yaxınlaşması funksiyasıdır (yəni bizim hesabladığımız gəlir),

Sadə xətti reqressiya tənliyinin həlli doğru cavablardır (nümunədə təqdim olunan gəlir),

Sadə xətti reqressiya tənliyinin həlli nümunənin indeksidir (sapmanın müəyyən edildiyi ayın sayı)

Gəlin funksiyanı diferensiallayaq, qismən diferensial tənlikləri təyin edək və analitik həllə keçməyə hazır olaq. Ancaq əvvəlcə diferensiasiyanın nə olduğu haqqında qısa bir araşdırma aparaq və törəmənin həndəsi mənasını xatırlayaq.

Fərqləndirmə

Diferensiasiya funksiyanın törəməsinin tapılması əməliyyatıdır.

Törəmə nə üçündür? Funksiyanın törəməsi funksiyanın dəyişmə sürətini xarakterizə edir və bizə onun istiqamətini göstərir. Verilmiş nöqtədəki törəmə müsbət olarsa, funksiya artır, əks halda funksiya azalır. Modul törəməsinin dəyəri nə qədər böyükdürsə, funksiya qiymətlərinin dəyişmə sürəti də bir o qədər yüksəkdir, həmçinin funksiya qrafikinin yamacı da bir o qədər yüksəkdir.

Məsələn, Dekart koordinat sisteminin şərtlərində törəmənin M(0,0) nöqtəsindəki qiyməti bərabərdir. + 25 müəyyən bir nöqtədə, dəyərin dəyişdirildiyi zaman deməkdir Sadə xətti reqressiya tənliyinin həlli şərti vahid, dəyər ilə sağa Sadə xətti reqressiya tənliyinin həlli 25 şərti vahid artır. Qrafikdə bu, dəyərlərdə kifayət qədər dik yüksəliş bucağı kimi görünür Sadə xətti reqressiya tənliyinin həlli müəyyən bir nöqtədən.

Başqa bir misal. Törəmənin dəyəri 0,1- dəyişdirildikdə deməkdir Sadə xətti reqressiya tənliyinin həlli bir şərti vahid üçün dəyər Sadə xətti reqressiya tənliyinin həlli yalnız 0,1 şərti vahid azalır. Eyni zamanda, funksiyanın qrafikində biz demək olar ki, nəzərəçarpacaq dərəcədə aşağı eniş müşahidə edə bilərik. Bir dağla bənzətmə apararaq, sanki çox sıldırım zirvələri götürməli olduğumuz əvvəlki nümunədən fərqli olaraq, dağdan yumşaq bir yamacla çox yavaş enirik :)

Beləliklə, funksiyanı fərqləndirdikdən sonra Sadə xətti reqressiya tənliyinin həlli ehtimalla Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli, 1-ci dərəcəli qismən törəmələrin tənliklərini təyin edirik. Tənlikləri təyin etdikdən sonra iki tənlik sistemi alacağıq, həll edərkən əmsalların bu cür dəyərlərini seçə bilərik. Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli, bu zaman verilmiş nöqtələrdə müvafiq törəmələrin dəyərləri çox, çox az miqdarda dəyişir və analitik həll vəziyyətində heç dəyişmir. Başqa sözlə, tapılan əmsallarda səhv funksiyası minimuma çatacaq, çünki bu nöqtələrdə qismən törəmələrin dəyərləri sıfıra bərabər olacaqdır.

Beləliklə, diferensiasiya qaydalarına görə, əmsala nisbətən 1-ci dərəcəli qismən törəmənin tənliyi Sadə xətti reqressiya tənliyinin həlli forma alacaq:

Sadə xətti reqressiya tənliyinin həlli

ilə bağlı 1-ci dərəcəli qismən törəmə tənlik Sadə xətti reqressiya tənliyinin həlli forma alacaq:

Sadə xətti reqressiya tənliyinin həlli

Nəticədə kifayət qədər sadə analitik həlli olan tənliklər sistemi əldə etdik:

başlanğıc{tənlik*}
başlamaq{hallar}
na + bsumlimits_{i=1}^nx_i - sumlimits_{i=1}^ny_i = 0

sumlimits_{i=1}^nx_i(a +bsumlimits_{i=1}^nx_i - sumlimits_{i=1}^ny_i) = 0
son{hallar}
son{tənlik*}

Tənliyi həll etməzdən əvvəl əvvəlcədən yükləyək, yüklənmənin düzgünlüyünü yoxlayaq və verilənləri formatlayaq.

Məlumatların yüklənməsi və formatlanması

Qeyd etmək lazımdır ki, analitik həll üçün və gələcəkdə gradient və stoxastik gradient enişi üçün kodu iki variasiyada istifadə edəcəyik: kitabxanadan istifadə etməklə. saysız və ondan istifadə etmədən, onda müvafiq məlumat formatına ehtiyacımız var (koda bax).

Məlumat yükləmə və emal kodu

# импортируем все нужные нам библиотеки
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import math
import pylab as pl
import random

# графики отобразим в Jupyter
%matplotlib inline

# укажем размер графиков
from pylab import rcParams
rcParams['figure.figsize'] = 12, 6

# отключим предупреждения Anaconda
import warnings
warnings.simplefilter('ignore')

# загрузим значения
table_zero = pd.read_csv('data_example.txt', header=0, sep='t')

# посмотрим информацию о таблице и на саму таблицу
print table_zero.info()
print '********************************************'
print table_zero
print '********************************************'

# подготовим данные без использования NumPy

x_us = []
[x_us.append(float(i)) for i in table_zero['x']]
print x_us
print type(x_us)
print '********************************************'

y_us = []
[y_us.append(float(i)) for i in table_zero['y']]
print y_us
print type(y_us)
print '********************************************'

# подготовим данные с использованием NumPy

x_np = table_zero[['x']].values
print x_np
print type(x_np)
print x_np.shape
print '********************************************'

y_np = table_zero[['y']].values
print y_np
print type(y_np)
print y_np.shape
print '********************************************'

Vizualizasiya

İndi biz, birincisi, məlumatları yüklədikdən, ikincisi, yükləmənin düzgünlüyünü yoxladıqdan və nəhayət məlumatları formatlaşdırdıqdan sonra ilk vizuallaşdırmanı həyata keçirəcəyik. Çox vaxt bu üsuldan istifadə olunur cüt süjet kitabxanalar Dəniz doğulmuş. Bizim nümunəmizdə sayların məhdudluğu səbəbindən kitabxanadan istifadə etməyin mənası yoxdur Dəniz doğulmuş. Adi kitabxanadan istifadə edəcəyik matplotlib və yalnız səpələnmə xəttinə baxın.

Scatter Plot Kodu

print 'График №1 "Зависимость выручки от месяца года"'

plt.plot(x_us,y_us,'o',color='green',markersize=16)
plt.xlabel('$Months$', size=16)
plt.ylabel('$Sales$', size=16)
plt.show()

Qrafik No1 “Gəlirin ilin ayından asılılığı”

Sadə xətti reqressiya tənliyinin həlli

Analitik həll

Ən çox yayılmış vasitələrdən istifadə edirik python və tənliklər sistemini həll edin:

başlanğıc{tənlik*}
başlamaq{hallar}
na + bsumlimits_{i=1}^nx_i - sumlimits_{i=1}^ny_i = 0

sumlimits_{i=1}^nx_i(a +bsumlimits_{i=1}^nx_i - sumlimits_{i=1}^ny_i) = 0
son{hallar}
son{tənlik*}

Kramerin qaydasına görə ümumi determinantı, həmçinin müəyyənediciləri tapın Sadə xətti reqressiya tənliyinin həlliSadə xətti reqressiya tənliyinin həlli, bundan sonra müəyyənedicinin bölünməsi Sadə xətti reqressiya tənliyinin həlli ümumi təyinediciyə - əmsalı tapın Sadə xətti reqressiya tənliyinin həlli, eynilə əmsalı tapırıq Sadə xətti reqressiya tənliyinin həlli.

Analitik həll kodu

# определим функцию для расчета коэффициентов a и b по правилу Крамера
def Kramer_method (x,y):
        # сумма значений (все месяца)
    sx = sum(x)
        # сумма истинных ответов (выручка за весь период)
    sy = sum(y)
        # сумма произведения значений на истинные ответы
    list_xy = []
    [list_xy.append(x[i]*y[i]) for i in range(len(x))]
    sxy = sum(list_xy)
        # сумма квадратов значений
    list_x_sq = []
    [list_x_sq.append(x[i]**2) for i in range(len(x))]
    sx_sq = sum(list_x_sq)
        # количество значений
    n = len(x)
        # общий определитель
    det = sx_sq*n - sx*sx
        # определитель по a
    det_a = sx_sq*sy - sx*sxy
        # искомый параметр a
    a = (det_a / det)
        # определитель по b
    det_b = sxy*n - sy*sx
        # искомый параметр b
    b = (det_b / det)
        # контрольные значения (прооверка)
    check1 = (n*b + a*sx - sy)
    check2 = (b*sx + a*sx_sq - sxy)
    return [round(a,4), round(b,4)]

# запустим функцию и запишем правильные ответы
ab_us = Kramer_method(x_us,y_us)
a_us = ab_us[0]
b_us = ab_us[1]
print ' 33[1m' + ' 33[4m' + "Оптимальные значения коэффициентов a и b:"  + ' 33[0m' 
print 'a =', a_us
print 'b =', b_us
print

# определим функцию для подсчета суммы квадратов ошибок
def errors_sq_Kramer_method(answers,x,y):
    list_errors_sq = []
    for i in range(len(x)):
        err = (answers[0] + answers[1]*x[i] - y[i])**2
        list_errors_sq.append(err)
    return sum(list_errors_sq)

# запустим функцию и запишем значение ошибки
error_sq = errors_sq_Kramer_method(ab_us,x_us,y_us)
print ' 33[1m' + ' 33[4m' + "Сумма квадратов отклонений" + ' 33[0m'
print error_sq
print

# замерим время расчета
# print ' 33[1m' + ' 33[4m' + "Время выполнения расчета суммы квадратов отклонений:" + ' 33[0m'
# % timeit error_sq = errors_sq_Kramer_method(ab,x_us,y_us)

Əldə etdiyimiz budur:

Sadə xətti reqressiya tənliyinin həlli

Beləliklə, əmsalların dəyərləri tapılır, kvadrat sapmaların cəmi müəyyən edilir. Tapılmış əmsallara uyğun olaraq səpilmə histoqramı üzərində düz xətt çəkək.

Reqressiya xətti kodu

# определим функцию для формирования массива рассчетных значений выручки
def sales_count(ab,x,y):
    line_answers = []
    [line_answers.append(ab[0]+ab[1]*x[i]) for i in range(len(x))]
    return line_answers

# построим графики
print 'Грфик№2 "Правильные и расчетные ответы"'
plt.plot(x_us,y_us,'o',color='green',markersize=16, label = '$True$ $answers$')
plt.plot(x_us, sales_count(ab_us,x_us,y_us), color='red',lw=4,
         label='$Function: a + bx,$ $where$ $a='+str(round(ab_us[0],2))+',$ $b='+str(round(ab_us[1],2))+'$')
plt.xlabel('$Months$', size=16)
plt.ylabel('$Sales$', size=16)
plt.legend(loc=1, prop={'size': 16})
plt.show()

Diaqram №2 "Düzgün və hesablanmış cavablar"

Sadə xətti reqressiya tənliyinin həlli

Hər ay üçün sapmaların qrafikinə baxa bilərsiniz. Bizim vəziyyətimizdə ondan heç bir əhəmiyyətli praktiki dəyər əldə etməyəcəyik, lakin sadə xətti reqressiya tənliyinin gəlirin ilin ayından asılılığını nə dərəcədə yaxşı xarakterizə etdiyinə dair maraqları təmin edəcəyik.

Sapma qrafiki kodu

# определим функцию для формирования массива отклонений в процентах
def error_per_month(ab,x,y):
    sales_c = sales_count(ab,x,y)
    errors_percent = []
    for i in range(len(x)):
        errors_percent.append(100*(sales_c[i]-y[i])/y[i])
    return errors_percent

# построим график
print 'График№3 "Отклонения по-месячно, %"'
plt.gca().bar(x_us, error_per_month(ab_us,x_us,y_us), color='brown')
plt.xlabel('Months', size=16)
plt.ylabel('Calculation error, %', size=16)
plt.show()

Diaqram № 3 "Sayma,%"

Sadə xətti reqressiya tənliyinin həlli

Mükəmməl deyil, amma işimizi gördük.

Bir funksiya yazaq ki, əmsalları təyin edək Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli kitabxanadan istifadə edir saysız, daha dəqiq desək, iki funksiya yazacağıq: biri psevdo-ters matrisdən istifadə etməklə (proses hesablama baxımından mürəkkəb və qeyri-sabit olduğundan praktikada tövsiyə edilmir), digəri isə matris tənliyindən istifadə etməklə.

Analitik Həll Kodu (NumPy)

# для начала добавим столбец с не изменяющимся значением в 1. 
# Данный столбец нужен для того, чтобы не обрабатывать отдельно коэффицент a
vector_1 = np.ones((x_np.shape[0],1))
x_np = table_zero[['x']].values # на всякий случай приведем в первичный формат вектор x_np
x_np = np.hstack((vector_1,x_np))

# проверим то, что все сделали правильно
print vector_1[0:3]
print x_np[0:3]
print '***************************************'
print

# напишем функцию, которая определяет значения коэффициентов a и b с использованием псевдообратной матрицы
def pseudoinverse_matrix(X, y):
    # задаем явный формат матрицы признаков
    X = np.matrix(X)
    # определяем транспонированную матрицу
    XT = X.T
    # определяем квадратную матрицу
    XTX = XT*X
    # определяем псевдообратную матрицу
    inv = np.linalg.pinv(XTX)
    # задаем явный формат матрицы ответов
    y = np.matrix(y)
    # находим вектор весов
    return (inv*XT)*y

# запустим функцию
ab_np = pseudoinverse_matrix(x_np, y_np)
print ab_np
print '***************************************'
print

# напишем функцию, которая использует для решения матричное уравнение
def matrix_equation(X,y):
    a = np.dot(X.T, X)
    b = np.dot(X.T, y)
    return np.linalg.solve(a, b)

# запустим функцию
ab_np = matrix_equation(x_np,y_np)
print ab_np

Əmsalları müəyyən etmək üçün sərf olunan vaxtı müqayisə edin Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli, təqdim olunan 3 üsula görə.

Hesablama vaxtının hesablanması üçün kod

print ' 33[1m' + ' 33[4m' + "Время выполнения расчета коэффициентов без использования библиотеки NumPy:" + ' 33[0m'
% timeit ab_us = Kramer_method(x_us,y_us)
print '***************************************'
print
print ' 33[1m' + ' 33[4m' + "Время выполнения расчета коэффициентов с использованием псевдообратной матрицы:" + ' 33[0m'
%timeit ab_np = pseudoinverse_matrix(x_np, y_np)
print '***************************************'
print
print ' 33[1m' + ' 33[4m' + "Время выполнения расчета коэффициентов с использованием матричного уравнения:" + ' 33[0m'
%timeit ab_np = matrix_equation(x_np, y_np)

Sadə xətti reqressiya tənliyinin həlli

Kiçik bir məlumat miqdarında, Cramer metodundan istifadə edərək əmsalları tapan "öz-özünə yazılmış" funksiya irəli gəlir.

İndi əmsalları tapmaq üçün başqa yollara keçə bilərsiniz Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli.

gradient eniş

Əvvəlcə gradientin nə olduğunu müəyyən edək. Sadə şəkildə desək, gradient funksiyanın maksimum artım istiqamətini göstərən seqmentdir. Qradiyentin göründüyü yerdə yoxuşa dırmaşmağa bənzətməklə, dağın zirvəsinə ən dik qalxma var. Dağ nümunəsini inkişaf etdirərək, unutmayın ki, mümkün qədər tez aşağıya, yəni minimuma - funksiyanın artmadığı və azalmadığı yerə çatmaq üçün həqiqətən ən dik eniş lazımdır. Bu zaman törəmə sıfır olacaq. Ona görə də bizə qradiyent yox, antiqradient lazımdır. Antiqradienti tapmaq üçün sadəcə qradiyenti vurmaq lazımdır -1 (mənfi bir).

Diqqət edək ki, bir funksiyanın bir neçə minimumu ola bilər və aşağıda təklif olunan alqoritmə uyğun olaraq onlardan birinə enərək, tapılandan aşağı ola biləcək başqa bir minimum tapa bilməyəcəyik. Rahatlayın, təhlükədə deyilik! Bizim vəziyyətimizdə funksiyamızdan bəri vahid minimumla məşğul oluruq Sadə xətti reqressiya tənliyinin həlli qrafikdə adi paraboladır. Və hamımızın məktəb riyaziyyat kursundan çox yaxşı bildiyimiz kimi, parabolanın yalnız bir minimumu var.

Qradiyentin nə üçün lazım olduğunu və qradiyentin seqment olduğunu, yəni eyni əmsalları olan verilmiş koordinatları olan bir vektor olduğunu anladıqdan sonra Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli gradient enişini həyata keçirə bilərik.

Başlamazdan əvvəl enmə alqoritmi haqqında bir neçə cümlə oxumağı təklif edirəm:

  • Əmsalların koordinatlarını psevdo-təsadüfi olaraq təyin edirik Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli. Nümunəmizdə sıfıra yaxın əmsalları təyin edəcəyik. Bu ümumi bir təcrübədir, lakin hər bir işin öz təcrübəsi ola bilər.
  • Koordinatdan Sadə xətti reqressiya tənliyinin həlli nöqtədə 1-ci dərəcəli qismən törəmənin qiymətini çıxarın Sadə xətti reqressiya tənliyinin həlli. Deməli, törəmə müsbətdirsə, funksiya artır. Buna görə də, törəmənin dəyərini çıxararaq, böyümənin əks istiqamətində, yəni enmə istiqamətində hərəkət edəcəyik. Törəmə mənfi olarsa, bu nöqtədə funksiya azalır və törəmənin dəyərini çıxarır, biz enişə doğru irəliləyirik.
  • Bənzər bir əməliyyatı koordinatla həyata keçiririk Sadə xətti reqressiya tənliyinin həlli: nöqtədə qismən törəmənin qiymətini çıxarın Sadə xətti reqressiya tənliyinin həlli.
  • Minimumdan tullanmamaq və dərin kosmosa uçmamaq üçün addım ölçüsünü enmə istiqamətində təyin etmək lazımdır. Ümumiyyətlə, hesablamaların dəyərini azaltmaq üçün addımı necə düzgün qurmaq və eniş zamanı onu necə dəyişdirmək barədə bütöv bir məqalə yazmaq olar. Ancaq indi bir az fərqli vəzifəmiz var və addım ölçüsünü elmi "poke" üsulu ilə və ya sadə insanlarda deyildiyi kimi, empirik olaraq təyin edəcəyik.
  • Verilmiş koordinatlardan çıxdıqdan sonra Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli törəmələrin dəyərlərini çıxarsaq, yeni koordinatlar alırıq Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli. Artıq hesablanmış koordinatlardan növbəti addımı (çıxma) edirik. Və beləliklə, tələb olunan yaxınlaşma əldə olunana qədər dövr təkrar-təkrar başlayır.

Hamısı! İndi biz Mariana xəndəyinin ən dərin dərəsini axtarmağa hazırıq. Gəlin başlayaq.

Gradient eniş kodu

# напишем функцию градиентного спуска без использования библиотеки NumPy. 
# Функция на вход принимает диапазоны значений x,y, длину шага (по умолчанию=0,1), допустимую погрешность(tolerance)
def gradient_descent_usual(x_us,y_us,l=0.1,tolerance=0.000000000001):
    # сумма значений (все месяца)
    sx = sum(x_us)
    # сумма истинных ответов (выручка за весь период)
    sy = sum(y_us)
    # сумма произведения значений на истинные ответы
    list_xy = []
    [list_xy.append(x_us[i]*y_us[i]) for i in range(len(x_us))]
    sxy = sum(list_xy)
    # сумма квадратов значений
    list_x_sq = []
    [list_x_sq.append(x_us[i]**2) for i in range(len(x_us))]
    sx_sq = sum(list_x_sq)
    # количество значений
    num = len(x_us)
    # начальные значения коэффициентов, определенные псевдослучайным образом
    a = float(random.uniform(-0.5, 0.5))
    b = float(random.uniform(-0.5, 0.5))
    # создаем массив с ошибками, для старта используем значения 1 и 0
    # после завершения спуска стартовые значения удалим
    errors = [1,0]
    # запускаем цикл спуска
    # цикл работает до тех пор, пока отклонение последней ошибки суммы квадратов от предыдущей, не будет меньше tolerance
    while abs(errors[-1]-errors[-2]) > tolerance:
        a_step = a - l*(num*a + b*sx - sy)/num
        b_step = b - l*(a*sx + b*sx_sq - sxy)/num
        a = a_step
        b = b_step
        ab = [a,b]
        errors.append(errors_sq_Kramer_method(ab,x_us,y_us))
    return (ab),(errors[2:])

# запишем массив значений 
list_parametres_gradient_descence = gradient_descent_usual(x_us,y_us,l=0.1,tolerance=0.000000000001)


print ' 33[1m' + ' 33[4m' + "Значения коэффициентов a и b:" + ' 33[0m'
print 'a =', round(list_parametres_gradient_descence[0][0],3)
print 'b =', round(list_parametres_gradient_descence[0][1],3)
print


print ' 33[1m' + ' 33[4m' + "Сумма квадратов отклонений:" + ' 33[0m'
print round(list_parametres_gradient_descence[1][-1],3)
print



print ' 33[1m' + ' 33[4m' + "Количество итераций в градиентном спуске:" + ' 33[0m'
print len(list_parametres_gradient_descence[1])
print

Sadə xətti reqressiya tənliyinin həlli

Mariana xəndəyinin ən dibinə endik və orada əmsalların eyni dəyərlərini tapdıq Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlliəslində gözlənilən bir şeydir.

Gəlin başqa bir dalış edək, yalnız bu dəfə, bizim dərin dəniz vasitəmizin doldurulması başqa texnologiyalar olacaq, yəni kitabxana saysız.

Qradient Eniş Kodu (NumPy)

# перед тем определить функцию для градиентного спуска с использованием библиотеки NumPy, 
# напишем функцию определения суммы квадратов отклонений также с использованием NumPy
def error_square_numpy(ab,x_np,y_np):
    y_pred = np.dot(x_np,ab)
    error = y_pred - y_np
    return sum((error)**2)

# напишем функцию градиентного спуска с использованием библиотеки NumPy. 
# Функция на вход принимает диапазоны значений x,y, длину шага (по умолчанию=0,1), допустимую погрешность(tolerance)
def gradient_descent_numpy(x_np,y_np,l=0.1,tolerance=0.000000000001):
    # сумма значений (все месяца)
    sx = float(sum(x_np[:,1]))
    # сумма истинных ответов (выручка за весь период)
    sy = float(sum(y_np))
    # сумма произведения значений на истинные ответы
    sxy = x_np*y_np
    sxy = float(sum(sxy[:,1]))
    # сумма квадратов значений
    sx_sq = float(sum(x_np[:,1]**2))
    # количество значений
    num = float(x_np.shape[0])
    # начальные значения коэффициентов, определенные псевдослучайным образом
    a = float(random.uniform(-0.5, 0.5))
    b = float(random.uniform(-0.5, 0.5))
    # создаем массив с ошибками, для старта используем значения 1 и 0
    # после завершения спуска стартовые значения удалим
    errors = [1,0]
    # запускаем цикл спуска
    # цикл работает до тех пор, пока отклонение последней ошибки суммы квадратов от предыдущей, не будет меньше tolerance
    while abs(errors[-1]-errors[-2]) > tolerance:
        a_step = a - l*(num*a + b*sx - sy)/num
        b_step = b - l*(a*sx + b*sx_sq - sxy)/num
        a = a_step
        b = b_step
        ab = np.array([[a],[b]])
        errors.append(error_square_numpy(ab,x_np,y_np))
    return (ab),(errors[2:])

# запишем массив значений 
list_parametres_gradient_descence = gradient_descent_numpy(x_np,y_np,l=0.1,tolerance=0.000000000001)

print ' 33[1m' + ' 33[4m' + "Значения коэффициентов a и b:" + ' 33[0m'
print 'a =', round(list_parametres_gradient_descence[0][0],3)
print 'b =', round(list_parametres_gradient_descence[0][1],3)
print


print ' 33[1m' + ' 33[4m' + "Сумма квадратов отклонений:" + ' 33[0m'
print round(list_parametres_gradient_descence[1][-1],3)
print

print ' 33[1m' + ' 33[4m' + "Количество итераций в градиентном спуске:" + ' 33[0m'
print len(list_parametres_gradient_descence[1])
print

Sadə xətti reqressiya tənliyinin həlli
Əmsal dəyərləri Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli dəyişməzdirlər.

Qradiyentin enişi zamanı xətanın necə dəyişdiyinə, yəni hər addımda kvadrat kənara çıxanların cəminin necə dəyişdiyinə baxaq.

Cəmi Kvadrat Sapma Plotunun kodu

print 'График№4 "Сумма квадратов отклонений по-шагово"'
plt.plot(range(len(list_parametres_gradient_descence[1])), list_parametres_gradient_descence[1], color='red', lw=3)
plt.xlabel('Steps (Iteration)', size=16)
plt.ylabel('Sum of squared deviations', size=16)
plt.show()

Diaqram №4 "Qradient enişində kvadrat sapmaların cəmi"

Sadə xətti reqressiya tənliyinin həlli

Qrafikdə səhvin hər addımda azaldığını görürük və müəyyən sayda təkrarlamadan sonra demək olar ki, üfüqi xətt müşahidə edirik.

Nəhayət, kodun icra müddətindəki fərqi qiymətləndirək:

Zamanlama qradiyenti enişinin hesablanması üçün kod

print ' 33[1m' + ' 33[4m' + "Время выполнения градиентного спуска без использования библиотеки NumPy:" + ' 33[0m'
%timeit list_parametres_gradient_descence = gradient_descent_usual(x_us,y_us,l=0.1,tolerance=0.000000000001)
print '***************************************'
print

print ' 33[1m' + ' 33[4m' + "Время выполнения градиентного спуска с использованием библиотеки NumPy:" + ' 33[0m'
%timeit list_parametres_gradient_descence = gradient_descent_numpy(x_np,y_np,l=0.1,tolerance=0.000000000001)

Sadə xətti reqressiya tənliyinin həlli

Bəlkə də biz səhv edirik, amma yenə də kitabxanadan istifadə etməyən sadə "öz-özünə yazılmış" funksiya saysız kitabxanadan istifadə edərək funksiyanın hesablama vaxtından əvvəl saysız.

Ancaq biz hələ də dayanmırıq, lakin sadə xətti reqressiya tənliyini həll etmək üçün başqa bir maraqlı üsul öyrənməyə doğru irəliləyirik. Tanış!

Stokastik Qradient Eniş

Stokastik qradiyentin necə işlədiyini tez başa düşmək üçün onun adi gradient enişindən fərqlərini müəyyən etmək daha yaxşıdır. Biz, qradient enmə vəziyyətində, törəmələrinin tənliklərində Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli nümunədə mövcud olan bütün xüsusiyyətlərin və doğru cavabların dəyərlərinin cəmindən istifadə etdi (yəni bütün bunların cəmi Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli). Stokastik gradient enişində biz nümunədəki bütün dəyərlərdən istifadə etməyəcəyik, bunun əvəzinə psevdo-təsadüfi olaraq sözdə nümunə indeksini seçəcəyik və onun dəyərlərindən istifadə edəcəyik.

Məsələn, indeks 3 (üç) rəqəmi kimi müəyyən edilirsə, biz dəyərləri götürürük Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli, sonra dəyərləri törəmələrin tənliklərində əvəz edirik və yeni koordinatları təyin edirik. Sonra koordinatları təyin etdikdən sonra nümunə indeksini yenidən psevdo-təsadüfi şəkildə müəyyənləşdiririk, indeksə uyğun olan dəyərləri qismən diferensial tənliklərə əvəz edirik və koordinatları yeni bir şəkildə təyin edirik. Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli və s. yaşıl konvergensiyaya qədər. İlk baxışdan, ümumiyyətlə işləyə biləcəyi kimi görünə bilər, amma işləyir. Düzdür, qeyd etmək lazımdır ki, səhv hər addımda azalmır, amma əlbəttə ki, bir tendensiya var.

Stokastik qradiyentin adi enmə ilə müqayisədə üstünlükləri hansılardır? Nümunəmizin ölçüsü çox böyükdürsə və on minlərlə dəyərlə ölçülürsə, deməli, onların təsadüfi minini emal etmək bütün nümunədən daha asandır. Bu, stokastik gradient enişinin başladığı yerdir. Bizim vəziyyətimizdə, əlbəttə ki, böyük bir fərq görməyəcəyik.

Koda baxaq.

Stokastik Qradient Eniş kodu

# определим функцию стох.град.шага
def stoch_grad_step_usual(vector_init, x_us, ind, y_us, l):
#     выбираем значение икс, которое соответствует случайному значению параметра ind 
# (см.ф-цию stoch_grad_descent_usual)
    x = x_us[ind]
#     рассчитывыаем значение y (выручку), которая соответствует выбранному значению x
    y_pred = vector_init[0] + vector_init[1]*x_us[ind]
#     вычисляем ошибку расчетной выручки относительно представленной в выборке
    error = y_pred - y_us[ind]
#     определяем первую координату градиента ab
    grad_a = error
#     определяем вторую координату ab
    grad_b = x_us[ind]*error
#     вычисляем новый вектор коэффициентов
    vector_new = [vector_init[0]-l*grad_a, vector_init[1]-l*grad_b]
    return vector_new


# определим функцию стох.град.спуска
def stoch_grad_descent_usual(x_us, y_us, l=0.1, steps = 800):
#     для самого начала работы функции зададим начальные значения коэффициентов
    vector_init = [float(random.uniform(-0.5, 0.5)), float(random.uniform(-0.5, 0.5))]
    errors = []
#     запустим цикл спуска
# цикл расчитан на определенное количество шагов (steps)
    for i in range(steps):
        ind = random.choice(range(len(x_us)))
        new_vector = stoch_grad_step_usual(vector_init, x_us, ind, y_us, l)
        vector_init = new_vector
        errors.append(errors_sq_Kramer_method(vector_init,x_us,y_us))
    return (vector_init),(errors)


# запишем массив значений 
list_parametres_stoch_gradient_descence = stoch_grad_descent_usual(x_us, y_us, l=0.1, steps = 800)

print ' 33[1m' + ' 33[4m' + "Значения коэффициентов a и b:" + ' 33[0m'
print 'a =', round(list_parametres_stoch_gradient_descence[0][0],3)
print 'b =', round(list_parametres_stoch_gradient_descence[0][1],3)
print


print ' 33[1m' + ' 33[4m' + "Сумма квадратов отклонений:" + ' 33[0m'
print round(list_parametres_stoch_gradient_descence[1][-1],3)
print

print ' 33[1m' + ' 33[4m' + "Количество итераций в стохастическом градиентном спуске:" + ' 33[0m'
print len(list_parametres_stoch_gradient_descence[1])

Sadə xətti reqressiya tənliyinin həlli

Biz əmsallara diqqətlə baxırıq və özümüzü “Necə?” sualına tuturuq. Əmsalların digər dəyərlərini də aldıq Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli. Bəlkə stoxastik gradient eniş tənlik üçün daha optimal parametrlər tapıb? Təəssüf ki, heç bir. Kvadrat sapmaların cəminə baxmaq və əmsalların yeni dəyərləri ilə səhvin daha böyük olduğunu görmək kifayətdir. Ümidsizliyə tələsmirik. Gəlin xətanın dəyişmə qrafikini yaradaq.

Stokastik qradiyent enişdə kvadrat sapmaların cəminin qrafiki üçün kod

print 'График №5 "Сумма квадратов отклонений по-шагово"'
plt.plot(range(len(list_parametres_stoch_gradient_descence[1])), list_parametres_stoch_gradient_descence[1], color='red', lw=2)
plt.xlabel('Steps (Iteration)', size=16)
plt.ylabel('Sum of squared deviations', size=16)
plt.show()

Diaqram №5 "Stokastik Qradient Enişdə Kvadrat Sapmaların Cəmi"

Sadə xətti reqressiya tənliyinin həlli

Cədvələ baxdıqdan sonra hər şey öz yerinə düşür və indi hər şeyi düzəldəcəyik.

Bəs nə baş verdi? Aşağıdakılar baş verdi. Təsadüfi olaraq bir ayı seçdiyimiz zaman, alqoritmimiz gəlirin hesablanmasında səhvi azaltmağa çalışır ki, seçilmiş ay üçün. Sonra başqa bir ayı seçib hesablamağı təkrarlayırıq, lakin ikinci seçilmiş ay üçün səhvi azaldırıq. İndi xatırlayaq ki, ilk iki ayda sadə xətti reqressiya tənliyinin xəttindən əhəmiyyətli dərəcədə yayınırıq. Bu o deməkdir ki, bu iki aydan biri seçildikdə, onların hər birinin xətasını azaltmaqla, alqoritmimiz bütün nümunə üzrə xətanı ciddi şəkildə artırır. Bəs nə etməli? Cavab sadədir: enmə addımını azaltmaq lazımdır. Həqiqətən, enmə addımını azaltmaqla, xəta həm də yuxarı və ya aşağı “atlamağı” dayandıracaq. Daha doğrusu, “atlama” xətası dayanmayacaq, amma o qədər də tez etməyəcək :) Gəlin yoxlayaq.

SGD-ni daha kiçik bir addımla idarə etmək üçün kod

# запустим функцию, уменьшив шаг в 100 раз и увеличив количество шагов соответсвующе 
list_parametres_stoch_gradient_descence = stoch_grad_descent_usual(x_us, y_us, l=0.001, steps = 80000)

print ' 33[1m' + ' 33[4m' + "Значения коэффициентов a и b:" + ' 33[0m'
print 'a =', round(list_parametres_stoch_gradient_descence[0][0],3)
print 'b =', round(list_parametres_stoch_gradient_descence[0][1],3)
print


print ' 33[1m' + ' 33[4m' + "Сумма квадратов отклонений:" + ' 33[0m'
print round(list_parametres_stoch_gradient_descence[1][-1],3)
print



print ' 33[1m' + ' 33[4m' + "Количество итераций в стохастическом градиентном спуске:" + ' 33[0m'
print len(list_parametres_stoch_gradient_descence[1])

print 'График №6 "Сумма квадратов отклонений по-шагово"'
plt.plot(range(len(list_parametres_stoch_gradient_descence[1])), list_parametres_stoch_gradient_descence[1], color='red', lw=2)
plt.xlabel('Steps (Iteration)', size=16)
plt.ylabel('Sum of squared deviations', size=16)
plt.show()

Sadə xətti reqressiya tənliyinin həlli

Diaqram №6 "Stokastik qradiyent eniş üçün kvadrat sapmaların cəmi (80k addım)"

Sadə xətti reqressiya tənliyinin həlli

Şanslar yaxşılaşdı, lakin hələ də ideal deyil. Hipotetik olaraq, bu, bu şəkildə düzəldilə bilər. Məsələn, son 1000 iterasiyada minimum səhvin edildiyi əmsalların dəyərlərini seçirik. Düzdür, bunun üçün əmsalların dəyərlərini özləri yazmalıyıq. Biz bunu etməyəcəyik, əksinə, cədvələ diqqət yetirəcəyik. Hamar görünür və səhv bərabər şəkildə azalır. Əslində elə deyil. Gəlin ilk 1000 iterasiyaya baxaq və onları sonuncularla müqayisə edək.

SGD diaqramı üçün kod (ilk 1000 addım)

print 'График №7 "Сумма квадратов отклонений по-шагово. Первые 1000 итераций"'
plt.plot(range(len(list_parametres_stoch_gradient_descence[1][:1000])), 
         list_parametres_stoch_gradient_descence[1][:1000], color='red', lw=2)
plt.xlabel('Steps (Iteration)', size=16)
plt.ylabel('Sum of squared deviations', size=16)
plt.show()

print 'График №7 "Сумма квадратов отклонений по-шагово. Последние 1000 итераций"'
plt.plot(range(len(list_parametres_stoch_gradient_descence[1][-1000:])), 
         list_parametres_stoch_gradient_descence[1][-1000:], color='red', lw=2)
plt.xlabel('Steps (Iteration)', size=16)
plt.ylabel('Sum of squared deviations', size=16)
plt.show()

Qrafik № 7 "SGD-nin kvadrat sapmalarının cəmi (ilk 1000 addım)"

Sadə xətti reqressiya tənliyinin həlli

Diaqram №8 "SGD-nin kvadrat sapmalarının cəmi (son 1000 addım)"

Sadə xətti reqressiya tənliyinin həlli

Enişin ən əvvəlində səhvdə kifayət qədər vahid və kəskin azalma müşahidə edirik. Son təkrarlamalarda görürük ki, xəta 1,475 dəyərinin ətrafında və ətrafında gedir və bəzi məqamlarda hətta bu optimal dəyərə bərabər olur, lakin sonra yenə də yüksəlir... Yenə deyirəm, dəyərləri yaza bilərsiniz. əmsallar Sadə xətti reqressiya tənliyinin həlli и Sadə xətti reqressiya tənliyinin həlli, və sonra xətanın minimal olduğuları seçin. Bununla belə, daha böyük problemimiz var idi: optimala yaxın dəyərlər əldə etmək üçün 80 min addım atmalı olduq (koda baxın). Və bu, gradient enişlə əlaqədar stoxastik qradiyent enişdə hesablama vaxtına qənaət etmək ideyasına artıq ziddir. Nə düzəldilə və yaxşılaşdırıla bilər? Görmək çətin deyil ki, ilk iterasiyalarda davamlı olaraq aşağı düşürük və buna görə də, ilk təkrarlarda böyük bir addım buraxmalı və irəlilədikcə addımı azaltmalıyıq. Bu məqalədə bunu etməyəcəyik - artıq süründürülmüşdür. Arzu edənlər bunu necə edəcəyini özü fikirləşə bilər, çətin deyil 🙂

İndi kitabxanadan istifadə edərək stoxastik gradient enişini həyata keçirək saysız (və əvvəllər müəyyən etdiyimiz qayaların üstündən keçməyək)

Stokastik Qradient Eniş Kodu (NumPy)

# для начала напишем функцию градиентного шага
def stoch_grad_step_numpy(vector_init, X, ind, y, l):
    x = X[ind]
    y_pred = np.dot(x,vector_init)
    err = y_pred - y[ind]
    grad_a = err
    grad_b = x[1]*err
    return vector_init - l*np.array([grad_a, grad_b])

# определим функцию стохастического градиентного спуска
def stoch_grad_descent_numpy(X, y, l=0.1, steps = 800):
    vector_init = np.array([[np.random.randint(X.shape[0])], [np.random.randint(X.shape[0])]])
    errors = []
    for i in range(steps):
        ind = np.random.randint(X.shape[0])
        new_vector = stoch_grad_step_numpy(vector_init, X, ind, y, l)
        vector_init = new_vector
        errors.append(error_square_numpy(vector_init,X,y))
    return (vector_init), (errors)

# запишем массив значений 
list_parametres_stoch_gradient_descence = stoch_grad_descent_numpy(x_np, y_np, l=0.001, steps = 80000)

print ' 33[1m' + ' 33[4m' + "Значения коэффициентов a и b:" + ' 33[0m'
print 'a =', round(list_parametres_stoch_gradient_descence[0][0],3)
print 'b =', round(list_parametres_stoch_gradient_descence[0][1],3)
print


print ' 33[1m' + ' 33[4m' + "Сумма квадратов отклонений:" + ' 33[0m'
print round(list_parametres_stoch_gradient_descence[1][-1],3)
print



print ' 33[1m' + ' 33[4m' + "Количество итераций в стохастическом градиентном спуске:" + ' 33[0m'
print len(list_parametres_stoch_gradient_descence[1])
print

Sadə xətti reqressiya tənliyinin həlli

Dəyərlər istifadə etmədən enərkən demək olar ki, eyni olduğu ortaya çıxdı saysız. Bununla belə, bu məntiqlidir.

Stokastik gradient enişlərinin bizə nə qədər vaxt sərf etdiyini öyrənək.

SGD hesablama vaxtını təyin etmək üçün kod (80k addım)

print ' 33[1m' + ' 33[4m' +
"Время выполнения стохастического градиентного спуска без использования библиотеки NumPy:"
+ ' 33[0m'
%timeit list_parametres_stoch_gradient_descence = stoch_grad_descent_usual(x_us, y_us, l=0.001, steps = 80000)
print '***************************************'
print

print ' 33[1m' + ' 33[4m' +
"Время выполнения стохастического градиентного спуска с использованием библиотеки NumPy:"
+ ' 33[0m'
%timeit list_parametres_stoch_gradient_descence = stoch_grad_descent_numpy(x_np, y_np, l=0.001, steps = 80000)

Sadə xətti reqressiya tənliyinin həlli

Meşə nə qədər uzaqlaşsa, buludlar bir o qədər qaranlıq olur: yenə də "öz-özünə yazılmış" düstur ən yaxşı nəticəni göstərir. Bütün bunlar onu göstərir ki, kitabxanadan istifadənin daha incə üsulları olmalıdır. saysız, həqiqətən hesablama əməliyyatlarını sürətləndirir. Bu yazıda biz onlar haqqında öyrənməyəcəyik. Boş vaxtınızda düşünməli bir şey :)

Biz yekunlaşdırırıq

Xülasə etməzdən əvvəl çox güman ki, əziz oxucumuzdan yaranan bir suala cavab vermək istərdim. Nəyə görə, əslində, enişlərlə bu cür “əzablar”, əlimizdə belə güclü və sadə bir cihaz varsa, dağdan aşağı-yuxarı (əsasən aşağı) gəzib (əsasən aşağı) xəzinəni tapmaq lazımdır. bizi dərhal doğru yerə teleport edən analitik həll?

Bu sualın cavabı səthdə yatır. İndi biz əsl cavabın olduğu çox sadə bir nümunəni təhlil etdik Sadə xətti reqressiya tənliyinin həlli bir xüsusiyyətdən asılıdır Sadə xətti reqressiya tənliyinin həlli. Bunu həyatda tez-tez görmürsən, ona görə də təsəvvür edək ki, bizdə 2, 30, 50 və ya daha çox əlamət var. Buna hər bir xüsusiyyət üçün minlərlə, hətta on minlərlə dəyər əlavə edin. Bu halda, analitik həll testdən keçə və uğursuz ola bilər. Öz növbəsində, gradient enmə və onun dəyişmələri yavaş-yavaş, lakin şübhəsiz ki, bizi məqsədə - funksiyanın minimumuna yaxınlaşdıracaq. Sürətdən narahat olmayın - yəqin ki, biz hələ də addım uzunluğunu (yəni sürəti) təyin etməyə və tənzimləməyə imkan verəcək yolları təhlil edəcəyik.

İndi isə qısa xülasə üçün.

Birincisi, ümid edirəm ki, məqalədə təqdim olunan material yeni başlayan "məlumat alimlərinə" sadə (və təkcə deyil) xətti reqressiya tənliklərini necə həll etməyi başa düşməyə kömək edəcəkdir.

İkincisi, tənliyi həll etməyin bir neçə yoluna baxdıq. İndi vəziyyətdən asılı olaraq, tapşırığa ən uyğun olanı seçə bilərik.

Üçüncüsü, biz əlavə parametrlərin gücünü, yəni gradient enişinin addım uzunluğunu gördük. Bu parametrə laqeyd yanaşmaq olmaz. Yuxarıda qeyd edildiyi kimi, hesablama xərclərini azaltmaq üçün enmə zamanı addım uzunluğu dəyişdirilməlidir.

Dördüncüsü, bizim vəziyyətimizdə "öz-özünə yazılmış" funksiyalar hesablamaların ən yaxşı vaxt nəticəsini göstərdi. Bu, yəqin ki, kitabxananın imkanlarından ən peşəkar şəkildə istifadə edilməməsi ilə bağlıdır. saysız. Ancaq nə olursa olsun, nəticə özünü aşağıdakı kimi göstərir. Bir tərəfdən, bəzən müəyyən edilmiş fikirləri sorğulamağa dəyər, digər tərəfdən, həmişə hər şeyi çətinləşdirməyə dəyməz - əksinə, bəzən problemi həll etməyin daha sadə yolu daha təsirli olur. Məqsədimiz sadə xətti reqressiya tənliyini həll etmək üçün üç yanaşmanı təhlil etmək olduğundan, "öz-özünə yazılmış" funksiyaların istifadəsi bizim üçün kifayət idi.

Ədəbiyyat (və ya buna bənzər bir şey)

1. Xətti reqressiya

http://statistica.ru/theory/osnovy-lineynoy-regressii/

2. Ən kiçik kvadratlar üsulu

mathprofi.ru/method_naimenshih_kvadratov.html

3. Törəmə

www.mathprofi.ru/chastnye_proizvodnye_primery.html

4. Gradient

mathprofi.ru/proizvodnaja_po_napravleniju_i_gradient.html

5. Qradient eniş

habr.com/en/post/471458

habr.com/en/post/307312

artemarakcheev.com//2017-12-31/linear_regression

6. NumPy Kitabxanası

docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.linalg.solve.html

docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.linalg.pinv.html

pythonworld.com/numpy/2.html

Mənbə: www.habr.com

Добавить комментарий