lineare Regression
Datensätze und Quelldateien können im Github-Projekt bezogen werden
Adresse: https://github.com/Raymond-Yang-2001/AndrewNg-Machine-Learing-Homework
1. Univariate lineare Regression
Die univariate lineare Regression findet eine eindimensionale Gleichung und passt eine gerade Linie an.
Univariate lineare Regressionsformel
hw , b ( x ) = b + wx h_{w,b}(x)=b+wxHw , b( X )=B+B x
Www undbbb ist ein Parameter. Um die Berechnung zu erleichtern, können Siexxx plus einx 0 = 1 x_0=1X0=1
hw , b ( x ) = bx 0 + wx 1 h_{w,b}(x)=bx_{0}+wx_{1}Hw , b( X )=b x0+B x1
verlustfunktion
J ( w , b ) = 1 2 m ∑ i = 1 m ( hw , b ( x ( i ) ) − y ( i ) ) 2 J(w,b)=\frac{1}{2m}\sum_{ i=1}^{m}(h_{w,b}(x^{(i)})-y^{(i)})^{2}J ( w ,B )=2m _1ich = 1∑m( Hw , b( X( ich ) )−j( ich ) )2
Um übermäßige oder kleine Verluste zu vermeiden, die durch ungeeignete Datenbereiche verursacht werden (z. B. wenn der Datenwert zu groß ist, kann der Verlust1 0 5 10^51 05 oder1 0 6 10^61 06 , diese Größenordnung ist für eine intuitive Analyse nicht geeignet) Bei der Bewertung des Verlusts können Sie hw, b (x (i)) h_{w,b}(x^{(i)})Hw , b( X( i ) )sumy( i ) y^{(i)}j( i ) Standardisieren Sie zunächst so, dass der Verlustwert innerhalb eines auswertbaren Bereichs liegt. Beim Gradientenabstieg ist dies jedoch nicht der Fall
Optimierungsalgorithmus – Batch Gradient Descent (BGD)
wj = wj − α ∂ ∂ wj J ( w , b ) = wj − α 1 m ∑ i = 1 m ( hw , b ( x ( i ) ) − y ( i ) ) x ( i ) w_j=w_{j }-\alpha\frac{\partial}{\partial{w_j}}{J(w,b)}=w_{j}-\alpha \frac{1}{m}\sum_{i=1}^{ m}{(h_{w,b}(x^{(i)})-y^{(i)})x^{(i)}}wj=wj−A∂ wj∂J ( w ,B )=wj−AM1ich = 1∑m( Hw , b( X( ich ) )−j( i ) )x( i )
bj = bj − α ∂ ∂ bj J ( w , b ) = wj − α 1 m ∑ i = 1 m ( hw , b ( x ( i ) ) − y ( i ) ) b_j=b_{j} -\alpha\frac{\partial}{\partial{b_j}}{J(w,b)}=w_{j}-\alpha \frac{1}{m}\sum_{i=1}^{m }{(h_{w,b}(x^{(i)})-y^{(i)})}Bj=Bj−A∂ bj∂J ( w ,B )=wj−AM1ich = 1∑m( Hw , b( X( ich ) )−j( i ) )
Hier können wirθ \thetaθ einheitliche Identifikationsparameter, einschließlichWWw undbbB .
Das heißt, jjthj Parameterθ j \theta_jichjBestimmen Sie Folgendes:
θ j = θ j − α ∂ ∂ wj J ( θ ; x ) = wj − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x ( i ) \theta_{j}=\theta_{j}-\alpha\frac{\partial}{\partial{w_j}}{J(\theta;\mathbf{x})}=w_{j}-\alpha \frac {1}{m}\sum_{i=1^{m}{(h_{\theta}(x^{(i)})-y^{(i)})x^{(i) }}ichj=ichj−A∂ wj∂J ( θ ;X )=wj−AM1ich = 1∑m( Hich( X( ich ) )−j( i ) )x( i )
wobeiα \alphaα ist die Lernrate.
2. Multivariable lineare Regression
Bei der multivariablen linearen Regression wird versucht, die Beziehung zwischen mehreren Variablen und vorhergesagten Werten zu ermitteln. Zum Beispiel die Beziehung zwischen Hausgröße, Anzahl der Schlafzimmer in einem Haus und Hauspreisen.
Feature-Skalierung (Normalisierung)
Wenn die numerischen Unterschiede zwischen verschiedenen Merkmalen der Stichprobe zu groß sind, treten bei der Optimierung auf Gradientenbasis einige Probleme auf. Beispielsweise gibt es die folgende Regressionsgleichung:
h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 h_{\theta}(x)=\theta_{0}+\theta_{1}x_{ 1}+\theta_{2}x_{2}Hich( X )=ich0+ich1X1+ich2X2
Angenommen x 2 x_{2}X2Der Bereich ist 0 ∼ 1 0\sim10∼1,x 1 x_1X1Der Bereich ist 1 0 3 ∼ 1 0 4 10^3\sim10^41 03∼1 04 . Wir optimieren gleichzeitigθ 0 ∼ θ 2 \theta_0\sim\theta_2ich0∼ich2, so dass sie sich alle um die gleiche Größe ändern, dann ist es offensichtlich, dass θ 1 \theta_1 , wenn die Eingabeproben gleich sindich1Die Änderung wird größer sein als θ 2 \theta_2ich2Änderungen, die zu einer höheren Leistung führen. Dies kann auch als Modellpaar θ 1 \theta_1 verstanden werdenich1Empfindlichere. Wie im folgenden Verlustisoliniendiagramm gezeigt, ist θ 1 \theta_1ich1Kleine Änderungen können drastische Veränderungen bei den Verlusten mit sich bringen. In diesem Fall wird die Parameteroptimierung schwieriger.
Eine Möglichkeit, dieses Problem zu lösen, ist die Feature-Skalierung, die zwei Features auf den gleichen Bereich skaliert. Beispielsweise kann eine Z-Score-Normalisierung durchgeführt werden:
xnew = x − μ σ x_{new} = \frac{x-\mu}{\sigma}Xneu _ _=PX−M
Darunter μ \muμ ist der Mittelwert des Datensatzes,σ \sigmaσ ist die Standardabweichung und die Verteilung neuer Daten ist eine Verteilung mit Mittelwert 0 und Standardabweichung 1.
Das Parameterverlustdiagramm nach der Datennormalisierung sieht wie folgt aus:
Inverse Skalierung von Parametern
Da die Daten skaliert sind, werden auch die endgültigen Parameter entsprechend skaliert. Die spezifische Beziehung ist wie folgt:
θ 0 + θ 1 ∼ d + 1 x 1 ∼ d + 1 − μ x σ x = y − μ y σ y \theta_{0}+\theta_{1\sim d+1} \frac{x_{1\sim d+1}-\mu_{x}}{\sigma_{x}}=\frac{y-\mu_{y}}{\sigma_{y}}ich0+ich1 ∼ d + 1PxX1 ∼ d + 1−Mx=Pyj−My
Hier reden wir über jjy wurde ebenfalls standardisiert.Tatsächlich ist dies nicht erforderlich und es wird keine Auswirkungen auf die Leistung haben. Durch die Normalisierung von y werden die Parameter jedoch kleiner und die Konvergenz kann für auf 0 initialisierte Parameter schneller erreicht werden.
In der StandardisierungyyIn diesem Fall lautet die inverse Skalierungsformel der Parameter:
θ 1 ∼ d + 1 new = θ 1 ∼ d + 1 σ x σ y \theta_{1\sim d+1}^{new}=\frac{\ theta_{1\sim d+1}}{\sigma_{x}}\sigma_{y}ich1 ∼ d + 1neu _ _=Pxich1 ∼ d + 1Py
Formel:
θ 0 σ y + θ 1 ∼ d + 1 new ( x 1 ∼ d + 1 − μ x ) = y − μ y \theta_{0}\sigma_{y}+\theta_{1\sim d+1 }^{new}(x_{1\sim d+1}-\mu_{x})=y-\mu_{y}ich0Py+ich1 ∼ d + 1neu _ _( X1 ∼ d + 1−Mx)=j−My
θ 0 neu = θ 0 σ y + μ y − θ 1 ∼ d + 1 neu μ x \theta_{0}^{neu}=\theta_{0}\sigma_{y}+\mu_{y}-\theta_ {1\sim+1}^{neu}\mu_{x}ich0neu _ _=ich0Py+My−ich1 ∼ d + 1neu _ _Mx
Darunter gilt während des Vektorisierungsvorgangs θ 1 ∼ d + 1 new \theta_{1\sim d+1}^{new}ich1 ∼ d + 1neu _ _和μ x \mu_{x}MxSie sind alle Vektoren von (1,d), und die Multiplikation sollte das innere Vektorprodukt verwenden.
3. Implementierung des Codes für den linearen Regressionsalgorithmus
Vektorimplementierung
Seien die Daten x \boldsymbol{x}Die Dimensionen von x sind(n, d) (n,d)( N ,d ) , wobei n die Anzahl der Stichproben und d die Dimension der Stichprobenmerkmale ist. Zur Vereinfachung der Berechnung fügen wir der Stichprobe eine zusätzliche Merkmalsdimension mit allen Werten 1 hinzu, sodass ihre Dimension( n , d + 1 ) (n, d+1)( N ,D+1 )
- Vorhersage
Sei der Parameter θ \boldsymbol{\theta}Die Dimension von θ ist (1, d+1), dann istx θ ⊤ \boldsymbol{x\theta^{\top}}x θ⊤或( θ x ⊤ ) ⊤ \boldsymbol{(\theta x^{\top})^{\top}}( θ x⊤ )⊤Die Dimension kann erhalten werden als(n, 1) (n,1)( N ,1 ) Vorhersageergebnish θ ( x ) h_{\boldsymbol{\theta}}(\boldsymbol{x})Hich( X ) . - Teilen wir die
Größe j durch die Größe:
θ j = θ j − α ∂ ∂ wj J ( θ ; x ) = wj − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x ( i ) \theta_{j}=\theta_{j}-\alpha\frac{\partial}{\partial{w_j}}{J(\theta;\mathbf{x})}=w_ {j }-\alpha\frac{1}{m}\sum_{i=1}^{m}{(h_{\theta}(x^{(i)})-y^{(i)}) x^ {(ich)}}ichj=ichj−A∂ wj∂J ( θ ;X )=wj−AM1ich = 1∑m( Hich( X( ich ) )−j( i ) )x( i )
Tatsächlich setzen wir hierθ 0 \theta_{0}ich0Als Voreingenommenheit sollte sein Gradient sein:
∂ ∂ w 0 J ( θ ; x ) = w 0 − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) \frac{\ partiell}{\partial{w_0}}{J(\theta;\mathbf{x})}=w_{0}-\alpha \frac{1}{m}\sum_{i=1}^{m}{ (h_{\theta}(x^{(i)})-y^{(i)})}∂ w0∂J ( θ ;X )=w0−AM1ich = 1∑m( Hich( X( ich ) )−j( i ) ), da wir die Daten mit Merkmalsdimensionenx 0 x_0X0, sodass er wie andere Parameter mit der obigen Formel berechnet werden kann.
Lassen Sie Fehler FehlerFehlermatrix β\boldsymbol{\beta}β为h θ ( x ) − x h_{\boldsymbol{\theta}}(\boldsymbol{x})-\boldsymbol{x}Hich( X )−x , mit Abmessungen( n , 1 ) (n,1)( N ,1 ) , dannx ⊤ β / n \boldsymbol{x^{\top}\beta} /nX⊤ β/nist die Dimension(d + 1, 1) (d+1,1)( D+1 ,x ⊤ β = [ x ( 1 ) x ( 2 ) ⋯ ] × [ h ( x ( 1 ) ) − y ( 1 ) h ( x (
2 ) ) − y ( 2 ) ⋮ ] = [ ∑ i = 1 n ( h ( x ( i ) ) − y ( i ) ) x 0 ( 1 ) ∑ i = 1 n ( h ( x ( i ) ) − y ( i ) ) x 1 ( 1 ) ⋮ ] \boldsymbol{x^{\top}\beta}= \left[ \begin{matrix} x^{(1)}& x^{(2)} &\cdots \end{matrix} \right] \times \left[ \begin{matrix} h(x^{(1)})-y^{(1)}\\ h(x^{(2)})-y^{(2)}\\ \vdots \end{matrix} \right] =\left[ \begin{matrix} \sum_{i=1}^{n}{(h(x^{(i)})-y^{(i)})x_ {0}^{(1)}}\\ \sum_{i=1}^{n}{(h(x^{(i)})-y^{(i)})x_{1}^{ (1)}}\\ \vdots \end{matrix} \right]X⊤ β=[X( 1 )X( 2 )⋯]× h ( x( 1 ) )−j( 1 )h ( x( 2 ) )−j( 2 )⋮ = ∑ich = 1n( h ( x( ich ) )−j( i ) )x0( 1 )∑ich = 1n( h ( x( ich ) )−j( i ) )x1( 1 )⋮
x ⊤ β / n \boldsymbol{x^{\top}\beta} /nXJedes Element in ⊤ β/n
Python-Code
import numpy as np
def square_loss(pred, target):
"""
计算平方误差
:param pred: 预测
:param target: ground truth
:return: 损失序列
"""
return np.sum(np.power((pred - target), 2))
def compute_loss(pred, target):
"""
计算归一化平均损失
:param pred: 预测
:param target: ground truth
:return: 损失
"""
pred = (pred - pred.mean(axis=0)) / pred.std(axis=0)
target = (pred - target.mean(axis=0)) / target.std(axis=0)
loss = square_loss(pred, target)
return np.sum(loss) / (2 * pred.shape[0])
class LinearRegression:
"""
线性回归类
"""
def __init__(self, x, y, val_x, val_y, epoch=100, lr=0.1):
"""
初始化
:param x: 样本, (sample_number, dimension)
:param y: 标签, (sample_numer, 1)
:param epoch: 训练迭代次数
:param lr: 学习率
"""
self.theta = None
self.loss = []
self.val_loss = []
self.n = x.shape[0]
self.d = x.shape[1]
self.epoch = epoch
self.lr = lr
t = np.ones(shape=(self.n, 1))
self.x_std = x.std(axis=0)
self.x_mean = x.mean(axis=0)
self.y_mean = y.mean(axis=0)
self.y_std = y.std(axis=0)
x_norm = (x - self.x_mean) / self.x_std
y_norm = (y - self.y_mean) / self.y_std
self.y = y_norm
self.x = np.concatenate((t, x_norm), axis=1)
self.val_x = val_x
self.val_y = val_y
def init_theta(self):
"""
初始化参数
:return: theta (1, d+1)
"""
self.theta = np.zeros(shape=(1, self.d + 1))
def validation(self, x, y):
x = (x - x.mean(axis=0)) / x.std(axis=0)
y = (y - y.mean(axis=0)) / y.std(axis=0)
outputs = self.predict(x)
curr_loss = square_loss(outputs, y) / (2 * y.shape[0])
return curr_loss
def gradient_decent(self, pred):
"""
实现梯度下降求解
"""
# error (n,1)
error = pred - self.y
# gradient (d+1, 1)
gradient = np.matmul(self.x.T, error)
# gradient (1,d+1)
gradient = gradient.T / pred.shape[0]
# update parameters
self.theta = self.theta - (self.lr / self.n) * gradient
def train(self):
"""
训练线性回归
:return: 参数矩阵theta (1,d+1); 损失序列 loss
"""
self.init_theta()
for i in range(self.epoch):
# pred (1,n); theta (1,d+1); self.x.T (d+1, n)
pred = np.matmul(self.theta, self.x.T)
# pred (n,1)
pred = pred.T
curr_loss = square_loss(pred, self.y) / (2 * self.n)
val_loss = self.validation(self.val_x, self.val_y)
self.gradient_decent(pred)
self.val_loss.append(val_loss)
self.loss.append(curr_loss)
print("Epoch: {}/{}\tTrain Loss: {:.4f}\tVal loss: {:.4f}".format(i + 1, self.epoch, curr_loss, val_loss))
# un_scaling parameters
self.theta[0, 1:] = self.theta[0, 1:] / self.x_std.T * self.y_std[0]
self.theta[0, 0] = self.theta[0, 0] * self.y_std[0] + self.y_mean[0] - np.dot(self.theta[0, 1:], self.x_mean)
return self.theta, self.loss, self.val_loss
def predict(self, x):
"""
回归预测
:param x: 输入样本 (n,d)
:return: 预测结果 (n,1)
"""
# (d,1)
t = np.ones(shape=(x.shape[0], 1))
x = np.concatenate((t, x), axis=1)
pred = np.matmul(self.theta, x.T)
return pred.T
4. Experimentelle Ergebnisse
Univariate Regression
Aufteilung des Trainingssatzes zur Datensatzvisualisierung und des Testsatzes
from LinearRegression import LinearRegression
epochs = 200
alpha = 1
linear_reg = LinearRegression(x=train_x_ex,y=train_y_ex,val_x=val_x_ex, val_y=val_y_ex, lr=alpha,epoch=epochs)
start_time = time.time()
theta,loss, val_loss = linear_reg.train()
end_time = time.time()
Train Time: 0.0309s
Val Loss: 6.7951
Visualisierung des Trainingsprozesses
und Prognosekurve für den Sk-Learn-Vergleich
multivariable Regression
Datenvisualisierungs- und Trainingsset und Validierungsset
from LinearRegression import LinearRegression
alpha = 0.1
epochs = 1000
multi_lr = LinearRegression(train_x,train_y_ex,val_x=val_x,val_y=val_y_ex, epoch=epochs,lr=alpha)
start_time = time.time()
theta, loss, val_loss = multi_lr.train()
end_time = time.time()
Train Time: 0.1209s
Val Loss: 4.187(采用归一化后数据计算损失)
Visualisierung des Trainingsprozesses
Vorhersageebene (im Vergleich zu sk-learn),
wobei Blau die Vorhersageebene dieses Algorithmus und Grau die Vorhersageebene von sk-learn ist
Zusammenfassung des Experiments
Um bei der Implementierung des linearen Regressionsalgorithmus eine bessere Leistung zu erzielen, können Sie versuchen, die Lernrate oder die Anzahl der Iterationen anzupassen, um eine bessere Leistung zu erzielen. Da Matrixoperationen anstelle von Schleifen verwendet werden, wird die Trainingszeit erheblich verkürzt, sie hat jedoch noch nicht das Niveau der Sk-Learn-Bibliotheksfunktion erreicht.