作为一名曾经研究过人工神经网络的菜鸟,前两天刚听说有岭回归估计和LASSO估计,统计学老师也布置了作业,然,在不甚理解的情况下,用Python写了一下,也不知是否正确。不合适的地方请不吝赐教。

作业如下:

python 岭回归summary python 岭回归LASSO回归_LASSO

x,y已知,分别用岭估计和LASSO估计,估计

python 岭回归summary python 岭回归LASSO回归_岭回归_02

的值,并使用MSE评估估计结果。

个人理解:

在完全没有数据的情况下,很显然,需要随机生成一些数据。在年少的时候就知道,若已知

python 岭回归summary python 岭回归LASSO回归_岭回归_02


python 岭回归summary python 岭回归LASSO回归_python 岭回归summary_04

值,给定一个x就会有个y生成。

所以

第一步:肯定是要生成一批y,将

python 岭回归summary python 岭回归LASSO回归_岭回归_02

作为真实值,用来与接下来估计出的值进行比较。第二步,应该是在给定x,y的条件下,使用岭估计和LASSO估计来得到

python 岭回归summary python 岭回归LASSO回归_岭回归_02

的估计值。

(额,好像说的像废话)

对于岭估计和LASSO估计,是由岭回归和LASSO方法来的。

关于岭回归和LASSO的理论知识,可以参看如下链接:

机器学习-第3周,岭回归和lasso   (个人觉着,讲的挺好的)


接下来,在了解了理论知识的皮毛,开始实现代码。

(这样其实不好,要深入了解理论知识后,才好开始写代码。因为如果一开始想的问题不对,可能会造成代码的全盘推翻。)

说一下我实现代码的整个思路:

      # 问题描述:模型 y=x*b+a 。给定x,y估计b。
      # 整体思路:
      # 0. 初始化,设置全局参数:n为数据总量,dim为维度
      # 1。随机生成n*dim维的x,dim*1维的系数b和a,求出y值
      # 2. 随机生成模型参数Lambda,确定回归模型,得到模型系数B和Lambda的图像
      # 3. 通过验证,确定最优回归模型的Lambda值
      # 4. 基于最优的Lamma建模,并给定x,y 确定系数_B
      # 5. 评估真实系数b和模型系数B的MSE


代码片段如下:(整个代码会在后面提供链接)

1.初始化 随机生成n*dim维的x,dim*1维的系数b和a,求出y值,返回x,y,b

def ini_data(n,dim):
    '''
    初始化数据
    :param n: 数据总量
    :param dim: 参数维度
    :return: x,y,b(系数)
    '''
    x = np.random.uniform(-100,100,(n,dim))
    b = np.random.rand(dim)
    a = np.random.rand(n)
    y=np.matmul(x,b)+a
    return x,y,b

2. 岭回归模型

def reg_model_Ridge(x,y,alphas,dim):
    '''
    ;岭回归估计
    :param x:
    :param y:
    :param alphas: 随机生成多个模型参数Lambda
    :param dim:维度
    :return: ridge_B 最优模型的系数
    '''
    model_coff=[]
    for alpha in alphas:
        ridge = Ridge(alpha=alpha,normalize=True)
        ridge.fit(x,y)
        model_coff.append(ridge.coef_)
    # if dim<=10:
    #plot_data(alphas, model_coff, 'Log Alpha', 'Cofficients', 'alpha系数与岭回归系数的关系 ,dim='+str(dim))
    # 交叉验证,找到模型最优的Lambda值
    ridge_cv= RidgeCV(alphas=alphas,normalize=True,scoring="neg_mean_absolute_error", cv=5)
    ridge_cv.fit(x,y)
    ridge_best_lambda = ridge_cv.alpha_
    # 建立最优模型
    ridge = Ridge(alpha=ridge_best_lambda,normalize=True)
    ridge.fit(x,y)
    # 得到最优模型的系数
    ridge_B = ridge.coef_
    return ridge_B

3.LASSO模型

def reg_model_LASSO(x,y,alphas,dim):
    '''
    ;LASSO 回归
    :param x:
    :param y:
    :param alphas: 随机生成多个模型参数Lambda
    :param dim:维度
    :return: lasso_B 最优模型的系数
    '''
    model_coff=[]
    for alpha in alphas:
        lasso = Lasso(alpha=alpha,normalize=True)
        lasso.fit(x,y)
        model_coff.append(lasso.coef_)
    # if dim <= 10:
    #plot_data(alphas, model_coff, 'Log Alpha', 'Cofficients', 'alpha系数与LASSO系数的关系 ,dim='+str(dim))
    # 交叉验证,找到模型最优的Lambda值
    lasso_cv= LassoCV(alphas=alphas,normalize=True,max_iter=1000, cv=5)
    lasso_cv.fit(x,y)
    ridge_best_lambda = lasso_cv.alpha_
    # 建立最优模型
    lasso = Lasso(alpha=ridge_best_lambda,normalize=True)
    lasso.fit(x,y)
    # 得到最优模型的系数
    lasso_B = lasso.coef_
    return lasso_B

说明:

岭回归和LASSO回归在Python包sklearn.linear_model中已经写好了,而且还有相对应的交叉验证的模型。

两块代码整体上是一样的,首先,生成一批的alpha值,可以画出alpha值和模型系数中间的关系(为什么?这个我现在也不甚了解,希望大神可以指点一二)。然后,通过校验模型,来确定最优模型的alpha值。最后,基于最优的alpha值建立模型,得到最优模型的系数(也就是估计出来的

python 岭回归summary python 岭回归LASSO回归_岭回归_02

值)

注明几点:

(1)我们需要随机生成一批模型的alpha变量,因为很多时候,我们需要通过实验来选择最佳的alpha值,给指定一个具体的alpha值,就会建成一个新的模型。

(2)在模型的调用上,沿用了训练神经网络的方式,像.fit()函数,用来向模型中喂入数据。可以通过“.”来获得模型中的参数值。

(3)岭回归校验方法(RidgeCV)中,有个scoring参数,而LASSO校验中没有。

(4)在运行中,如果scoring="mean_absolute_error"会出错,要改为scoring="neg_mean_absolute_error"。

5. 运行代码 (作业要求对数据对个维度进行比较,所以用了for循环)

def run_fun():
    n =500  # data length
    dims = [10,50,100,200]
    for dim in dims:
        # alphas = 10 ** np.random.uniform(-5,5,dim)
        alphas = 10 ** np.linspace(-5, 5, dim)
        x, y, b=ini_data(n,dim)
        ridge_B=reg_model_Ridge(x,y,alphas,dim)
        RMSE = np.sqrt(mean_squared_error(ridge_B, b))
        print("----------维度:", dim, ",---------")
        print("岭回归 MSE :",RMSE)
        lasso_B=reg_model_LASSO(x,y,alphas,dim)
        LMSE = np.sqrt(mean_squared_error(lasso_B, b))
        print("LASSO MSE :", LMSE)
 run_fun()

6.结束了,就这样。

代码链接:

运行的结果是这样子的:

python 岭回归summary python 岭回归LASSO回归_python 岭回归summary_08

python 岭回归summary python 岭回归LASSO回归_岭回归_09

 

python 岭回归summary python 岭回归LASSO回归_岭估计_10