Қарапайым сызықтық регрессия теңдеуін шешу

Мақалада қарапайым (жұпталған) регрессия сызығының математикалық теңдеуін анықтаудың бірнеше жолы қарастырылады.

Мұнда қарастырылатын теңдеуді шешудің барлық әдістері ең кіші квадраттар әдісіне негізделген. Әдістерді келесідей белгілейік:

  • Аналитикалық шешім
  • Градиенттің төмендеуі
  • Стохастикалық градиенттің түсуі

Түзу теңдеуін шешудің әрбір әдісі үшін мақалада әртүрлі функциялар қарастырылған, олар негізінен кітапхананы пайдаланбай жазылғандарға бөлінеді. сансыз және есептеулер үшін пайдаланатындар сансыз. Бұл шебер пайдалану деп саналады сансыз есептеу шығындарын азайтады.

Мақалада келтірілген барлық код тілде жазылған питон 2.7 қолдану арқылы Jupyter Notebook. Бастапқы код және үлгі деректері бар файл орналастырылған Github

Мақала жаңадан бастағандарға да, жасанды интеллекттегі өте кең бөлімді - машиналық оқытуды біртіндеп меңгере бастағандарға да бағытталған.

Материалды көрсету үшін біз өте қарапайым мысалды қолданамыз.

Мысал шарттары

Бізде тәуелділікті сипаттайтын бес құндылық бар Y от X (№1 кесте):

№1 кесте «Мысалы шарттар»

Қарапайым сызықтық регрессия теңдеуін шешу

құндылықтар деп есептейміз Қарапайым сызықтық регрессия теңдеуін шешу жыл айы болып табылады, және Қарапайым сызықтық регрессия теңдеуін шешу — осы айдағы табыс. Басқаша айтқанда, табыс жылдың айына байланысты және Қарапайым сызықтық регрессия теңдеуін шешу - кіріс тәуелді болатын жалғыз белгі.

Мысал осылайша, кірістің жылдың айына шартты тәуелділігі тұрғысынан да, құндылықтар саны тұрғысынан да - олардың саны өте аз. Дегенмен, мұндай жеңілдету, олар айтқандай, жаңадан бастағандар игеретін материалды әрдайым оңай емес түсіндіруге мүмкіндік береді. Сондай-ақ сандардың қарапайымдылығы қағаздағы мысалды айтарлықтай еңбек шығындарынсыз шешуге мүмкіндік береді.

Мысалда келтірілген тәуелділікті форманың қарапайым (жұпталған) регрессия сызығының математикалық теңдеуі арқылы өте жақсы жуықтауға болады деп есептейік:

Қарапайым сызықтық регрессия теңдеуін шешу

қайда Қарапайым сызықтық регрессия теңдеуін шешу табыс алынған ай, Қарапайым сызықтық регрессия теңдеуін шешу - айға сәйкес келетін кіріс; Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу есептелген сызықтың регрессия коэффициенттері болып табылады.

коэффициент екенін ескеріңіз Қарапайым сызықтық регрессия теңдеуін шешу жиі есептік сызықтың еңісі немесе градиенті деп аталады; сомасын көрсетеді Қарапайым сызықтық регрессия теңдеуін шешу өзгерген кезде Қарапайым сызықтық регрессия теңдеуін шешу.

Мысалдағы біздің міндетіміз теңдеудегі осындай коэффициенттерді таңдау екені анық Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу, бұл кезде біздің есептелген кіріс мәндерінің айлар бойынша нақты жауаптардан ауытқуы, яғни. үлгіде ұсынылған мәндер минималды болады.

Ең кіші квадрат әдісі

Ең кіші квадраттар әдісі бойынша ауытқуды квадраттау арқылы есептеу керек. Бұл әдіс қарама-қарсы белгілер болса, ауытқулардың өзара жойылуын болдырмауға мүмкіндік береді. Мысалы, егер бір жағдайда ауытқу болса +5 (плюс бес), ал екіншісінде -5 (минус бес), онда ауытқулардың қосындысы бірін-бірі жоққа шығарады және 0 (нөл) құрайды. Ауытқуды квадраттауға болмайды, бірақ модульдің қасиетін қолдануға болады, сонда барлық ауытқулар оң болады және жинақталады. Біз бұл мәселеге егжей-тегжейлі тоқталмаймыз, тек есептеулерге ыңғайлы болу үшін ауытқуды квадраттау әдеттегідей екенін көрсетеміз.

Квадраттық ауытқулардың (қателердің) ең аз сомасын анықтайтын формула осылай көрінеді:

Қарапайым сызықтық регрессия теңдеуін шешу

қайда Қарапайым сызықтық регрессия теңдеуін шешу шынайы жауаптардың жуықтау функциясы (яғни біз есептеген кіріс),

Қарапайым сызықтық регрессия теңдеуін шешу дұрыс жауаптар (үлгіде берілген кіріс),

Қарапайым сызықтық регрессия теңдеуін шешу іріктеу көрсеткіші болып табылады (ауытқу анықталған айдың саны)

Функцияны дифференциалдап, дербес дифференциалдық теңдеулерді анықтап, аналитикалық шешімге көшуге дайын болайық. Бірақ алдымен дифференциацияның не екеніне қысқаша экскурсия жасап, туындының геометриялық мағынасын еске түсірейік.

Дифференциация

Дифференциалдау – функцияның туындысын табу операциясы.

Туынды не үшін қолданылады? Функцияның туындысы функцияның өзгеру жылдамдығын сипаттайды және оның бағытын айтады. Егер берілген нүктедегі туынды оң болса, онда функция өседі, әйтпесе функция кемиді. Ал абсолютті туындының мәні неғұрлым үлкен болса, функция мәндерінің өзгеру жылдамдығы соғұрлым жоғары болады, сонымен қатар функция графигінің еңісі соғұрлым тік болады.

Мысалы, декарттық координаталар жүйесінің жағдайында М(0,0) нүктесіндегі туындының мәні мынаған тең. + 25 берілген нүктеде мән ауысқанда дегенді білдіреді Қарапайым сызықтық регрессия теңдеуін шешу шартты бірлік, мән бойынша оңға қарай Қарапайым сызықтық регрессия теңдеуін шешу 25 шартты бірлікке артады. Графикте бұл мәндердің айтарлықтай күрт өсуі сияқты көрінеді Қарапайым сызықтық регрессия теңдеуін шешу берілген нүктеден.

Тағы бір мысал. Туынды мән тең -0,1 ығысқанда дегенді білдіреді Қарапайым сызықтық регрессия теңдеуін шешу бір шартты бірлікке, мәнге Қарапайым сызықтық регрессия теңдеуін шешу 0,1 шартты бірлікке ғана төмендейді. Сонымен қатар, функцияның графигінде біз әрең байқалатын төмен еңісті байқаймыз. Тауға ұқсастық жасай отырып, біз өте тік шыңдарға шығуға тура келген алдыңғы мысалға қарағанда, таудан жұмсақ еңіспен өте баяу түсіп бара жатқандай боламыз :)

Осылайша, функцияны дифференциалданғаннан кейін Қарапайым сызықтық регрессия теңдеуін шешу коэффициенттер бойынша Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу, 1-ші ретті дербес дифференциалдық теңдеулерді анықтаймыз. Теңдеулерді анықтағаннан кейін біз екі теңдеу жүйесін аламыз, оны шешу арқылы біз коэффициенттердің осындай мәндерін таңдай аламыз. Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу, онда берілген нүктелердегі сәйкес туындылардың мәндері өте, өте аз мөлшерге өзгереді, ал аналитикалық шешім жағдайында мүлдем өзгермейді. Басқаша айтқанда, табылған коэффициенттердегі қателік функциясы минимумға жетеді, өйткені бұл нүктелердегі ішінара туындылардың мәндері нөлге тең болады.

Сонымен, дифференциалдау ережелеріне сәйкес коэффициентке қатысты 1-ші ретті дербес туынды теңдеу Қарапайым сызықтық регрессия теңдеуін шешу нысанда болады:

Қарапайым сызықтық регрессия теңдеуін шешу

қатысты 1-ші ретті дербес туынды теңдеу Қарапайым сызықтық регрессия теңдеуін шешу нысанда болады:

Қарапайым сызықтық регрессия теңдеуін шешу

Нәтижесінде біз өте қарапайым аналитикалық шешімі бар теңдеулер жүйесін алдық:

бастау{теңдеу*}
бастау{жағдайлар}
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
соңы{жағдайлар}
соңы{теңдеу*}

Теңдеуді шешпес бұрын, алдын ала жүктеп алайық, жүктеудің дұрыстығын тексеріп, деректерді пішімдейміз.

Деректерді жүктеу және пішімдеу

Айта кету керек, аналитикалық шешім үшін, содан кейін градиент және стохастикалық градиент түсіру үшін біз кодты екі нұсқада қолданамыз: кітапхананы пайдалану сансыз және оны қолданбай, бізге сәйкес деректерді пішімдеу қажет болады (кодты қараңыз).

Мәліметтерді жүктеу және өңдеу коды

# импортируем все нужные нам библиотеки
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 '********************************************'

Көрнекілік

Енді, біріншіден, деректерді жүктегеннен кейін, екіншіден, жүктеудің дұрыстығын тексеріп, соңында деректерді пішімдегеннен кейін біз бірінші визуализацияны орындаймыз. Бұл үшін жиі қолданылатын әдіс жұптық сызба кітапханалар Теңіз. Біздің мысалда саны шектеулі болғандықтан, кітапхананы пайдаланудың мәні жоқ Теңіз. Біз кәдімгі кітапхананы пайдаланамыз matplotlib және жай ғана шашырау сызбасына қараңыз.

Шашырау коды

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()

№1 диаграмма «Кірістің жыл айына тәуелділігі»

Қарапайым сызықтық регрессия теңдеуін шешу

Аналитикалық шешім

Ең көп таралған құралдарды қолданайық питон және теңдеулер жүйесін шешіңіз:

бастау{теңдеу*}
бастау{жағдайлар}
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
соңы{жағдайлар}
соңы{теңдеу*}

Крамер ережесі бойынша арқылы жалпы анықтауышты, сонымен қатар анықтауыштарды табамыз Қарапайым сызықтық регрессия теңдеуін шешу және бойынша Қарапайым сызықтық регрессия теңдеуін шешу, одан кейін анықтауышты бөлу Қарапайым сызықтық регрессия теңдеуін шешу жалпы анықтауышқа – коэффициентті табыңыз Қарапайым сызықтық регрессия теңдеуін шешу, дәл солай коэффициентті табамыз Қарапайым сызықтық регрессия теңдеуін шешу.

Аналитикалық шешім коды

# определим функцию для расчета коэффициентов 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)

Міне, бізде:

Қарапайым сызықтық регрессия теңдеуін шешу

Сонымен, коэффициенттердің мәндері табылды, квадраттық ауытқулардың қосындысы белгіленді. Табылған коэффициенттерге сәйкес шашырау гистограммасына түзу жүргізейік.

Регрессия жолының коды

# определим функцию для формирования массива рассчетных значений выручки
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()

№2 кесте «Дұрыс және есептелген жауаптар»

Қарапайым сызықтық регрессия теңдеуін шешу

Әр ай үшін ауытқу графигін қарауға болады. Біздің жағдайда біз одан ешқандай маңызды практикалық мән алмаймыз, бірақ біз қарапайым сызықтық регрессия теңдеуі кірістің жыл айына тәуелділігін қаншалықты жақсы сипаттайтыны туралы қызығушылығымызды қанағаттандырамыз.

Ауытқу диаграммасының коды

# определим функцию для формирования массива отклонений в процентах
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()

№3 диаграмма «Ауытқулар, %»

Қарапайым сызықтық регрессия теңдеуін шешу

Мінсіз емес, бірақ біз тапсырманы орындадық.

Коэффициенттерін анықтау үшін функцияны жазайық Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу кітапхананы пайдаланады сансыз, дәлірек айтсақ, біз екі функцияны жазамыз: біреуі жалған кері матрицаны (практикада ұсынылмайды, өйткені процесс есептеу тұрғысынан күрделі және тұрақсыз), екіншісі матрицалық теңдеуді пайдаланады.

Аналитикалық шешім коды (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

Коэффициенттерді анықтауға кеткен уақытты салыстырайық Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу, ұсынылған 3 әдіске сәйкес.

Есептеу уақытын есептеу коды

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)

Қарапайым сызықтық регрессия теңдеуін шешу

Деректер саны аз болса, Крамер әдісі арқылы коэффициенттерді табатын «өздігінен жазылған» функция алға шығады.

Енді коэффициенттерді табудың басқа тәсілдеріне көшуге болады Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу.

Градиенттің төмендеуі

Алдымен градиенттің не екенін анықтайық. Қарапайым тілмен айтқанда, градиент – функцияның максималды өсу бағытын көрсететін сегмент. Тауға шығуға ұқсастық бойынша, градиент беттері таудың басына ең тік көтерілетін жер. Таумен мысалды дамыта отырып, біз шын мәнінде ойпатқа мүмкіндігінше тез жету үшін ең тік түсу қажет екенін, яғни минимум - функцияның артпайтын немесе азаймайтын жерін еске түсіреміз. Бұл кезде туынды нөлге тең болады. Сондықтан бізге градиент емес, антиградиент қажет. Антиградиентті табу үшін градиентті көбейту керек -1 (минус бір).

Функцияның бірнеше минимумдары болуы мүмкін екеніне назар аударайық және төменде ұсынылған алгоритмді қолдана отырып, олардың біреуіне түскеннен кейін біз басқа минимумды таба алмаймыз, ол табылғаннан төмен болуы мүмкін. Демалайық, бұл бізге қауіп төндірмейді! Біздің жағдайда біз бір минимуммен айналысамыз, өйткені біздің функциямыз Қарапайым сызықтық регрессия теңдеуін шешу графикте дұрыс парабола берілген. Біздің мектептегі математика курсынан бәріміз жақсы білуіміз керек, параболаның бір ғана минимумы бар.

Бізге градиент не үшін қажет екенін, сондай-ақ градиент сегмент екенін, яғни координаталары берілген вектор екенін анықтағаннан кейін, дәл сол коэффициенттер. Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу градиентті түсіруді жүзеге асыра аламыз.

Бастамас бұрын мен төмендеу алгоритмі туралы бірнеше сөйлемді оқуды ұсынамын:

  • Біз коэффициенттердің координаталарын жалған кездейсоқ түрде анықтаймыз Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу. Біздің мысалда біз нөлге жақын коэффициенттерді анықтаймыз. Бұл әдеттегі тәжірибе, бірақ әр жағдайда өз тәжірибесі болуы мүмкін.
  • Координатадан Қарапайым сызықтық регрессия теңдеуін шешу нүктесіндегі 1-ші ретті ішінара туындының мәнін алып тастаңыз Қарапайым сызықтық регрессия теңдеуін шешу. Демек, туынды оң болса, онда функция артады. Демек, туындының мәнін шегеру арқылы өсудің қарама-қарсы бағытына, яғни төмендеу бағытына қарай жылжимыз. Егер туынды теріс болса, онда бұл нүктедегі функция төмендейді және туындының мәнін алып тастау арқылы біз төмендеу бағытында қозғаламыз.
  • Біз ұқсас операцияны координатпен орындаймыз Қарапайым сызықтық регрессия теңдеуін шешу: нүктедегі ішінара туындының мәнін алып тастаңыз Қарапайым сызықтық регрессия теңдеуін шешу.
  • Минимумнан секіріп, терең кеңістікке ұшып кетпеу үшін қадам өлшемін түсу бағытында орнату қажет. Тұтастай алғанда, есептеу шығындарын азайту үшін қадамды қалай дұрыс орнату және оны түсіру процесінде қалай өзгерту керектігі туралы толық мақала жазуға болады. Бірақ қазір біздің алдымызда сәл басқаша міндет тұр және біз қадам өлшемін ғылыми әдіспен «пок» немесе олар айтқандай, эмпирикалық түрде белгілейміз.
  • Біз берілген координаталардан шыққаннан кейін Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу туындылардың мәндерін алып тастасақ, жаңа координаталар аламыз Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу. Біз есептелген координаталардан келесі қадамды (алу) жасаймыз. Осылайша цикл қажетті конвергенцияға жеткенше қайта-қайта басталады.

Барлық! Енді біз Мариана шұңқырының ең терең шатқалын іздеуге дайынбыз. Бастайық.

Градиенттің түсу коды

# напишем функцию градиентного спуска без использования библиотеки 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

Қарапайым сызықтық регрессия теңдеуін шешу

Біз Мариана шұңқырының ең түбіне сүңгіп, сол жерден бірдей коэффициент мәндерін таптық Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу, бұл дәл күтуге болатын нәрсе.

Тағы бір сүңгіп көрейік, тек осы жолы біздің терең теңіз көлігіміз басқа технологиялармен, атап айтқанда кітапханамен толтырылады. сансыз.

Градиенттің түсу коды (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

Қарапайым сызықтық регрессия теңдеуін шешу
Коэффицент мәндері Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу өзгермейтін.

Градиенттің түсуі кезінде қатенің қалай өзгергенін, яғни әр қадам сайын квадраттық ауытқулардың қосындысы қалай өзгергенін қарастырайық.

Квадраттық ауытқулардың қосындыларын салу коды

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()

График №4 «Градиенттің түсуі кезіндегі квадраттық ауытқулардың қосындысы»

Қарапайым сызықтық регрессия теңдеуін шешу

Графикте біз әрбір қадам сайын қатенің азайғанын көреміз және белгілі бір итерациялар санынан кейін біз дерлік көлденең сызықты байқаймыз.

Соңында, кодты орындау уақытындағы айырмашылықты бағалайық:

Градиенттің түсуін есептеу уақытын анықтауға арналған код

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)

Қарапайым сызықтық регрессия теңдеуін шешу

Мүмкін біз бірдеңе дұрыс емес істеп жатырмыз, бірақ бұл кітапхананы пайдаланбайтын қарапайым «үйде жазылған» функция. сансыз кітапхананы пайдаланып функцияның есептеу уақытынан асып түседі сансыз.

Бірақ біз бір орында тұрған жоқпыз, бірақ қарапайым сызықтық регрессия теңдеуін шешудің тағы бір қызықты әдісін зерттеуге бет бұрып жатырмыз. Танысыңыз!

Стохастикалық градиенттің түсуі

Стохастикалық градиенттік түсірудің жұмыс істеу принципін тез түсіну үшін оның қарапайым градиенттік түсуден айырмашылығын анықтаған дұрыс. Біз, градиенттік төмендеу жағдайында, туындыларының теңдеуінде Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу үлгіде бар барлық мүмкіндіктер мен шынайы жауаптардың мәндерінің қосындысын пайдаланды (яғни, барлығының қосындысы Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу). Стохастикалық градиентті түсіру кезінде біз үлгідегі барлық мәндерді пайдаланбаймыз, оның орнына псевдокездейсоқ таңдап алынған индекс деп аталатынды таңдап, оның мәндерін пайдаланамыз.

Мысалы, егер индекс 3 (үш) саны болып анықталса, онда біз мәндерді аламыз Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу, содан кейін біз мәндерді туынды теңдеулерге ауыстырамыз және жаңа координаттарды анықтаймыз. Содан кейін координаталарды анықтай отырып, біз тағы да псевдокездейсоқ таңдамалы индексті анықтаймыз, индекске сәйкес мәндерді ішінара дифференциалдық теңдеулерге ауыстырамыз және координаталарды жаңа әдіспен анықтаймыз Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу және т.б. конвергенция жасыл түске боялғанша. Бір қарағанда, бұл мүлдем жұмыс істемейтін сияқты көрінуі мүмкін, бірақ солай. Қателік қадам сайын азаймайтынын айта кеткен жөн, бірақ тенденция бар екені сөзсіз.

Стохастикалық градиент түсудің әдеттегіден қандай артықшылығы бар? Егер біздің іріктеме көлемі өте үлкен болса және ондаған мың мәндермен өлшенсе, онда бүкіл іріктеуден гөрі, айталық, олардың кездейсоқ мыңын өңдеу әлдеқайда оңай. Бұл жерде стохастикалық градиенттің түсуі пайда болады. Біздің жағдайда, әрине, біз көп айырмашылықты байқамаймыз.

Кодты қарастырайық.

Стохастикалық градиенттің түсу коды

# определим функцию стох.град.шага
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])

Қарапайым сызықтық регрессия теңдеуін шешу

Біз коэффициенттерге мұқият қарап, «Бұл қалай болуы мүмкін?» Деген сұрақты қоямыз. Басқа коэффициент мәндерін алдық Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу. Мүмкін стохастикалық градиенттің түсуі теңдеу үшін оңтайлы параметрлерді тапқан шығар? Өкінішке орай жоқ. Квадраттық ауытқулардың қосындысына қарап, коэффициенттердің жаңа мәндерімен қатенің үлкенірек екенін көру жеткілікті. Біз үмітсіздікке асықпаймыз. Қатені өзгерту графигін құрастырайық.

Стохастикалық градиенттік төмендеу кезінде квадраттық ауытқулардың қосындысын құру коды

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()

График №5 «Стохастикалық градиенттің түсуі кезіндегі квадраттық ауытқулар сомасы»

Қарапайым сызықтық регрессия теңдеуін шешу

Кестеге қарасақ, бәрі өз орнына келеді, енді бәрін жөндейміз.

Сонымен не болды? Келесі оқиға болды. Кездейсоқ бір айды таңдаған кезде, біздің алгоритміміз кірісті есептеудегі қатені азайтуға тырысады. Содан кейін біз тағы бір айды таңдап, есептеуді қайталаймыз, бірақ біз екінші таңдалған ай үшін қатені азайтамыз. Енді алғашқы екі ай қарапайым сызықтық регрессия теңдеуінің сызығынан айтарлықтай ауытқығанын есте сақтаңыз. Бұл осы екі айдың кез келгенін таңдағанда, олардың әрқайсысының қатесін азайту арқылы біздің алгоритміміз бүкіл үлгідегі қатені айтарлықтай арттырады дегенді білдіреді. Сонымен не істеу керек? Жауап қарапайым: түсу қадамын азайту керек. Өйткені, төмендеу қадамын азайту арқылы қате жоғары және төмен «секіруді» тоқтатады. Дәлірек айтқанда, «секіру» қатесі тоқтамайды, бірақ оны тез жасамайды :) Тексерейік.

Шағын қадамдармен SGD іске қосу коды

# запустим функцию, уменьшив шаг в 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()

Қарапайым сызықтық регрессия теңдеуін шешу

График №6 «Стохастикалық градиенттің түсуі кезіндегі квадраттық ауытқулар сомасы (80 мың қадам)»

Қарапайым сызықтық регрессия теңдеуін шешу

Коэффиценттер жақсарды, бірақ әлі де идеалды емес. Гипотетикалық түрде, мұны осылай түзетуге болады. Біз, мысалы, соңғы 1000 итерацияда ең аз қателік жіберілген коэффициенттердің мәндерін таңдаймыз. Рас, бұл үшін біз коэффициенттердің мәндерін де жазуымыз керек. Біз мұны істемейміз, керісінше, кестеге назар аударамыз. Бұл тегіс көрінеді және қате біркелкі азаяды. Шындығында бұл дұрыс емес. Алғашқы 1000 итерацияны қарастырайық және оларды соңғысымен салыстырайық.

SGD диаграммасының коды (алғашқы 1000 қадам)

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()

График № 7 «СGD квадраттық ауытқулар сомасы (алғашқы 1000 қадам)»

Қарапайым сызықтық регрессия теңдеуін шешу

График №8 «SGD квадраттық ауытқуларының сомасы (соңғы 1000 қадам)»

Қарапайым сызықтық регрессия теңдеуін шешу

Түсудің ең басында біз қателіктің айтарлықтай біркелкі және күрт төмендеуін байқаймыз. Соңғы итерацияларда қатенің 1,475 мәнін айналып өтетінін және кейбір сәттерде тіпті осы оңтайлы мәнге тең келетінін көреміз, бірақ содан кейін ол әлі де көтеріледі ... Қайталап айтамын, сіз мәндерді жаза аласыз коэффициенттер Қарапайым сызықтық регрессия теңдеуін шешу и Қарапайым сызықтық регрессия теңдеуін шешу, содан кейін қатесі аз болатындарды таңдаңыз. Дегенмен, бізде күрделі мәселе болды: оңтайлы мәндерге жақындау үшін бізге 80 мың қадам жасау керек болды (кодты қараңыз). Және бұл қазірдің өзінде градиенттің түсуіне қатысты стохастикалық градиенттің түсуімен есептеу уақытын үнемдеу идеясына қайшы келеді. Нені түзетуге және жақсартуға болады? Бірінші итерацияларда біз сенімді түрде төмендеп жатқанымызды байқау қиын емес, сондықтан бірінші итерацияларда үлкен қадам қалдырып, алға қарай қадамды азайту керек. Біз бұл мақалада мұны жасамаймыз - бұл тым ұзақ. Қалағандар мұны қалай жасау керектігін өздері ойлап алады, бұл қиын емес :)

Енді кітапхананы пайдаланып стохастикалық градиентті түсіруді орындайық сансыз (және біз бұрын анықтаған тастардан сүрінбейік)

Стохастикалық градиенттің түсу коды (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

Қарапайым сызықтық регрессия теңдеуін шешу

Мәндер қолданбай төмендеу кезіндегідей болды сансыз. Дегенмен, бұл логикалық.

Стохастикалық градиенттің түсуі қанша уақытқа созылғанын білейік.

SGD есептеу уақытын анықтау коды (80 мың қадам)

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)

Қарапайым сызықтық регрессия теңдеуін шешу

Орманға неғұрлым ұзағырақ болса, бұлттар соғұрлым қараңғы болады: тағы да «өзін-өзі жазған» формула ең жақсы нәтижені көрсетеді. Мұның бәрі кітапхананы пайдаланудың бұдан да нәзік жолдары болуы керек екенін көрсетеді сансыз, бұл есептеу операцияларын шынымен жылдамдатады. Бұл мақалада біз олар туралы білмейміз. Бос уақытыңызда ойланатын нәрсе болады :)

Қорытындылайық

Қорытындыламас бұрын, құрметті оқырманымыздан туындаған сұраққа жауап бергім келеді. Неліктен, шын мәнінде, мұндай «азаптау» төмен қарай, неліктен біздің қолымызда осындай қуатты және қарапайым құрылғы болса, қазыналы ойпатты табу үшін таудан (негізінен төмен) жоғары және төмен жүру керек. Бізді бірден дұрыс жерге апаратын аналитикалық шешімнің түрі?

Бұл сұрақтың жауабы бетінде жатыр. Енді біз өте қарапайым мысалды қарастырдық, онда дұрыс жауап бар Қарапайым сызықтық регрессия теңдеуін шешу бір белгіге байланысты Қарапайым сызықтық регрессия теңдеуін шешу. Сіз мұны өмірде жиі кездестіре бермейсіз, сондықтан бізде 2, 30, 50 немесе одан да көп белгілер бар деп елестетейік. Осыған әр атрибут үшін мыңдаған, тіпті он мыңдаған мәндерді қосайық. Бұл жағдайда аналитикалық шешім сынаққа төтеп бермеуі және сәтсіздікке ұшырауы мүмкін. Өз кезегінде, градиенттің төмендеуі және оның вариациялары баяу, бірақ сөзсіз бізді мақсатқа - функцияның минимумына жақындатады. Жылдамдық туралы алаңдамаңыз - біз қадам ұзындығын (яғни жылдамдықты) орнатуға және реттеуге мүмкіндік беретін жолдарды қарастыратын шығармыз.

Ал енді нақты қысқаша қорытынды.

Біріншіден, мақалада ұсынылған материал қарапайым (тек қана емес) сызықтық регрессия теңдеулерін шешу жолын түсінуде «деректер ғалымдарына» көмектеседі деп үміттенемін.

Екіншіден, теңдеуді шешудің бірнеше жолдарын қарастырдық. Енді жағдайға байланысты мәселені шешу үшін ең қолайлысын таңдай аламыз.

Үшіншіден, біз қосымша параметрлердің күшін, атап айтқанда градиенттің түсу қадамының ұзындығын көрдік. Бұл параметрді елемеуге болмайды. Жоғарыда атап өтілгендей, есептеулердің құнын төмендету үшін түсу кезінде қадам ұзындығын өзгерту керек.

Төртіншіден, біздің жағдайда «үйде жазылған» функциялар есептеулер үшін ең жақсы уақыт нәтижелерін көрсетті. Бұл кітапхананың мүмкіндіктерін кәсіби түрде пайдаланбауынан болса керек сансыз. Қалай болғанда да, келесі қорытынды өзін көрсетеді. Бір жағынан, кейде қалыптасқан пікірлерге күмән келтіруге тұрарлық, ал екінші жағынан, әрқашан бәрін қиындатудың қажеті жоқ - керісінше, кейде мәселені шешудің қарапайым әдісі тиімдірек. Біздің мақсатымыз қарапайым сызықтық регрессия теңдеуін шешудің үш тәсілін талдау болғандықтан, біз үшін «өздігінен жазылған» функцияларды пайдалану жеткілікті болды.

Әдебиет (немесе осындай нәрсе)

1. Сызықтық регрессия

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

2. Ең кіші квадраттар әдісі

mathprofi.ru/metod_naimenshih_kvadratov.html

3. Туынды

www.mathprofi.ru/chastnye_proizvodnye_primery.html

4. Градиент

mathprofi.ru/proizvodnaja_po_napravleniju_i_gradient.html

5. Градиенттің түсуі

habr.com/en/post/471458

habr.com/en/post/307312

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

6. NumPy кітапханасы

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.ru/numpy/2.html

Ақпарат көзі: www.habr.com

пікір қалдыру