Rezoud ekwasyon senp regression lineyè

Atik la diskite sou plizyè fason pou detèmine ekwasyon matematik yon liy regresyon senp (pèch).

Tout metòd pou rezoud ekwasyon yo diskite isit la baze sou metòd pi piti kare yo. Ann endike metòd yo jan sa a:

  • Solisyon analyse
  • Desandan gradyan
  • Desandan gradyan stochastic

Pou chak metòd pou rezoud ekwasyon yon liy dwat, atik la bay divès fonksyon, ki se sitou divize an sa yo ki ekri san yo pa itilize bibliyotèk la. numpy ak sa yo ki itilize pou kalkil numpy. Yo kwè ke itilizasyon abil numpy ap redwi depans informatique yo.

Tout kòd yo bay nan atik la ekri nan lang lan piton 2.7 lè l sèvi avèk Kaye Jupyter. Kòd sous la ak dosye ak done echantiyon yo afiche sou Github

Atik la se plis ki vize a tou de débutan ak moun ki te deja piti piti kòmanse metrize etid la nan yon seksyon trè laj nan entèlijans atifisyèl - aprantisaj machin.

Pou ilistre materyèl la, nou itilize yon egzanp trè senp.

Egzanp kondisyon yo

Nou gen senk valè ki karakterize depandans Y soti nan X (Tablo No 1):

Tablo No 1 "Egzanp kondisyon"

Rezoud ekwasyon senp regression lineyè

Nou pral asime ke valè yo Rezoud ekwasyon senp regression lineyè se mwa nan ane a, epi Rezoud ekwasyon senp regression lineyè - revni mwa sa a. Nan lòt mo, revni depann sou mwa a nan ane a, ak Rezoud ekwasyon senp regression lineyè - siy la sèlman sou ki revni depann.

Egzanp la se konsa-konsa, tou de nan pwen de vi depandans kondisyonèl nan revni sou mwa a nan ane a, ak nan pwen de vi nan kantite valè - gen anpil nan yo. Sepandan, tankou yon senplifikasyon pral fè li posib, jan yo di, yo eksplike, pa toujou ak fasilite, materyèl la ke débutan asimile. Epi tou senplisite nimewo yo pral pèmèt moun ki vle rezoud egzanp lan sou papye san yo pa depans travay enpòtan.

Ann sipoze ke depandans yo bay nan egzanp lan ka byen apwoksimasyon pa ekwasyon matematik yon senp (pè) liy regresyon fòm nan:

Rezoud ekwasyon senp regression lineyè

kote Rezoud ekwasyon senp regression lineyè se mwa kote revni a te resevwa, Rezoud ekwasyon senp regression lineyè - revni ki koresponn ak mwa a, Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè se koyefisyan regresyon liy estime a.

Remake byen ke koyefisyan an Rezoud ekwasyon senp regression lineyè yo rele souvan pant oswa gradyan liy estime a; reprezante kantite lajan an Rezoud ekwasyon senp regression lineyè lè li chanje Rezoud ekwasyon senp regression lineyè.

Li evidan, travay nou an nan egzanp lan se chwazi koyefisyan sa yo nan ekwasyon an Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè, nan ki devyasyon yo nan valè revni kalkile nou an pa mwa soti nan repons yo vre, i.e. valè yo prezante nan echantiyon an pral minim.

Metòd pi piti kare

Dapre metòd la pi piti kare, yo ta dwe kalkile devyasyon an pa kare li. Teknik sa a pèmèt ou evite mityèl anile devyasyon si yo gen siy opoze. Pou egzanp, si nan yon ka, devyasyon an se +5 (plis senk), ak nan lòt la -5 (mwens senk), Lè sa a, sòm devyasyon yo pral anile youn ak lòt epi li se 0 (zewo). Ou pa bezwen kare devyasyon an, men sèvi ak pwopriyete modil la ak Lè sa a, tout devyasyon yo pral pozitif epi yo pral akimile. Nou pa pral rete sou pwen sa a an detay, men tou senpleman endike ke pou konvenyans nan kalkil, li se òdinè kare devyasyon an.

Men ki jan fòmil la sanble ak ki nou pral detèmine sòm ki pi piti nan devyasyon kare (erè):

Rezoud ekwasyon senp regression lineyè

kote Rezoud ekwasyon senp regression lineyè se yon fonksyon apwoksimasyon repons vre (ki vle di revni nou kalkile),

Rezoud ekwasyon senp regression lineyè se vre repons yo (revni yo bay nan echantiyon an),

Rezoud ekwasyon senp regression lineyè se endèks echantiyon an (kantite mwa kote yo detèmine devyasyon an)

Ann diferansye fonksyon an, defini ekwasyon diferans pasyèl yo, epi nou pare pou n ale nan solisyon analitik la. Men, anvan, ann fè yon ti levasyon sou sa diferansyasyon an epi sonje siyifikasyon jeyometrik derive a.

Diferansyasyon

Diferansyasyon se operasyon pou jwenn dérivés yon fonksyon.

Pou ki sa derive yo itilize? Derive yon fonksyon karakterize pousantaj chanjman fonksyon an epi li di nou direksyon li. Si dérivés nan yon pwen yo pozitif, lè sa a fonksyon an ogmante; sinon, fonksyon an diminye. Ak pi gwo valè derive absoli a, se pi gwo pousantaj chanjman nan valè fonksyon yo, osi byen ke pi apik pant graf fonksyon an.

Pa egzanp, nan kondisyon yon sistèm kowòdone katezyen, valè derive nan pwen M(0,0) egal a + 25 vle di ke nan yon pwen bay, lè valè a deplase Rezoud ekwasyon senp regression lineyè adwat pa yon inite konvansyonèl, valè Rezoud ekwasyon senp regression lineyè ogmante pa 25 inite konvansyonèl yo. Sou graf la li sanble yon ogmantasyon jistis apik nan valè Rezoud ekwasyon senp regression lineyè soti nan yon pwen bay.

Yon lòt egzanp. Valè dérivés egal -0,1 vle di ke lè deplase Rezoud ekwasyon senp regression lineyè pou chak inite konvansyonèl, valè Rezoud ekwasyon senp regression lineyè diminye pa sèlman 0,1 inite konvansyonèl yo. An menm tan an, sou graf fonksyon an, nou ka obsève yon pant desann apèn aparan. Trase yon analoji ak yon mòn, se kòmsi nou trè dousman desann yon pant dou soti nan yon mòn, kontrèman ak egzanp anvan an, kote nou te oblije monte pik trè apik :)

Kidonk, apre diferansye fonksyon an Rezoud ekwasyon senp regression lineyè pa chans Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè, nou defini ekwasyon pasyèl diferansye 1ye lòd. Apre yo fin detèmine ekwasyon yo, nou pral resevwa yon sistèm de ekwasyon, lè nou rezoud ki nou yo pral kapab chwazi valè sa yo nan koyefisyan yo. Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè, nan ki valè yo nan dérivés korespondan yo nan pwen yo bay yo chanje pa yon kantite, trè piti, epi nan ka a nan yon solisyon analyse pa chanje ditou. Nan lòt mo, fonksyon erè nan koyefisyan yo jwenn yo pral rive nan yon minimòm, paske valè dérivés pasyèl yo nan pwen sa yo pral egal a zewo.

Se konsa, dapre règ yo nan diferansyasyon, ekwasyon an derive pasyèl nan 1ye lòd la ki gen rapò ak koyefisyan an. Rezoud ekwasyon senp regression lineyè pral pran fòm sa a:

Rezoud ekwasyon senp regression lineyè

1ye lòd pasyèl ekwasyon dérivés parapò ak Rezoud ekwasyon senp regression lineyè pral pran fòm sa a:

Rezoud ekwasyon senp regression lineyè

Kòm yon rezilta, nou te resevwa yon sistèm ekwasyon ki gen yon solisyon analyse jistis senp:

kòmanse {ekwasyon*}
kòmanse{ka}
na + bsumlimits_{i=1}^nx_i — sumlimits_{i=1}^ny_i = 0

sumlimits_{i=1}^nx_i(yon +bsumlimits_{i=1}^nx_i — sumlimits_{i=1}^ny_i) = 0
fen {ka}
fen {ekwasyon*}

Anvan w rezoud ekwasyon an, ann prechaje, tcheke si chaje a kòrèk, epi fòma done yo.

Chaje ak fòma done yo

Li ta dwe remake ke akòz lefèt ke pou solisyon an analyse, epi imedyatman pou desandan gradyan ak stochastic gradyan, nou pral sèvi ak kòd la nan de varyasyon: lè l sèvi avèk bibliyotèk la. numpy epi san yo pa itilize li, Lè sa a, nou pral bezwen fòma done apwopriye (gade kòd).

Done chaje ak pwosesis kòd

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

Vizyalizasyon

Koulye a, apre nou te, premyèman, chaje done yo, dezyèmman, tcheke kòrèkteman nan loading la epi finalman fòma done yo, nou pral pote soti nan vizyalizasyon an premye. Metòd la souvan itilize pou sa a se parplot bibliyotèk yo seaborn. Nan egzanp nou an, akòz nimewo yo limite, pa gen okenn pwen nan itilize bibliyotèk la seaborn. Nou pral sèvi ak bibliyotèk regilye a matplotlib epi jis gade nan dispersion la.

Kòd 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()

Tablo No 1 "Depandans revni sou mwa nan ane a"

Rezoud ekwasyon senp regression lineyè

Solisyon analyse

Ann sèvi ak zouti ki pi komen nan python epi rezoud sistèm ekwasyon an:

kòmanse {ekwasyon*}
kòmanse{ka}
na + bsumlimits_{i=1}^nx_i — sumlimits_{i=1}^ny_i = 0

sumlimits_{i=1}^nx_i(yon +bsumlimits_{i=1}^nx_i — sumlimits_{i=1}^ny_i) = 0
fen {ka}
fen {ekwasyon*}

Dapre règ Cramer a nou pral jwenn detèminan jeneral la, osi byen ke detèminan pa Rezoud ekwasyon senp regression lineyè e pa Rezoud ekwasyon senp regression lineyè, apre sa, divize detèminan an pa Rezoud ekwasyon senp regression lineyè detèminan jeneral la - jwenn koyefisyan an Rezoud ekwasyon senp regression lineyè, Menm jan an tou nou jwenn koyefisyan an Rezoud ekwasyon senp regression lineyè.

Kòd solisyon analyse

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

Men sa nou jwenn:

Rezoud ekwasyon senp regression lineyè

Se konsa, yo te jwenn valè koyefisyan yo, yo te etabli sòm devyasyon kare yo. Ann trase yon liy dwat sou istogram gaye an akò ak koyefisyan yo jwenn.

Regresyon liy kòd

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

Tablo No 2 "Repons kòrèk ak kalkile"

Rezoud ekwasyon senp regression lineyè

Ou ka gade graf devyasyon pou chak mwa. Nan ka nou an, nou pa pral tire okenn valè pratik enpòtan nan li, men nou pral satisfè kiryozite nou sou ki jan byen senp ekwasyon an regression lineyè karakterize depandans nan revni sou mwa a nan ane a.

Kòd tablo devyasyon

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

Tablo No 3 "Devyasyon, %"

Rezoud ekwasyon senp regression lineyè

Pa pafè, men nou te konplete travay nou an.

Ann ekri yon fonksyon ki, pou detèmine koyefisyan yo Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè sèvi ak bibliyotèk la numpy, pi presizeman, nou pral ekri de fonksyon: youn lè l sèvi avèk yon matris pseudoenverse (pa rekòmande nan pratik, paske pwosesis la se enfòmatik konplèks ak enstab), lòt la lè l sèvi avèk yon ekwasyon matris.

Kòd solisyon analitik (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

Ann konpare tan ki pase pou detèmine koyefisyan yo Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè, an akò ak 3 metòd yo prezante.

Kòd pou kalkile tan kalkil

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)

Rezoud ekwasyon senp regression lineyè

Avèk yon ti kantite done, yon fonksyon "oto-ekri" soti pi devan, ki jwenn koyefisyan yo lè l sèvi avèk metòd Cramer la.

Koulye a, ou ka ale nan lòt fason yo jwenn koyefisyan Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè.

Desandan gradyan

Premyèman, ann defini ki sa yon gradyan ye. Senpleman mete, gradyan an se yon segman ki endike direksyon kwasans maksimòm yon fonksyon. Pa analoji ak k ap grenpe yon mòn, kote gradyan yo ap fè fas a se kote grenpe ki pi apik sou tèt mòn lan ye. Devlope egzanp lan ak mòn lan, nou sonje ke an reyalite nou bezwen desandan ki pi apik yo nan lòd yo rive nan plenn lan pi vit posib, se sa ki, minimòm nan - plas la kote fonksyon an pa ogmante oswa diminye. Nan pwen sa a derive a pral egal a zewo. Se poutèt sa, nou pa bezwen yon gradyan, men yon antigradyan. Pou jwenn antigradyan an ou jis bezwen miltipliye gradyan an pa -1 (mwens youn).

Se pou nou peye atansyon sou lefèt ke yon fonksyon ka gen plizyè minimòm, epi yo te desann nan youn nan yo lè l sèvi avèk algorithm yo pwopoze anba a, nou pa yo pral kapab jwenn yon lòt minimòm, ki ka pi ba pase youn nan yo te jwenn. Ann detann, sa a se pa yon menas pou nou! Nan ka nou an nou ap fè fas ak yon minimòm sèl, depi fonksyon nou an Rezoud ekwasyon senp regression lineyè sou graf la se yon parabòl regilye. Epi kòm nou tout ta dwe konnen trè byen nan kou matematik lekòl nou an, yon parabòl gen sèlman yon minimòm.

Apre nou te jwenn poukisa nou te bezwen yon gradyan, epi tou ke gradyan an se yon segman, se sa ki, yon vektè ki gen kowòdone bay yo, ki se jisteman menm koyefisyan yo. Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè nou ka aplike desandan gradyan.

Anvan w kòmanse, mwen sijere li jis kèk fraz sou algorithm desandan an:

  • Nou detèmine nan yon fason pseudo-o aza kowòdone yo nan koyefisyan yo Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè. Nan egzanp nou an, nou pral detèmine koyefisyan toupre zewo. Sa a se yon pratik komen, men chak ka gen pwòp pratik li yo.
  • Soti nan kowòdone Rezoud ekwasyon senp regression lineyè soustraksyon valè derive pasyèl 1ye lòd la nan pwen an Rezoud ekwasyon senp regression lineyè. Kidonk, si derive pozitif la, fonksyon an ap ogmante. Se poutèt sa, lè nou soustraksyon valè derive a, nou pral deplase nan direksyon opoze a nan kwasans, se sa ki, nan direksyon desandan. Si dérivés a negatif, lè sa a fonksyon nan pwen sa a diminye, epi lè nou soustraksyon valè dérivés a nou deplase nan direksyon desandan.
  • Nou fè yon operasyon menm jan an ak kowòdone a Rezoud ekwasyon senp regression lineyè: soustraksyon valè derive pasyèl la nan pwen an Rezoud ekwasyon senp regression lineyè.
  • Yo nan lòd yo pa sote sou minimòm la ak vole nan espas gwo twou san fon, li nesesè yo mete gwosè a etap nan yon direksyon ki nan desandan. An jeneral, ou ta ka ekri yon atik antye sou ki jan yo mete etap la kòrèkteman ak ki jan yo chanje li pandan pwosesis la desandan yo nan lòd yo diminye depans enfòmatik. Men koulye a, nou gen yon travay yon ti kras diferan devan nou, epi nou pral etabli gwosè a etap lè l sèvi avèk metòd la syantifik nan "poke" oswa, jan yo di nan langaj komen, anpirik.
  • Yon fwa nou soti nan kowòdone yo bay yo Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè soustraksyon valè dérivés yo, nou jwenn nouvo kowòdone Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè. Nou pran pwochen etap la (soustraksyon), ki deja soti nan kowòdone yo kalkile. Se konsa, sik la kòmanse ankò e ankò, jiskaske dirèksyon ki nesesè yo reyalize.

Tout! Koulye a, nou pare pou ale nan rechèch nan ravin ki pi pwofon nan Mariana Trench la. An n kòmanse.

Kòd pou desandan gradyan

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

Rezoud ekwasyon senp regression lineyè

Nou plonje nan fon lanmè a Mariana epi la nou jwenn tout menm valè koyefisyan yo Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè, ki se egzakteman sa ki te dwe espere.

Ann pran yon lòt plonje, sèlman fwa sa a, machin nan fon lanmè nou an pral plen ak lòt teknoloji, sètadi yon bibliyotèk. numpy.

Kòd pou desandan gradyan (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

Rezoud ekwasyon senp regression lineyè
Valè koyefisyan Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè enchanjab.

Ann gade ki jan erè a chanje pandan desandan gradyan, se sa ki, ki jan sòm total devyasyon kare a chanje ak chak etap.

Kòd pou trase sòm devyasyon kare

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

Grafik No 4 "Sòm devyasyon kare pandan desandan gradyan"

Rezoud ekwasyon senp regression lineyè

Sou graf la nou wè ke ak chak etap erè a diminye, epi apre yon sèten kantite iterasyon nou obsève yon liy prèske orizontal.

Finalman, an n estime diferans ki genyen nan tan ekzekisyon kòd:

Kòd pou detèmine tan kalkil desandan gradyan

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)

Rezoud ekwasyon senp regression lineyè

Petèt n ap fè yon bagay mal, men ankò se yon senp fonksyon "ekri lakay" ki pa sèvi ak bibliyotèk la. numpy depase tan kalkil yon fonksyon lè l sèvi avèk bibliyotèk la numpy.

Men, nou pa kanpe toujou, men n ap deplase nan direksyon pou etidye yon lòt fason enteresan pou rezoud senp ekwasyon regression lineyè a. Rankontre!

Desandan gradyan stochastic

Yo nan lòd yo byen vit konprann prensip la nan operasyon nan desandan gradyan stochastic, li se pi bon detèmine diferans li yo soti nan desandan gradyan òdinè. Nou, in the case of gradyan desandan, nan ekwasyon dérivés de Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè itilize sòm total valè tout karakteristik ak repons vre ki disponib nan echantiyon an (ki vle di, sòm tout Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè). Nan desandan gradyan stochastic, nou pa pral sèvi ak tout valè ki prezan nan echantiyon an, men olye de sa, pseudo-owaza chwazi sa yo rele endèks echantiyon an epi sèvi ak valè li yo.

Pou egzanp, si yo detèmine endèks la se nimewo 3 (twa), Lè sa a, nou pran valè yo Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè, Lè sa a, nou ranplase valè yo nan ekwasyon derive yo epi detèmine nouvo kowòdone. Lè sa a, lè nou te detèmine kowòdone yo, nou ankò pseudo-owaza detèmine endèks echantiyon an, ranplase valè ki koresponn ak endèks la nan ekwasyon diferans pasyèl yo, epi detèmine kowòdone yo nan yon nouvo fason. Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè elatriye. jiskaske dirèksyon an vin vèt. Nan premye gade, li ka pa sanble tankou sa a ta ka travay nan tout, men li fè sa. Se vre ke li vo anyen ke erè a pa diminye ak chak etap, men gen sètènman yon tandans.

Ki avantaj ki genyen nan desandan gradyan stochastic sou yon sèl konvansyonèl? Si gwosè echantiyon nou an trè gwo ak mezire nan dè dizèn de milye de valè, Lè sa a, li pi fasil yo trete, di, yon milye o aza nan yo, olye ke echantiyon an antye. Sa a se kote stochastic gradyan desandan antre nan jwèt. Nan ka nou an, nan kou, nou pa pral remake anpil nan yon diferans.

Ann gade kòd la.

Kòd pou desandan gradyan stochastic

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

Rezoud ekwasyon senp regression lineyè

Nou gade ak anpil atansyon nan koyefisyan yo epi kenbe tèt nou poze kesyon an "Kijan sa a ka ye?" Nou jwenn lòt valè koyefisyan Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè. Petèt stochastic gradyan desandan te jwenn plis paramèt optimal pou ekwasyon an? Malerezman non. Li se ase yo gade nan sòm total la nan devyasyon kare ak wè ke ak nouvo valè nan koyefisyan yo, erè a se pi gwo. Nou pa prese dezespwa. Ann konstwi yon graf nan chanjman erè a.

Kòd pou trase sòm devyasyon kare nan desandan gradyan stochastic

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 "Sòm devyasyon kare pandan desandan gradyan stochastic"

Rezoud ekwasyon senp regression lineyè

Gade nan orè a, tout bagay tonbe nan plas epi kounye a nou pral ranje tout bagay.

Se konsa, sa ki te pase? Sa ki annapre yo te rive. Lè nou chwazi yon mwa owaza, se pou mwa yo chwazi algorithm nou an ap chèche diminye erè nan kalkil revni. Lè sa a, nou chwazi yon lòt mwa epi repete kalkil la, men nou redwi erè a pou dezyèm mwa a chwazi. Koulye a, sonje ke de premye mwa yo devye siyifikativman ak liy ekwasyon senp lineyè regresyon an. Sa vle di ke lè yo chwazi nenpòt nan de mwa sa yo, lè yo diminye erè a nan chak nan yo, algorithm nou an seryezman ogmante erè a pou tout echantiyon an. Se konsa, sa pou yo fè? Repons lan se senp: ou bezwen diminye etap la desandan. Apre yo tout, pa diminye etap la desandan, erè a pral sispann tou "sote" leve, li desann. Oswa pito, erè a "sote" pa pral sispann, men li pa pral fè li tèlman vit :) Ann tcheke.

Kòd pou kouri SGD ak pi piti ogmantasyon

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

Rezoud ekwasyon senp regression lineyè

Grafik No 6 "Sòm devyasyon kare pandan desandan gradyan stochastic (80 mil etap)"

Rezoud ekwasyon senp regression lineyè

Koefisyan yo amelyore, men yo toujou pa ideyal. Ipotèz, sa a ka korije fason sa a. Nou chwazi, pou egzanp, nan dènye 1000 iterasyon yo valè koyefisyan yo ak ki erè minimòm lan te fè. Se vre, pou sa nou pral gen tou ekri valè koyefisyan yo tèt yo. Nou pa pral fè sa, men pito peye atansyon sou orè a. Li sanble lis ak erè a sanble diminye respire. Aktyèlman sa a se pa vre. Ann gade nan premye 1000 iterasyon yo epi konpare yo ak dènye a.

Kòd pou tablo SGD (premye 1000 etap)

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

Grafik No 7 "Sòm devyasyon kare SGD (premye 1000 etap)"

Rezoud ekwasyon senp regression lineyè

Grafik No 8 "Sòm devyasyon kare SGD (dènye 1000 etap)"

Rezoud ekwasyon senp regression lineyè

Nan kòmansman an anpil nan desandan an, nou obsève yon diminisyon jistis inifòm ak apik nan erè. Nan dènye iterasyon yo, nou wè ke erè a ale alantou ak alantou valè a nan 1,475 ak nan kèk moman menm egal valè sa a optimal, men Lè sa a, li toujou ap monte ... Mwen repete, ou ka ekri valè yo nan la. koyefisyan Rezoud ekwasyon senp regression lineyè и Rezoud ekwasyon senp regression lineyè, ak Lè sa a, chwazi sa yo pou ki erè a se minim. Sepandan, nou te gen yon pwoblèm ki pi grav: nou te oblije pran 80 mil etap (gade kòd) pou jwenn valè ki pre pi bon. Ak sa a deja kontredi lide nan ekonomize tan kalkil ak desandan gradyan stochastic parapò ak desandan gradyan. Ki sa ki ka korije ak amelyore? Li pa difisil pou remake ke nan premye iterasyon yo nou ap desann ak konfyans epi, kidonk, nou ta dwe kite yon gwo etap nan premye iterasyon yo epi redwi etap la pandan n ap avanse. Nou pa pral fè sa nan atik sa a - li deja twò lontan. Moun ki vle ka panse pou tèt yo ki jan fè sa, li pa difisil :)

Koulye a, an n fè stochastic gradyan desandan lè l sèvi avèk bibliyotèk la numpy (epi se pou nou pa bite sou wòch yo ke nou te idantifye pi bonè)

Kòd pou Desandan Gradyan Stochastic (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

Rezoud ekwasyon senp regression lineyè

Valè yo te tounen prèske menm jan ak lè desann san yo pa itilize numpy. Sepandan, sa a se lojik.

Ann chèche konnen konbyen tan desant stochastic gradyan te pran nou.

Kòd pou detèmine tan kalkil SGD (80 mil etap)

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)

Rezoud ekwasyon senp regression lineyè

Plis nan forè a, pi fonse nwaj yo: ankò, fòmil "oto-ekri" la montre pi bon rezilta a. Tout bagay sa yo sijere ke dwe gen menm plis sibtil fason yo sèvi ak bibliyotèk la numpy, ki vrèman akselere operasyon kalkil yo. Nan atik sa a nou pa pral aprann sou yo. Pral gen yon bagay pou w reflechi nan tan lib ou :)

Annou rezime

Anvan rezime, mwen ta renmen reponn yon kesyon ki gen plis chans soti nan men lektè nou an. Poukisa, an reyalite, tankou "tòti" ak desandans, poukisa nou bezwen mache monte ak desann mòn nan (sitou desann) yo nan lòd yo jwenn plenn lan trezò, si nou gen nan men nou yon aparèy pwisan ak senp, nan la. fòm yon solisyon analyse, ki imedyatman teleporte nou nan bon kote?

Repons kesyon sa a bay manti sou sifas la. Koulye a, nou te gade nan yon egzanp trè senp, nan ki repons lan se vre Rezoud ekwasyon senp regression lineyè depann sou yon sèl siy Rezoud ekwasyon senp regression lineyè. Ou pa wè sa souvan nan lavi, kidonk ann imajine ke nou gen 2, 30, 50 oswa plis siy. Ann ajoute nan sa a dè milye, oswa menm dè dizèn de milye de valè pou chak atribi. Nan ka sa a, solisyon an analyse ka pa kenbe tèt ak tès la ak echwe. Nan vire, desandan gradyan ak varyasyon li yo pral tou dousman men siman mennen nou pi pre objektif la - minimòm nan fonksyon an. Epi pa enkyete w sou vitès - nou pral pwobableman gade nan fason ki pral pèmèt nou mete ak kontwole longè etap (ki se, vitès).

Epi, koulye a aktyèl rezime a kout.

Premyèman, mwen espere ke materyèl la prezante nan atik la pral ede kòmanse "syantis done" nan konprann ki jan yo rezoud senp (epi pa sèlman) ekwasyon regression lineyè.

Dezyèmman, nou te gade plizyè fason pou rezoud ekwasyon an. Koulye a, tou depann de sitiyasyon an, nou ka chwazi youn nan ki pi byen adapte yo rezoud pwoblèm nan.

Twazyèmman, nou te wè pouvwa a nan anviwònman adisyonèl, sètadi longè etap desandan gradyan an. Paramèt sa a pa ka neglije. Kòm te note pi wo a, yo nan lòd yo redwi pri a nan kalkil, longè etap la ta dwe chanje pandan desandan an.

Katriyèmman, nan ka nou an, fonksyon "ekri lakay" yo te montre pi bon rezilta tan pou kalkil yo. Sa a se pwobableman akòz pa pi pwofesyonèl itilizasyon kapasite bibliyotèk la numpy. Men, jan li ka, konklizyon sa a sijere tèt li. Sou yon bò, pafwa li vo kesyone opinyon etabli, ak nan lòt men an, li pa toujou vo konplike tout bagay - okontrè, pafwa yon fason ki pi senp pou rezoud yon pwoblèm se pi efikas. Epi piske objektif nou se te analize twa apwòch pou rezoud yon senp ekwasyon regresyon lineyè, itilizasyon fonksyon "oto-ekri" te ase pou nou.

Literati (oswa yon bagay konsa)

1. Regression lineyè

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

2. Metòd pi piti kare

mathprofi.ru/metod_naimenshih_kvadratov.html

3. Dérivés

www.mathprofi.ru/chastnye_proizvodnye_primery.html

4. Gradyan

mathprofi.ru/proizvodnaja_po_napravleniju_i_gradient.html

5. Desandan gradyan

habr.com/en/post/471458

habr.com/en/post/307312

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

6. Bibliyotèk 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

Sous: www.habr.com

Add nouvo kòmantè