Zephyrnet-logo

Welke methoden moeten worden gebruikt om lineaire regressie op te lossen?

Datum:

Welke methoden moeten worden gebruikt om lineaire regressie op te lossen?

Als een fundamentele set algoritmen in elke toolbox voor machine learning, kan lineaire regressie worden opgelost met een verscheidenheid aan benaderingen. Hier bespreken we. met codevoorbeelden, vier methoden en demonstreren hoe ze moeten worden gebruikt.


By Ahmad bin Shafiq, Student Machine Learning.

Lineaire regressie is een algoritme voor machine learning onder supervisie. Het voorspelt een lineair verband tussen een onafhankelijke variabele (y), gebaseerd op de gegeven afhankelijke variabelen (x), zodat de onafhankelijke variabele (y) de laagste prijs.

Verschillende benaderingen om lineaire regressiemodellen op te lossen

Er zijn veel verschillende methoden die we kunnen toepassen op ons lineaire regressiemodel om het efficiënter te maken. Maar we zullen hier de meest voorkomende bespreken.

  1. Gradient Afdaling
  2. Least Square-methode / normale vergelijkingsmethode
  3. Adams-methode
  4. Singuliere Waarde Decompositie (SVD)

Oké, dus laten we beginnen ...

Gradient Afdaling

Een van de meest gebruikelijke en gemakkelijkste methoden voor beginners om lineaire regressieproblemen op te lossen, is gradiëntafdaling.

Hoe Gradient Descent werkt

Laten we nu aannemen dat we onze gegevens hebben uitgezet in de vorm van een spreidingsgrafiek, en wanneer we er een kostenfunctie op toepassen, zal ons model een voorspelling doen. Nu kan deze voorspelling erg goed zijn, of het kan ver verwijderd zijn van onze ideale voorspelling (wat betekent dat de kosten hoog zullen zijn). Dus om die kosten (fout) te minimaliseren, passen we er een gradiëntafdaling op toe.

Nu zal gradiëntafdaling onze hypothese langzaam laten convergeren naar een globaal minimum, waar de kosten zou het laagst zijn. Daarbij moeten we de waarde van handmatig instellen alfa, en de helling van de hypothese verandert ten opzichte van de waarde van onze alfa. Als de waarde van alpha groot is, zijn er grote stappen nodig. Anders, in het geval van kleine alfa, zou onze hypothese langzaam en via kleine babystapjes convergeren.

Hypothese convergeert naar een globaal minimum. Afbeelding van Medium.

De vergelijking voor gradiëntafname is

Bron: Ruder.io.

Gradient Descent implementeren in Python

import numpy als np uit matplotlib import pyplot #creating our data X = np.random.rand (10,1) y = np.random.rand (10,1) m = len (y) theta = np.ones (1) #applying gradiënt afdaling a = 0.0005 cost_list = [] voor i binnen bereik (len (y)): theta = theta - a * (1 / m) * np.transpose (X) @ (X @ theta - y) cost_val = (1 / m) * np.transpose (X) @ (X @ theta - y) cost_list.append (cost_val) # Onze hypothese voorspellen b = theta yhat = X.dot (b) # Onze resultaten in kaart brengen pyplot.scatter (X , y, kleur = 'rood') pyplot.plot (X, yhat, kleur = 'blauw') pyplot.show () 

Model naar Gradient Descent.

Hier hebben we eerst onze dataset gemaakt, en vervolgens hebben we al onze trainingsvoorbeelden doorlopen om onze kosten van hypothese te minimaliseren.

Voors:

Belangrijke voordelen van Gradient Descent zijn

  • Minder rekenkosten in vergelijking met SVD of ADAM
  • Looptijd is O (kn²)
  • Werkt goed met meer functies

nadelen:

Belangrijke nadelen van Gradient Descent zijn

  • Moet een leertempo kiezen α
  • Heeft veel iteraties nodig om samen te komen
  • Kan in Local Minima worden geplakt
  • Zo niet het juiste leertempo α, dan komt het misschien niet samen.

Least Square-methode

De methode met de kleinste kwadraten, ook wel bekend als de normale vergelijking, is ook een van de meest gebruikte benaderingen om lineaire regressiemodellen gemakkelijk op te lossen. Maar deze moet enige basiskennis hebben van lineaire algebra.

Hoe de kleinste kwadratenmethode werkt

In normale LSM lossen we rechtstreeks de waarde van onze coëfficiënt op. Kortom, in één stap bereiken we ons optische minimumpunt, of we kunnen slechts in één stap zeggen dat we onze hypothese aan onze gegevens aanpassen tegen de laagst mogelijke kosten.

Voor en na het toepassen van LSM op onze dataset. Afbeelding van Medium.

De vergelijking voor LSM is

LSM implementeren in Python

importeer numpy als np uit matplotlib importeer pyplot #creating our data X = np.random.rand (10,1) y = np.random.rand (10,1) #Computing coefficient b = np.linalg.inv (XTdot (X )). dot (XT) .dot (y) #Voorspelling van onze hypothese yhat = X.dot (b) #Plot van onze resultaten pyplot.scatter (X, y, color = 'red') pyplot.plot (X, yhat, color = 'blauw') pyplot.show () 

Hier hebben we eerst onze dataset gemaakt en vervolgens de kosten van onze hypothese geminimaliseerd met behulp van de

b = np.linalg.inv (XTdot (X)). punt (XT) .dot (y)

code, die gelijk is aan onze vergelijking.

Voors:

Belangrijke voordelen van LSM zijn:

  • Geen leertempo
  • Geen iteraties
  • Schalen van functies niet nodig
  • Werkt erg goed als het aantal functies kleiner is.

nadelen:

Belangrijke nadelen zijn:

  • Is rekenkundig duur als de dataset groot is.
  • Traag als het aantal functies meer is
  • Speelduur is O (n³)
  • Soms is je X transponeer X niet-inverteerbaar, dat wil zeggen, een singuliere matrix zonder inverse. Je kunt gebruiken np.linalg.pinv in plaats van np.linalg.inv om dit probleem op te lossen.

Adam's methode

ADAM, wat staat voor Adaptive Moment Estimation, is een optimalisatie-algoritme dat veel wordt gebruikt in Deep Learning.

Het is een iteratief algoritme dat goed werkt op data met veel ruis.

Het is de combinatie van RMSProp en Mini-batch Gradient Descent-algoritmen.

Naast het opslaan van een exponentieel afnemend gemiddelde van eerdere kwadraten zoals Adadelta en RMSprop, houdt Adam ook een exponentieel afnemende gemiddelde van voorbije verlopen, vergelijkbaar met momentum.

We berekenen de vervalgemiddelden van respectievelijk afgelopen en afgelopen kwadraten als volgt:

credit: Ruder.io.

As mt en vt worden geïnitialiseerd als vectoren van nullen, merken de auteurs van Adam op dat ze naar nul neigen, vooral tijdens de initiële tijdsstappen, en vooral wanneer de vervalsnelheden klein zijn (dwz β0β1 en β1β2 liggen dicht bij 2).

Ze neutraliseren deze vooroordelen door bias-gecorrigeerde schattingen van het eerste en tweede moment te berekenen:

credit: Ruder.io.

Vervolgens werken ze de parameters bij met:

credit: Ruder.io.

Je kunt de theorie achter Adam leren hier or hier.

Pseudocode voor Adam is

Bron: Arxiv Adam.

Laten we eens kijken naar de code in Pure Python.

#Creating the Dummy Data set and import bibraries import math import seaborn as sns import numpy as np from scipy import stats from matplotlib import pyplot x = np.random.normal (0,1, size = (100,1)) y = np .random.random (maat = (100,1)) 

Laten we nu de feitelijke grafiek van lineaire regressie en waarden voor helling en snijpunt voor onze dataset zoeken.

print ("Intercept is", stats.mstats.linregress (x, y) .intercept) print ("Slope is", stats.mstats.linregress (x, y) .slope) 

Laten we nu de Linear Regression-lijn bekijken met behulp van de Seaborn regplot functie.

pyplot.figure (figsize = (15,8)) sns.regplot (x, y) pyplot.show () 

Laten we Adam Optimizer nu coderen in pure Python.

h = lambda theta_0, theta_1, x: theta_0 + np.dot (x, theta_1) #vergelijking van rechte lijnen # de kostenfunctie (voor de hele batch. ter vergelijking later) def J (x, y, theta_0, theta_1): m = len (x) returnValue = 0 voor i binnen bereik (m): returnValue + = (h (theta_0, theta_1, x [i]) - y [i]) ** 2 returnValue = returnValue / (2 * m) return returnValue # het vinden van de gradiënt per trainingsvoorbeeld def grad_J (x, y, theta_0, theta_1): returnValue = np.array ([0., 0.]) returnValue [0] + = (h (theta_0, theta_1, x ) - y) returnValue [1] + = (h (theta_0, theta_1, x) - y) * x return returnValue class AdamOptimizer: def __init __ (self, weights, alpha = 0.001, beta1 = 0.9, beta2 = 0.999, epsilon = 1e-8): self.alpha = alpha self.beta1 = beta1 self.beta2 = beta2 self.epsilon = epsilon self.m = 0 self.v = 0 self.t = 0 self.theta = gewichten def backward_pass (self, gradiënt): self.t = self.t + 1 self.m = self.beta1 * self.m + (1 - self.beta1) * gradiënt self.v = self.beta2 * self.v + (1 - self. beta2) * (gradiënt ** 2) m_hat = self.m / (1 - self.beta 1 ** self.t) v_hat = self.v / (1 - self.beta2 ** self.t) self.theta = self.theta - self.alpha * (m_hat / (np.sqrt (v_hat) - self. epsilon)) retourneert self.theta 

Hier hebben we alle vergelijkingen geïmplementeerd die in de pseudocode hierboven worden genoemd met behulp van een objectgeoriënteerde benadering en enkele hulpfuncties.

Laten we nu de hyperparameters voor ons model instellen.

epochs = 1500 print_interval = 100 m = len (x) initiële_theta = np.array ([0., 0.]) # initiële waarde van theta, vóór gradiënt afdaling initiële_kosten = J (x, y, initiële_theta [0], initiële_theta [ 1]) theta = initial_theta adam_optimizer = AdamOptimizer (theta, alpha = 0.001) adam_history = [] # om het pad van de afkomst uit te zetten adam_history.append (dict ({'theta': theta, 'cost': initial_cost}) # om te controleren theta en kostenfunctie 

En tot slot, het trainingsproces.

for j in range (epochs): for i in range (m): gradients = grad_J (x [i], y [i], theta [0], theta [1]) theta = adam_optimizer.backward_pass (gradients) if ( (j + 1)% print_interval == 0 of j == 0): cost = J (x, y, theta [0], theta [1]) print ('After {} epochs, Cost = {}, theta = {} '. format (j + 1, cost, theta)) adam_history.append (dict ({' theta ': theta,' cost ': cost})) print (' nFinal theta = {} '. format (theta) ) 

Nu, als we de Laatste theta waarden voor de hellings- en snijwaarden, eerder berekend met scipy.stats.mstat.linregress, ze zijn bijna 99% gelijk en kunnen 100% gelijk zijn door de hyperparameters aan te passen.

Laten we het tot slot uitzetten.

b = theta yhat = b [0] + x.dot (b [1]) pyplot.figure (figsize = (15,8)) pyplot.scatter (x, y, kleur = 'rood') pyplot.plot (x , yhat, color = 'blue') pyplot.show () 

En we kunnen zien dat onze plot vergelijkbaar is met de plot die is verkregen met sns.regplot.

Voors:

  • Eenvoudig te implementeren.
  • Computationeel efficiënt.
  • Weinig geheugenvereisten.
  • Onvariant voor diagonale herschaling van de verlopen.
  • Zeer geschikt voor problemen die groot zijn in termen van data en / of parameters.
  • Geschikt voor niet-stationaire doelen.
  • Geschikt voor problemen met zeer luidruchtige / of schaarse hellingen.
  • Hyperparameters hebben een intuïtieve interpretatie en vereisen doorgaans weinig afstemming.

nadelen:

  • Adam en RMSProp zijn zeer gevoelig voor bepaalde waarden van het leertempo (en soms andere hyperparameters zoals de batchgrootte), en ze kunnen catastrofaal niet convergeren als het leertempo bijvoorbeeld te hoog is. (Bron: antwoordde)

Singuliere waarden ontbinding

Decompositie van singuliere waarden, verkort als SVD, is een van de beroemde en meest gebruikte methoden voor dimensionaliteitsreductie bij lineaire regressie.

SVD wordt (naast andere toepassingen) gebruikt als een voorverwerkingsstap om het aantal dimensies voor ons leeralgoritme te verminderen. SVD ontleedt een matrix in een product van drie andere matrices (U, S, V).

Zodra onze matrix is ​​ontleed, kunnen de coëfficiënten voor onze hypothese worden gevonden door de pseudo-inverse van de invoermatrix te berekenen X en dat te vermenigvuldigen met de uitvoervector y. Daarna passen we onze hypothese aan onze gegevens aan, en dat levert ons de laagste kosten op.

SVD implementeren in Python

importeer numpy als np uit matplotlib importeer pyplot #Onze gegevens maken X = np.random.rand (10,1) y = np.random.rand (10,1) #Computingcoëfficiënt b = np.linalg.pinv (X). punt (y) #Voorspelling van onze hypothese yhat = X.dot (b) #Plot van onze resultaten pyplot.scatter (X, y, kleur = 'rood') pyplot.plot (X, yhat, kleur = 'blauw') pyplot. laten zien() 


Hoewel het niet erg goed is geconvergeerd, is het nog steeds redelijk goed.

Hier hebben we eerst onze dataset gemaakt en vervolgens de kosten van onze hypothese geminimaliseerd met b = np.linalg.pinv (X) .dot (y), de vergelijking voor SVD.

Voors:

  • Werkt beter met hogere dimensionale gegevens
  • Goed voor gedistribueerde gegevens van het Gauss-type
  • Echt stabiel en efficiënt voor een kleine dataset
  • Bij het oplossen van lineaire vergelijkingen voor lineaire regressie, is het stabieler en heeft het de voorkeur.

nadelen:

  • Looptijd is O (n³)
  • Meerdere risicofactoren
  • Echt gevoelig voor uitschieters
  • Kan onstabiel worden met een zeer grote dataset

Leerresultaat

Vanaf nu hebben we gradiëntafdaling, LSM, ADAM en SVD geleerd en geïmplementeerd. En nu hebben we een heel goed begrip van al deze algoritmen, en we weten ook wat de voor- en nadelen zijn.

Een ding dat ons opviel, was dat het ADAM-optimalisatie-algoritme het meest nauwkeurig was, en volgens het actuele ADAM-onderzoekspaper presteert ADAM beter dan bijna alle andere optimalisatie-algoritmen.

Zie ook:

Bron: https://www.kdnuggets.com/2020/09/solving-linear-regression.html

spot_img

Laatste intelligentie

spot_img