Menyelesaikan persamaan regresi linear mudah

Artikel ini membincangkan beberapa cara untuk menentukan persamaan matematik bagi garis regresi mudah (berpasangan).

Semua kaedah untuk menyelesaikan persamaan yang dibincangkan di sini adalah berdasarkan kaedah kuasa dua terkecil. Mari kita nyatakan kaedah seperti berikut:

  • Penyelesaian analitikal
  • Keturunan Kecerunan
  • Penurunan kecerunan stokastik

Bagi setiap kaedah menyelesaikan persamaan garis lurus, artikel itu menyediakan pelbagai fungsi, yang kebanyakannya dibahagikan kepada yang ditulis tanpa menggunakan perpustakaan numpy dan yang digunakan untuk pengiraan numpy. Adalah dipercayai bahawa penggunaan mahir numpy akan mengurangkan kos pengkomputeran.

Semua kod yang diberikan dalam artikel ditulis dalam bahasa ular sawa 2.7 menggunakan Notebook Jupyter. Kod sumber dan fail dengan data sampel disiarkan pada Github

Artikel ini lebih ditujukan kepada kedua-dua pemula dan mereka yang telah secara beransur-ansur mula menguasai kajian bahagian yang sangat luas dalam kecerdasan buatan - pembelajaran mesin.

Untuk menggambarkan bahan, kami menggunakan contoh yang sangat mudah.

Contoh syarat

Kami mempunyai lima nilai yang mencirikan pergantungan Y daripada X (Jadual No. 1):

Jadual No. 1 "Syarat contoh"

Menyelesaikan persamaan regresi linear mudah

Kami akan menganggap bahawa nilai Menyelesaikan persamaan regresi linear mudah ialah bulan dalam setahun, dan Menyelesaikan persamaan regresi linear mudah β€” pendapatan bulan ini. Dalam erti kata lain, pendapatan bergantung pada bulan dalam setahun, dan Menyelesaikan persamaan regresi linear mudah - satu-satunya tanda di mana pendapatan bergantung.

Contohnya begitu-begitu, kedua-duanya dari sudut pergantungan bersyarat hasil pada bulan dalam setahun, dan dari sudut pandangan bilangan nilai - terdapat sangat sedikit daripada mereka. Walau bagaimanapun, penyederhanaan sedemikian akan memungkinkan, seperti yang mereka katakan, untuk menerangkan, tidak selalu dengan mudah, bahan yang diasimilasikan oleh pemula. Dan juga kesederhanaan nombor akan membolehkan mereka yang ingin menyelesaikan contoh di atas kertas tanpa kos buruh yang ketara.

Mari kita anggap bahawa pergantungan yang diberikan dalam contoh boleh dianggarkan dengan baik oleh persamaan matematik garis regresi mudah (berpasangan) dalam bentuk:

Menyelesaikan persamaan regresi linear mudah

mana Menyelesaikan persamaan regresi linear mudah adalah bulan di mana pendapatan diterima, Menyelesaikan persamaan regresi linear mudah - hasil yang sepadan dengan bulan, Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah ialah pekali regresi bagi garis anggaran.

Perhatikan bahawa pekali Menyelesaikan persamaan regresi linear mudah sering dipanggil cerun atau kecerunan garis anggaran; mewakili jumlah yang Menyelesaikan persamaan regresi linear mudah apabila ia berubah Menyelesaikan persamaan regresi linear mudah.

Jelas sekali, tugas kita dalam contoh adalah untuk memilih pekali sedemikian dalam persamaan Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah, di mana sisihan nilai hasil kami dikira mengikut bulan daripada jawapan sebenar, i.e. nilai yang ditunjukkan dalam sampel akan menjadi minimum.

Kaedah kuasa dua terkecil

Mengikut kaedah kuasa dua terkecil, sisihan hendaklah dikira dengan menduakannya. Teknik ini membolehkan anda mengelakkan pembatalan bersama penyimpangan jika mereka mempunyai tanda yang bertentangan. Sebagai contoh, jika dalam satu kes, sisihan adalah +5 (tambah lima), dan yang lain -5 (tolak lima), maka jumlah sisihan akan membatalkan satu sama lain dan berjumlah 0 (sifar). Adalah mungkin untuk tidak mengkuadratkan sisihan, tetapi menggunakan sifat modulus dan kemudian semua sisihan akan menjadi positif dan akan terkumpul. Kami tidak akan membincangkan perkara ini secara terperinci, tetapi hanya menunjukkan bahawa untuk kemudahan pengiraan, adalah lazim untuk mengkuadratkan sisihan.

Inilah rupa formula yang dengannya kita akan menentukan jumlah sisihan kuasa dua terkecil (ralat):

Menyelesaikan persamaan regresi linear mudah

mana Menyelesaikan persamaan regresi linear mudah ialah fungsi penghampiran jawapan benar (iaitu, hasil yang kami kira),

Menyelesaikan persamaan regresi linear mudah adalah jawapan yang benar (hasil yang disediakan dalam sampel),

Menyelesaikan persamaan regresi linear mudah ialah indeks sampel (bilangan bulan di mana sisihan ditentukan)

Mari bezakan fungsi, tentukan persamaan pembezaan separa, dan bersedia untuk beralih kepada penyelesaian analisis. Tetapi pertama-tama, mari kita bersiar-siar singkat tentang apa itu pembezaan dan ingat makna geometri terbitan itu.

Pembezaan

Pembezaan ialah operasi mencari terbitan bagi suatu fungsi.

Derivatif digunakan untuk apa? Derivatif fungsi mencirikan kadar perubahan fungsi dan memberitahu kita arahnya. Jika derivatif pada titik tertentu adalah positif, maka fungsi bertambah; jika tidak, fungsi berkurang. Dan semakin besar nilai terbitan mutlak, semakin tinggi kadar perubahan nilai fungsi, serta semakin curam kecerunan graf fungsi.

Sebagai contoh, di bawah keadaan sistem koordinat Cartesan, nilai terbitan pada titik M(0,0) adalah sama dengan +25 bermakna pada titik tertentu, apabila nilai dialihkan Menyelesaikan persamaan regresi linear mudah ke kanan oleh unit konvensional, nilai Menyelesaikan persamaan regresi linear mudah meningkat sebanyak 25 unit konvensional. Pada graf ia kelihatan seperti peningkatan yang agak curam dalam nilai Menyelesaikan persamaan regresi linear mudah dari titik tertentu.

Contoh yang lain. Nilai terbitan adalah sama -0,1 bermakna apabila disesarkan Menyelesaikan persamaan regresi linear mudah setiap satu unit konvensional, nilai Menyelesaikan persamaan regresi linear mudah berkurangan hanya 0,1 unit konvensional. Pada masa yang sama, pada graf fungsi, kita boleh melihat cerun menurun yang hampir tidak ketara. Melukis analogi dengan gunung, seolah-olah kita menuruni cerun yang lembut dari gunung, tidak seperti contoh sebelumnya, di mana kita terpaksa mendaki puncak yang sangat curam :)

Oleh itu, selepas membezakan fungsi Menyelesaikan persamaan regresi linear mudah secara kebetulan Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah, kami mentakrifkan persamaan pembezaan separa tertib pertama. Selepas menentukan persamaan, kami akan menerima sistem dua persamaan, dengan menyelesaikannya kami akan dapat memilih nilai pekali tersebut Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah, yang mana nilai derivatif yang sepadan pada titik tertentu berubah dengan jumlah yang sangat, sangat kecil, dan dalam kes penyelesaian analitik tidak berubah sama sekali. Dengan kata lain, fungsi ralat pada pekali yang ditemui akan mencapai minimum, kerana nilai derivatif separa pada titik ini akan sama dengan sifar.

Jadi, mengikut peraturan pembezaan, persamaan derivatif separa bagi tertib pertama berkenaan dengan pekali Menyelesaikan persamaan regresi linear mudah akan mengambil borang:

Menyelesaikan persamaan regresi linear mudah

Persamaan terbitan separa tertib pertama berkenaan dengan Menyelesaikan persamaan regresi linear mudah akan mengambil borang:

Menyelesaikan persamaan regresi linear mudah

Akibatnya, kami menerima sistem persamaan yang mempunyai penyelesaian analitik yang agak mudah:

mulakan{persamaan*}
mulakan{cases}
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
tamat{kes}
tamat{persamaan*}

Sebelum menyelesaikan persamaan, mari kita pramuat, semak sama ada pemuatan adalah betul, dan format data.

Memuatkan dan memformat data

Perlu diingatkan bahawa disebabkan oleh fakta bahawa untuk penyelesaian analitikal, dan seterusnya untuk kecerunan dan keturunan kecerunan stokastik, kami akan menggunakan kod dalam dua variasi: menggunakan perpustakaan numpy dan tanpa menggunakannya, maka kami memerlukan pemformatan data yang sesuai (lihat kod).

Pemuatan data dan kod pemprosesan

# ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ всС Π½ΡƒΠΆΠ½Ρ‹Π΅ Π½Π°ΠΌ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ
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 '********************************************'

Visualisasi

Sekarang, selepas kami, pertama, memuatkan data, kedua, menyemak ketepatan pemuatan dan akhirnya memformat data, kami akan menjalankan visualisasi pertama. Kaedah yang sering digunakan untuk ini ialah petak berpasangan perpustakaan Laut Laut. Dalam contoh kami, disebabkan bilangan yang terhad, tidak ada gunanya menggunakan perpustakaan Laut Laut. Kami akan menggunakan perpustakaan biasa Matplotlib dan lihat sahaja pada scatterplot.

Kod Scatterplot

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

Carta No. 1 "Pergantungan hasil pada bulan dalam setahun"

Menyelesaikan persamaan regresi linear mudah

Penyelesaian analitikal

Mari gunakan alat yang paling biasa dalam ular sawa dan selesaikan sistem persamaan:

mulakan{persamaan*}
mulakan{cases}
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
tamat{kes}
tamat{persamaan*}

Mengikut peraturan Cramer kita akan mencari penentu am, serta penentu oleh Menyelesaikan persamaan regresi linear mudah dan oleh Menyelesaikan persamaan regresi linear mudah, selepas itu, membahagikan penentu dengan Menyelesaikan persamaan regresi linear mudah kepada penentu am - cari pekali Menyelesaikan persamaan regresi linear mudah, begitu juga kita dapati pekali Menyelesaikan persamaan regresi linear mudah.

Kod penyelesaian analitikal

# ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для расчСта коэффициСнтов 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)

Inilah yang kami dapat:

Menyelesaikan persamaan regresi linear mudah

Jadi, nilai pekali telah dijumpai, jumlah sisihan kuasa dua telah ditetapkan. Mari kita lukis garis lurus pada histogram serakan mengikut pekali yang ditemui.

Kod baris regresi

# ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для формирования массива рассчСтных Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠΈ
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()

Carta No. 2 β€œJawapan yang betul dan dikira”

Menyelesaikan persamaan regresi linear mudah

Anda boleh melihat graf sisihan bagi setiap bulan. Dalam kes kami, kami tidak akan memperoleh sebarang nilai praktikal yang ketara daripadanya, tetapi kami akan memenuhi rasa ingin tahu kami tentang sejauh mana persamaan regresi linear mudah mencirikan pergantungan hasil pada bulan dalam setahun.

Kod carta sisihan

# ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для формирования массива ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠΉ Π² ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚Π°Ρ…
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()

Carta No. 3 "Sisihan, %"

Menyelesaikan persamaan regresi linear mudah

Tidak sempurna, tetapi kami menyelesaikan tugas kami.

Mari kita tulis fungsi yang, untuk menentukan pekali Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah menggunakan perpustakaan numpy, lebih tepat lagi, kami akan menulis dua fungsi: satu menggunakan matriks pseudoinverse (tidak disyorkan dalam amalan, kerana prosesnya kompleks dan tidak stabil dari segi pengiraan), satu lagi menggunakan persamaan matriks.

Kod Penyelesaian Analitikal (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

Mari kita bandingkan masa yang digunakan untuk menentukan pekali Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah, selaras dengan 3 kaedah yang dibentangkan.

Kod untuk mengira masa pengiraan

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)

Menyelesaikan persamaan regresi linear mudah

Dengan jumlah data yang kecil, fungsi "tulisan sendiri" muncul di hadapan, yang mencari pekali menggunakan kaedah Cramer.

Kini anda boleh beralih kepada cara lain untuk mencari pekali Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah.

Keturunan Kecerunan

Pertama, mari kita tentukan apa itu kecerunan. Ringkasnya, kecerunan ialah segmen yang menunjukkan arah pertumbuhan maksimum sesuatu fungsi. Secara analogi dengan mendaki gunung, di mana muka kecerunan adalah tempat pendakian paling curam ke puncak gunung itu. Membangunkan contoh dengan gunung, kita ingat bahawa sebenarnya kita memerlukan keturunan yang paling curam untuk sampai ke tanah pamah secepat mungkin, iaitu minimum - tempat di mana fungsi tidak meningkat atau berkurangan. Pada ketika ini derivatif akan sama dengan sifar. Oleh itu, kita tidak memerlukan kecerunan, tetapi antikecerunan. Untuk mencari antikecerunan anda hanya perlu mendarabkan kecerunan dengan -1 (tolak satu).

Marilah kita memberi perhatian kepada fakta bahawa fungsi boleh mempunyai beberapa minima, dan setelah turun ke salah satu daripadanya menggunakan algoritma yang dicadangkan di bawah, kita tidak akan dapat mencari minimum lain, yang mungkin lebih rendah daripada yang ditemui. Mari berehat, ini bukan ancaman kepada kami! Dalam kes kami, kami berurusan dengan minimum tunggal, sejak fungsi kami Menyelesaikan persamaan regresi linear mudah pada graf ialah parabola sekata. Dan seperti yang kita semua harus tahu dengan baik dari kursus matematik sekolah kita, parabola hanya mempunyai satu minimum.

Selepas kami mengetahui mengapa kami memerlukan kecerunan, dan juga bahawa kecerunan adalah segmen, iaitu, vektor dengan koordinat yang diberikan, yang merupakan pekali yang sama. Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah kita boleh melaksanakan penurunan kecerunan.

Sebelum memulakan, saya cadangkan membaca hanya beberapa ayat tentang algoritma keturunan:

  • Kami menentukan secara pseudo-rawak koordinat bagi pekali Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah. Dalam contoh kami, kami akan menentukan pekali berhampiran sifar. Ini adalah amalan biasa, tetapi setiap kes mungkin mempunyai amalannya sendiri.
  • Dari koordinat Menyelesaikan persamaan regresi linear mudah tolak nilai terbitan separa tertib pertama pada titik itu Menyelesaikan persamaan regresi linear mudah. Jadi, jika derivatifnya positif, maka fungsinya bertambah. Oleh itu, dengan menolak nilai terbitan, kita akan bergerak ke arah pertumbuhan yang bertentangan, iaitu ke arah keturunan. Jika terbitan adalah negatif, maka fungsi pada titik ini berkurangan dan dengan menolak nilai terbitan kita bergerak ke arah penurunan.
  • Kami menjalankan operasi yang sama dengan koordinat Menyelesaikan persamaan regresi linear mudah: tolak nilai terbitan separa pada titik Menyelesaikan persamaan regresi linear mudah.
  • Agar tidak melompat ke atas minimum dan terbang ke angkasa lepas, perlu menetapkan saiz langkah ke arah penurunan. Secara umum, anda boleh menulis keseluruhan artikel tentang cara menetapkan langkah dengan betul dan cara mengubahnya semasa proses penurunan untuk mengurangkan kos pengiraan. Tetapi sekarang kami mempunyai tugas yang sedikit berbeza di hadapan kami, dan kami akan menetapkan saiz langkah menggunakan kaedah saintifik "poke" atau, seperti yang mereka katakan dalam bahasa biasa, secara empirik.
  • Sebaik sahaja kita dari koordinat yang diberikan Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah tolak nilai derivatif, kita mendapat koordinat baharu Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah. Kami mengambil langkah seterusnya (penolakan), sudah dari koordinat yang dikira. Jadi kitaran bermula lagi dan lagi, sehingga penumpuan yang diperlukan dicapai.

Semua! Kini kami bersedia untuk pergi mencari gaung paling dalam di Palung Mariana. Mari kita mulakan.

Kod untuk keturunan kecerunan

# напишСм Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π³Ρ€Π°Π΄ΠΈΠ΅Π½Ρ‚Π½ΠΎΠ³ΠΎ спуска Π±Π΅Π· использования Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ 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

Menyelesaikan persamaan regresi linear mudah

Kami menyelam ke bahagian paling bawah Palung Mariana dan di sana kami menemui semua nilai pekali yang sama Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah, iaitu apa yang dijangkakan.

Mari kita menyelam lagi, cuma kali ini kenderaan laut dalam kita akan dipenuhi dengan teknologi lain iaitu perpustakaan numpy.

Kod untuk keturunan kecerunan (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

Menyelesaikan persamaan regresi linear mudah
Nilai pekali Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah tidak boleh diubah.

Mari kita lihat bagaimana ralat berubah semasa penurunan kecerunan, iaitu, bagaimana jumlah sisihan kuasa dua berubah dengan setiap langkah.

Kod untuk memplot jumlah sisihan kuasa dua

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

Graf No. 4 "Jumlah sisihan kuasa dua semasa penurunan kecerunan"

Menyelesaikan persamaan regresi linear mudah

Pada graf kita melihat bahawa dengan setiap langkah ralat berkurangan, dan selepas beberapa lelaran tertentu kita memerhatikan garis yang hampir mendatar.

Akhir sekali, mari kita anggarkan perbezaan dalam masa pelaksanaan kod:

Kod untuk menentukan masa pengiraan penurunan kecerunan

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)

Menyelesaikan persamaan regresi linear mudah

Mungkin kita melakukan sesuatu yang salah, tetapi sekali lagi ia adalah fungsi "tulisan rumah" yang mudah yang tidak menggunakan perpustakaan numpy mengatasi masa pengiraan fungsi menggunakan perpustakaan numpy.

Tetapi kita tidak berdiam diri, tetapi sedang bergerak ke arah mengkaji satu lagi cara yang menarik untuk menyelesaikan persamaan regresi linear mudah. jumpa!

Penurunan kecerunan stokastik

Untuk memahami dengan cepat prinsip operasi keturunan kecerunan stokastik, adalah lebih baik untuk menentukan perbezaannya daripada keturunan kecerunan biasa. Kami, dalam kes keturunan kecerunan, dalam persamaan derivatif bagi Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah menggunakan jumlah nilai semua ciri dan jawapan benar yang tersedia dalam sampel (iaitu, jumlah semua Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah). Dalam keturunan kecerunan stokastik, kami tidak akan menggunakan semua nilai yang ada dalam sampel, tetapi sebaliknya, pilih secara rawak pseudo indeks sampel dan gunakan nilainya.

Sebagai contoh, jika indeks ditentukan menjadi nombor 3 (tiga), maka kita mengambil nilainya Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah, kemudian kita menggantikan nilai ke dalam persamaan derivatif dan menentukan koordinat baharu. Kemudian, setelah menentukan koordinat, kami sekali lagi pseudo-rawak menentukan indeks sampel, menggantikan nilai yang sepadan dengan indeks ke dalam persamaan pembezaan separa, dan menentukan koordinat dengan cara yang baru Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah dan lain-lain. sehingga penumpuan bertukar hijau. Pada pandangan pertama, ia mungkin tidak kelihatan seperti ini boleh berfungsi sama sekali, tetapi ia berfungsi. Memang benar bahawa perlu diperhatikan bahawa ralat tidak berkurangan dengan setiap langkah, tetapi pasti ada kecenderungan.

Apakah kelebihan penurunan kecerunan stokastik berbanding konvensional? Jika saiz sampel kami sangat besar dan diukur dalam puluhan ribu nilai, maka lebih mudah untuk memproses, katakan, seribu rawak daripadanya, berbanding keseluruhan sampel. Di sinilah penurunan kecerunan stokastik dimainkan. Dalam kes kami, sudah tentu, kami tidak akan melihat banyak perbezaan.

Mari lihat kodnya.

Kod untuk keturunan kecerunan stokastik

# ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ стох.Π³Ρ€Π°Π΄.шага
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])

Menyelesaikan persamaan regresi linear mudah

Kami melihat dengan teliti pada pekali dan mendapati diri kami bertanya soalan "Bagaimana ini boleh berlaku?" Kami mendapat nilai pekali lain Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah. Mungkin keturunan kecerunan stokastik telah menemui parameter yang lebih optimum untuk persamaan? Malangnya tidak. Ia cukup untuk melihat jumlah sisihan kuasa dua dan melihat bahawa dengan nilai baru pekali, ralatnya lebih besar. Kami tidak tergesa-gesa untuk berputus asa. Mari bina graf perubahan ralat.

Kod untuk memplot jumlah sisihan kuasa dua dalam keturunan kecerunan stokastik

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

Graf No. 5 "Jumlah sisihan kuasa dua semasa penurunan kecerunan stokastik"

Menyelesaikan persamaan regresi linear mudah

Melihat kepada jadual, segala-galanya jatuh ke tempatnya dan kini kami akan membetulkan segala-galanya.

Jadi apa yang berlaku? Perkara berikut berlaku. Apabila kami memilih bulan secara rawak, maka untuk bulan yang dipilih itulah algoritma kami berusaha untuk mengurangkan ralat dalam mengira hasil. Kemudian kami memilih bulan lain dan ulangi pengiraan, tetapi kami mengurangkan ralat untuk bulan kedua yang dipilih. Sekarang ingat bahawa dua bulan pertama menyimpang dengan ketara daripada garis persamaan regresi linear mudah. Ini bermakna apabila mana-mana dua bulan ini dipilih, dengan mengurangkan ralat setiap satu daripadanya, algoritma kami secara serius meningkatkan ralat untuk keseluruhan sampel. Jadi apa yang perlu dilakukan? Jawapannya mudah: anda perlu mengurangkan langkah turun. Lagipun, dengan mengurangkan langkah penurunan, ralat juga akan berhenti "melompat" ke atas dan ke bawah. Atau sebaliknya, ralat "melompat" tidak akan berhenti, tetapi ia tidak akan melakukannya dengan cepat :) Mari semak.

Kod untuk menjalankan SGD dengan kenaikan yang lebih kecil

# запустим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΠ² шаг Π² 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()

Menyelesaikan persamaan regresi linear mudah

Graf No. 6 "Jumlah sisihan kuasa dua semasa penurunan kecerunan stokastik (80 ribu langkah)"

Menyelesaikan persamaan regresi linear mudah

Pekali telah bertambah baik, tetapi masih tidak ideal. Secara hipotesis, ini boleh diperbetulkan dengan cara ini. Kami memilih, sebagai contoh, dalam 1000 lelaran terakhir nilai pekali yang ralat minimum dibuat. Benar, untuk ini kita juga perlu menulis nilai pekali itu sendiri. Kami tidak akan melakukan ini, sebaliknya memberi perhatian kepada jadual. Ia kelihatan lancar dan ralat kelihatan berkurangan sama rata. Sebenarnya ini tidak benar. Mari lihat 1000 lelaran pertama dan bandingkan dengan yang terakhir.

Kod untuk carta SGD (1000 langkah pertama)

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

Graf No. 7 β€œJumlah sisihan kuasa dua SGD (1000 langkah pertama)”

Menyelesaikan persamaan regresi linear mudah

Graf No. 8 β€œJumlah sisihan kuasa dua SGD (1000 langkah terakhir)”

Menyelesaikan persamaan regresi linear mudah

Pada awal-awal keturunan, kami memerhatikan penurunan ralat yang agak seragam dan curam. Dalam lelaran terakhir, kita melihat bahawa ralat berlaku di sekitar nilai 1,475 dan pada beberapa ketika menyamai nilai optimum ini, tetapi kemudian ia masih meningkat... Saya ulangi, anda boleh menulis nilai-nilai pekali Menyelesaikan persamaan regresi linear mudah ΠΈ Menyelesaikan persamaan regresi linear mudah, dan kemudian pilih yang ralatnya adalah minimum. Walau bagaimanapun, kami mempunyai masalah yang lebih serius: kami terpaksa mengambil 80 ribu langkah (lihat kod) untuk mendapatkan nilai yang hampir optimum. Dan ini sudah bercanggah dengan idea untuk menjimatkan masa pengiraan dengan keturunan kecerunan stokastik berbanding dengan keturunan kecerunan. Apa yang boleh diperbetulkan dan diperbaiki? Tidak sukar untuk menyedari bahawa dalam lelaran pertama kita dengan yakin akan menurun dan, oleh itu, kita harus meninggalkan satu langkah besar dalam lelaran pertama dan mengurangkan langkah semasa kita bergerak ke hadapan. Kami tidak akan melakukan ini dalam artikel ini - ia sudah terlalu panjang. Mereka yang ingin boleh berfikir sendiri bagaimana untuk melakukan ini, ia tidak sukar :)

Sekarang mari kita lakukan penurunan kecerunan stokastik menggunakan perpustakaan numpy (dan jangan kita tersandung pada batu yang kita kenal pasti sebelum ini)

Kod untuk Keturunan Kecerunan Stokastik (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

Menyelesaikan persamaan regresi linear mudah

Nilainya ternyata hampir sama seperti ketika menurun tanpa menggunakan numpy. Walau bagaimanapun, ini adalah logik.

Mari kita ketahui berapa lama penurunan kecerunan stokastik mengambil masa kita.

Kod untuk menentukan masa pengiraan SGD (80 ribu langkah)

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)

Menyelesaikan persamaan regresi linear mudah

Semakin jauh ke dalam hutan, semakin gelap awan: sekali lagi, formula "tulisan sendiri" menunjukkan hasil terbaik. Semua ini menunjukkan bahawa mesti ada cara yang lebih halus untuk menggunakan perpustakaan numpy, yang benar-benar mempercepatkan operasi pengiraan. Dalam artikel ini kita tidak akan belajar tentang mereka. Akan ada sesuatu untuk difikirkan pada masa lapang anda :)

Meringkaskan

Sebelum meringkaskan, saya ingin menjawab soalan yang kemungkinan besar timbul daripada pembaca yang dikasihi. Mengapa, sebenarnya, "penyiksaan" seperti itu dengan keturunan, mengapa kita perlu berjalan naik dan turun gunung (kebanyakannya turun) untuk mencari tanah pamah yang berharga, jika kita ada di tangan kita alat yang kuat dan mudah, di bentuk penyelesaian analitikal, yang membawa kita serta-merta ke tempat Betul?

Jawapan kepada soalan ini terletak di permukaan. Sekarang kita telah melihat contoh yang sangat mudah, di mana jawapan yang benar adalah Menyelesaikan persamaan regresi linear mudah bergantung pada satu tanda Menyelesaikan persamaan regresi linear mudah. Anda tidak sering melihat ini dalam hidup, jadi mari bayangkan bahawa kita mempunyai 2, 30, 50 atau lebih tanda. Mari tambahkan pada ini beribu-ribu, malah berpuluh-puluh ribu nilai untuk setiap atribut. Dalam kes ini, penyelesaian analitik mungkin tidak dapat menahan ujian dan gagal. Sebaliknya, keturunan kecerunan dan variasinya akan secara perlahan tetapi pasti membawa kita lebih dekat kepada matlamat - fungsi minimum. Dan jangan risau tentang kelajuan - kami mungkin akan melihat cara yang membolehkan kami menetapkan dan mengawal panjang langkah (iaitu kelajuan).

Dan sekarang ringkasan ringkas sebenar.

Pertama, saya berharap bahan yang dibentangkan dalam artikel itu akan membantu memulakan "saintis data" dalam memahami cara menyelesaikan persamaan regresi linear yang mudah (dan bukan sahaja).

Kedua, kami melihat beberapa cara untuk menyelesaikan persamaan. Sekarang, bergantung kepada keadaan, kita boleh memilih yang paling sesuai untuk menyelesaikan masalah.

Ketiga, kami melihat kuasa tetapan tambahan, iaitu panjang langkah penurunan kecerunan. Parameter ini tidak boleh diabaikan. Seperti yang dinyatakan di atas, untuk mengurangkan kos pengiraan, panjang langkah perlu diubah semasa penurunan.

Keempat, dalam kes kami, fungsi "tulisan rumah" menunjukkan hasil masa terbaik untuk pengiraan. Ini mungkin disebabkan oleh penggunaan keupayaan perpustakaan yang paling profesional numpy. Tetapi walau bagaimanapun, kesimpulan berikut menunjukkan dirinya sendiri. Di satu pihak, kadangkala patut mempersoalkan pendapat yang telah ditetapkan, dan sebaliknya, ia tidak selalu bernilai merumitkan segala-galanya - sebaliknya, kadang-kadang cara yang lebih mudah untuk menyelesaikan masalah adalah lebih berkesan. Dan kerana matlamat kami adalah untuk menganalisis tiga pendekatan untuk menyelesaikan persamaan regresi linear yang mudah, penggunaan fungsi "tulisan sendiri" adalah cukup untuk kami.

Sastera (atau sesuatu seperti itu)

1. Regresi linear

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

2. Kaedah kuasa dua terkecil

mathprofi.ru/metod_naimenshih_kvadratov.html

3. Terbitan

www.mathprofi.ru/chastnye_proizvodnye_primery.html

4. Kecerunan

mathprofi.ru/proizvodnaja_po_napravleniju_i_gradient.html

5. Keturunan kecerunan

habr.com/ms/post/471458

habr.com/ms/post/307312

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

6. Perpustakaan 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

Sumber: www.habr.com

Tambah komen