手書きアルゴリズム-リッジ(L2正規用語)回帰を達成するためのPythonコード

リッジ入門

前の2つの記事では、オーバーフィッティングと正規化を紹介し、L1とL2の正規化の原則と特性についてより包括的に説明しました。
リンク:原則分析-オーバーフィッティングと正規化

そして、なげなわ回帰を達成するためのpythonコード;
リンク:手書きのアルゴリズム-なげなわ回帰を達成するためのpythonコード

今日は、これに基づいて、比較的単純な
リッジ回帰について説明します。この記事では、主にPythonコード(L2正規用語を使用)のリッジ回帰を実装し、例を使用して原理を証明します。

リッジ回帰分析とPythonコードの実装

前の記事から生成されたデータセットを引用する:

import numpy as np
from matplotlib import pyplot as plt
import sklearn.datasets

#生成100个一元回归数据集
x,y = sklearn.datasets.make_regression(n_features=1,noise=5,random_state=2020)
plt.scatter(x,y)
plt.show()

#加5个异常数据,为什么这么加,大家自己看一下生成的x,y的样子
a = np.linspace(1,2,5).reshape(-1,1)
b = np.array([350,380,410,430,480])

#生成加入异常数据后新的数据集
x_1 = np.r_[x,a]
y_1 = np.r_[y,b]

plt.scatter(x_1,y_1)
plt.show()

ここに写真の説明を挿入
ここに写真の説明を挿入
上記は、正常なデータセットと5つの異常なデータが追加された画像です。線形回帰を直接使用して適合させる場合:

class normal():
    def __init__(self):
        pass

    def fit(self,x,y):
        m=x.shape[0]
        X = np.concatenate((np.ones((m,1)),x),axis=1)
        xMat=np.mat(X)
        yMat =np.mat(y.reshape(-1,1))

        xTx=xMat.T*xMat
        #xTx.I为xTx的逆矩阵
        ws=xTx.I*xMat.T*yMat
        
        #返回参数
        return ws
         


plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
clf1 =normal()
#拟合原始数据
w1 = clf1.fit(x,y)
#预测数据
y_pred = x * w1[1] + w1[0]

#拟合新数据
w2 = clf1.fit(x_1,y_1)
#预测数据
y_1_pred = x_1 * w2[1] + w2[0]

print('原始样本拟合参数:\n',w1)
print('\n')
print('新样本拟合参数:\n',w2)

ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

ここに写真の説明を挿入
いくつかの異常なポイントデータのために、新しいフィット回帰線のパラメータは19ポイント以上から47ポイント以上に大幅に大きくなり、実際のデータ分布から外れ、モデルのパフォーマンスが低下します。

モデルを調整するためにL2正規用語を追加します。以下は、L2正規化の損失関数です。
ここに写真の説明を挿入

方法1:リッジ回帰パラメータを解くための勾配降下法

前回の記事では、線形回帰の勾配とL2正規項の勾配を推定しました。この勾配は、2つを加算するか、忘れるか、または記述
ここに写真の説明を挿入
します。次のようにpythonコードを記述します(つまり、元の線形回帰勾配にL2を加算します)。勾配):

class ridge():
    def __init__(self):
        pass
    
    #梯度下降法迭代训练模型参数,x为特征数据,y为标签数据,a为学习率,epochs为迭代次数,Lambda为正则项参数
    def fit(self,x,y,a,epochs,Lambda):  
        #计算总数据量
        m=x.shape[0]
        #给x添加偏置项
        X = np.concatenate((np.ones((m,1)),x),axis=1)
        #计算总特征数
        n = X.shape[1]
        #初始化W的值,要变成矩阵形式
        W=np.mat(np.ones((n,1)))
        #X转为矩阵形式
        xMat = np.mat(X)
        #y转为矩阵形式,这步非常重要,且要是m x 1的维度格式
        yMat =np.mat(y.reshape(-1,1))
        #循环epochs次
        for i in range(epochs):
            gradient = xMat.T*(xMat*W-yMat)/m + Lambda * W
            W=W-a * gradient
        return W
    def predict(self,x,w):  #这里的x也要加偏置,训练时x是什么维度的数据,预测也应该保持一样
        return np.dot(x,w)

リッジ回帰を実現するためのridge()関数の例(以下のパラメーターはすべてデバッグ後のものであり、モデルを収束させ、反復回数を増やし続け、学習率を変更できることを確認しました。最終的なモデル係数は変更されません):

Lambdaパラメータが0の場合、つまりL2正規項が追加されていない場合、それは通常の線形回帰であり、パラメータ出力は同じで、47ポイントを超えます。

#Lambda=0时;
clf = ridge()
w = clf.fit(x_1,y_1,a = 0.001,epochs = 10000,Lambda=0)
print(w)

#计算新的拟合值
y_1_pred = x_1 * w[1] + w[0]

ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

ここに写真の説明を挿入

Lambda = 0.5の場合、パラメーターは31ポイント以上になります。

#Lambda=0.5时;
clf = ridge()
w = clf.fit(x_1,y_1,a = 0.001,epochs = 10000,Lambda=0.5)
print(w)

#计算新的拟合值
y_1_pred = x_1 * w[1] + w[0]

ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

ここに写真の説明を挿入

Lambda = 1.5の場合、パラメーターは18ポイントを超えます。これは、基本的に、外れ値を追加しないパラメーターと同じです。

#Lambda=1.5时;
clf = ridge()
w = clf.fit(x_1,y_1,a = 0.001,epochs = 10000,Lambda=1.5)
print(w)

#计算新的拟合值
y_1_pred = x_1 * w[1] + w[0]

ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

ここに写真の説明を挿入

Lambda = 20の場合、パラメータは2ポイントを超え、フィッティングラインはほぼ水平線になります。この時点では、フィッティングが大幅に不足しており、損失関数の値が非常に大きく、モデルがまったく収束していません。

#Lambda=20时;
clf = ridge()
w = clf.fit(x_1,y_1,a = 0.001,epochs = 10000,Lambda=20)
print(w)

#计算新的拟合值
y_1_pred = x_1 * w[1] + w[0]

ax1= plt.subplot()
ax1.scatter(x_1,y_1,label='样本分布')
ax1.plot(x,y_pred,c='y',label='原始样本拟合')
ax1.plot(x_1,y_1_pred,c='r',label='新样本拟合')
ax1.legend(prop = {'size':15}) #此参数改变标签字号的大小
plt.show()

ここに写真の説明を挿入
適切なL2正規項パラメーターがオーバーフィットを防ぐことができることがわかります。
ラムダパラメーターがどんどん大きくなると、モデルパラメーターはどんどん小さくなり、ゆっくりとゼロに近づきます。

方法2:リッジ回帰を達成するための標準方程式法

次に、標準方程式法を使用してリッジ回帰を実現します。導出式は次のとおりです
ここに写真の説明を挿入。pythonコードは次のように実装されます。

class standard_ridge():
    def __init__(self):
        pass

    def fit(self,x,y,Lambda):
        m = x.shape[0]
        X = np.concatenate((np.ones((m,1)),x),axis=1)
        xMat= np.mat(X)
        yMat = np.mat(y.reshape(-1,1))

        xTx = xMat.T * xMat
        #生成单位矩阵,2个矩阵行列相等才可以相加
        #前面的梯度下降法代码中,我们没有省掉m,因此,我们化简时,也不省掉m,最后形式就是在正则项梯度这里乘以m,其实不会造成本质影响
        rxTx = xTx + np.eye(xMat.shape[1]) * Lambda * m
        
        #rxTx.I为rxTx的逆矩阵
        w = rxTx.I * xMat.T * yMat
        
        return w

操作の結果は次のとおりです。
ここに写真の説明を挿入
基本的に結果は同じですが、この形式の方が簡潔で便利です。

比較するにはsklearnを呼び出します

from sklearn.linear_model import Ridge
lr=Ridge(alpha=0)
lr.fit(x_1,y_1)
print('alpha=0时',lr.coef_,'\n')

lr=Ridge(alpha=40)
lr.fit(x_1,y_1)
print('alpha=40时',lr.coef_,'\n')

lr=Ridge(alpha=150)
lr.fit(x_1,y_1)
print('alpha=150时',lr.coef_,'\n')

lr=Ridge(alpha=2000)
lr.fit(x_1,y_1)
print('alpha=2000时',lr.coef_)

ここに写真の説明を挿入

sklearn OracleRidge:

1.アルファ値が増加する、つまり正規項の係数が増加すると、係数はますます0に近づきますが、0に等しいものはありません。

#用波士顿房价回归数据集展示
data =  sklearn.datasets.load_boston()
x =data['data']
y= data['target']

lr=Ridge(alpha=0)
lr.fit(x,y)
print('alpha=0时',lr.coef_,'\n')

lr=Ridge(alpha=10)
lr.fit(x,y)
print('alpha=10时',lr.coef_,'\n')

lr=Ridge(alpha=100)
lr.fit(x,y)
print('alpha=100时',lr.coef_,'\n')

lr=Ridge(alpha=1000)
lr.fit(x,y)
print('alpha=1000时',lr.coef_)

ここに写真の説明を挿入
概要:ここでは線形回帰シリーズを紹介しました。多くの概念が初めて導入されたため、読者が理解できるようにデータ例を補足し、同時にこれらの基本概念を手動で再現するために、非常に細心の注意を払って記述されています。明確であり、後で複雑なアルゴリズムを説明すると便利です。

次に、ロジスティック回帰を紹介します。

おすすめ

転載: blog.csdn.net/weixin_44700798/article/details/110738525