数据分析(三)线性回归模型实现

news2025/1/13 11:47:55

1. 惩罚线性回归模型概述

线性回归在实际应用时需要对普通最小二乘法进行一些修改。普通最小二乘法只在训练数据上最小化错误,难以顾及所有数据。

惩罚线性回归方法是一族用于克服最小二乘法( OLS)过拟合问题的方法。岭回归是惩罚线性回归的一个特例。岭回归通过对回归系数的平方和进行惩罚来避免过拟合。其他惩罚回归算法使用不同形式的惩罚项。

下面几个特点使得惩罚线性回归方法非常有效:

--模型训练足够快速。

--变量的重要性信息。

--部署时的预测足够快速。

--在各种问题上性能可靠,尤其对样本并不明显多于属性的属性矩阵,或者非常稀疏的矩阵。希望模型为稀疏解(即只使用部分属性进行预测的吝啬模型)。

--问题可能适合使用线性模型来解决。

公式 4-6 可以用如下语言描述:向量 beta 是以及常量 beta 零星是使期望预测的均方

错误最小的值,期望预测的均方错误是指在所有数据行(i=1,...,n)上计算 yi 与预测生成

yi 之间的错误平方的平均。

岭惩罚项对于惩罚回归来说并不是唯一有用的惩罚项。任何关于向量长度的指标都可以。使用不同的长度指标可以改变解的重要性。岭回归应用欧式几何的指标(即 β 的平方和)。另外一个有用的算法称作套索(Lasso)回归,该回归源于出租车的几何路径被称作曼哈顿距离或者 L1 正则化(即 β 的绝对值的和)。ElasticNet 惩罚项包含套索惩罚项以及岭惩罚项。

2. 求解惩罚线性回归问题

有大量通用的数值优化算法可以求解公式 4-6、公式 4-8 以及公式 4-11 对应的优化问题,但是惩罚线性回归问题的重要性促使研究人员开发专用算法,从而能够非常快地生成解。本文将对这些算法进行介绍并且运行相关代码,重点介绍2种算法:最小角度回归 LARS 以及 Glmnet。

LARS 算法可以理解为一种改进的前向逐步回归算法。

之所以介绍 LARS 算法是因为该算法非常接近于套索以及前向逐步回归, LARS 算法很容易理解并且实现起来相对紧凑。通过研究 LARS 的代码,你会理解针对更一般的 ElasticNet 回归求解的具体过程,并且会了解惩罚回归求解的细节。

3. 完整代码(code)

from math import sqrt
import pandas as pd
import matplotlib.pyplot as plt
from tqdm import tqdm


def x_normalized(xList, xMeans, xSD):
    nrows = len(xList)
    ncols = len(xList[0])
    xNormalized = []
    for i in range(nrows):
        rowNormalized = [(xList[i][j] - xMeans[j]) / xSD[j] for j in range(ncols)]
        xNormalized.append(rowNormalized)


def data_normalized(wine):
    nrows, ncols = wine.shape
    wineNormalized = wine
    for i in range(ncols):
        mean = summary.iloc[1, i]
        sd = summary.iloc[2, i]
        wineNormalized.iloc[:, i:(i + 1)] = (wineNormalized.iloc[:, i:(i + 1)] - mean) / sd
    return wineNormalized


def calculate_betaMat(nSteps, stepSize, wineNormalized):
    nrows, ncols = wineNormalized.shape
    # initialize a vector of coefficients beta(系数初始化)
    beta = [0.0] * (ncols - 1)
    # initialize matrix of betas at each step(系数矩阵初始化)
    betaMat = []
    betaMat.append(list(beta))
    # initialize residuals list(误差初始化)
    residuals = [0.0] * nrows
    for i in tqdm(range(nSteps)):
        # calculate residuals(计算误差)
        for j in range(nrows):
            residuals[j] = wineNormalized.iloc[j, (ncols - 1)]
            for k in range(ncols - 1):
                residuals[j] += - wineNormalized.iloc[j, k] * beta[k]

        # calculate correlation between attribute columns from normalized wine and residual(变量与误差相关系数)
        corr = [0.0] * (ncols - 1)
        for j in range(ncols - 1):
            for k in range(nrows):
                corr[j] += wineNormalized.iloc[k, j] * residuals[k] / nrows

        iStar = 0
        corrStar = corr[0]
        for j in range(1, (ncols - 1)):
            if abs(corrStar) < abs(corr[j]):  # 相关性大的放前面
                iStar = j
                corrStar = corr[j]
        beta[iStar] += stepSize * corrStar / abs(corrStar)  # 系数
        betaMat.append(list(beta))
    return betaMat


def plot_betaMat1(betaMat):
    ncols = len(betaMat[0])
    for i in range(ncols):
        # plot range of beta values for each attribute
        coefCurve = betaMat[0:nSteps][i]
        plt.plot(coefCurve)

    plt.xlabel("Attribute Index")
    plt.ylabel(("Attribute Values"))
    plt.show()


def plot_betaMat2(nSteps, betaMat):
    ncols = len(betaMat[0])
    for i in range(ncols):
        # plot range of beta values for each attribute
        coefCurve = [betaMat[k][i] for k in range(nSteps)]
        xaxis = range(nSteps)
        plt.plot(xaxis, coefCurve)

    plt.xlabel("Steps Taken")
    plt.ylabel(("Coefficient Values"))
    plt.show()


def S(z, gamma):
    if gamma >= abs(z):
        return 0.0
    return (z / abs(z)) * (abs(z) - gamma)


if __name__ == '__main__':
    target_url = "http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"
    wine = pd.read_csv(target_url, header=0, sep=";")

    # normalize the wine data
    summary = wine.describe()
    print(summary)

    # 数据标准化
    wineNormalized = data_normalized(wine)
    # number of steps to take(训练步数)
    nSteps = 100
    stepSize = 0.1
    betaMat = calculate_betaMat(nSteps, stepSize, wineNormalized)
    plot_betaMat1(betaMat)
# ----------------------------larsWine---------------------------------------------------
    # read data into iterable
    names = wine.columns
    xList = []
    labels = []
    firstLine = True
    for i in range(len(wine)):
        row = wine.iloc[i]
        # put labels in separate array
        labels.append(float(row[-1]))
        # convert row to floats
        floatRow = row[:-1]
        xList.append(floatRow)
    # Normalize columns in x and labels
    nrows = len(xList)
    ncols = len(xList[0])
    # calculate means and variances(计算均值和方差)
    xMeans = []
    xSD = []
    for i in range(ncols):
        col = [xList[j][i] for j in range(nrows)]
        mean = sum(col) / nrows
        xMeans.append(mean)
        colDiff = [(xList[j][i] - mean) for j in range(nrows)]
        sumSq = sum([colDiff[i] * colDiff[i] for i in range(nrows)])
        stdDev = sqrt(sumSq / nrows)
        xSD.append(stdDev)

    # use calculate mean and standard deviation to normalize xList(X标准化)
    xNormalized = x_normalized(xList, xMeans, xSD)
    # Normalize labels: 将属性及标签进行归一化
    meanLabel = sum(labels) / nrows
    sdLabel = sqrt(sum([(labels[i] - meanLabel) * (labels[i] - meanLabel) for i in range(nrows)]) / nrows)
    labelNormalized = [(labels[i] - meanLabel) / sdLabel for i in range(nrows)]

    # initialize a vector of coefficients beta
    beta = [0.0] * ncols
    # initialize matrix of betas at each step
    betaMat = []
    betaMat.append(list(beta))
    # number of steps to take
    nSteps = 350
    stepSize = 0.004
    nzList = []
    for i in range(nSteps):
        # calculate residuals
        residuals = [0.0] * nrows
        for j in range(nrows):
            labelsHat = sum([xNormalized[j][k] * beta[k] for k in range(ncols)]) 
            residuals[j] = labelNormalized[j] - labelsHat  # 计算残差

        # calculate correlation between attribute columns from normalized wine and residual
        corr = [0.0] * ncols
        for j in range(ncols):
            corr[j] = sum([xNormalized[k][j] * residuals[k] for k in range(nrows)]) / nrows  # 每个属性和残差的关联

        iStar = 0
        corrStar = corr[0]
        for j in range(1, (ncols)):  # 逐个判断哪个属性对降低残差贡献最大
            if abs(corrStar) < abs(corr[j]):  # 好的(最大关联)特征会排到列表前面,应该保留,不太好的特征会排到最后
                iStar = j
                corrStar = corr[j]
        beta[iStar] += stepSize * corrStar / abs(corrStar)  # 固定增加beta变量值,关联为正增量为正;关联为负,增量为负
        betaMat.append(list(beta))  # 求解得到参数结果

        nzBeta = [index for index in range(ncols) if beta[index] != 0.0]
        for q in nzBeta:
            if q not in nzList:  # 对于每一迭代步,记录非零系数对应索引
                nzList.append(q)
    nameList = [names[nzList[i]] for i in range(len(nzList))]
    print(nameList)
    plot_betaMat2(nSteps, betaMat)  # 绘制系数曲线

# -------------------------------larsWine 10折交叉------------------------------------------------
    # Build cross-validation loop to determine best coefficient values.
    # number of cross validation folds
    nxval = 10
    # number of steps and step size
    nSteps = 350
    stepSize = 0.004
    # initialize list for storing errors.
    errors = []  # 记录每一步迭代的错误
    for i in range(nSteps):
        b = []
        errors.append(b)

    for ixval in range(nxval):  # 10折交叉验证
        # Define test and training index sets
        idxTrain = [a for a in range(nrows) if a % nxval != ixval * nxval]
        idxTest = [a for a in range(nrows) if a % nxval == ixval * nxval]
        # Define test and training attribute and label sets
        xTrain = [xNormalized[r] for r in idxTrain]  # 训练集
        labelTrain = [labelNormalized[r] for r in idxTrain]
        xTest = [xNormalized[r] for r in idxTest]  # 测试集
        labelTest = [labelNormalized[r] for r in idxTest]

        # Train LARS regression on Training Data
        nrowsTrain = len(idxTrain)
        nrowsTest = len(idxTest)

        # initialize a vector of coefficients beta
        beta = [0.0] * ncols

        # initialize matrix of betas at each step
        betaMat = []
        betaMat.append(list(beta))
        for iStep in range(nSteps):
            # calculate residuals
            residuals = [0.0] * nrows
            for j in range(nrowsTrain):
                labelsHat = sum([xTrain[j][k] * beta[k] for k in range(ncols)])
                residuals[j] = labelTrain[j] - labelsHat
            # calculate correlation between attribute columns from normalized wine and residual
            corr = [0.0] * ncols
            for j in range(ncols):
                corr[j] = sum([xTrain[k][j] * residuals[k] for k in range(nrowsTrain)]) / nrowsTrain

            iStar = 0
            corrStar = corr[0]
            for j in range(1, (ncols)):
                if abs(corrStar) < abs(corr[j]):
                    iStar = j
                    corrStar = corr[j]
            beta[iStar] += stepSize * corrStar / abs(corrStar)
            betaMat.append(list(beta))

            # Use beta just calculated to predict and accumulate out of sample error - not being used in the calc of beta
            for j in range(nrowsTest):
                labelsHat = sum([xTest[j][k] * beta[k] for k in range(ncols)])
                err = labelTest[j] - labelsHat
                errors[iStep].append(err)
    cvCurve = []
    for errVect in errors:
        mse = sum([x * x for x in errVect]) / len(errVect)
        cvCurve.append(mse)
    minMse = min(cvCurve)
    minPt = [i for i in range(len(cvCurve)) if cvCurve[i] == minMse][0]
    print("Minimum Mean Square Error", minMse)
    print("Index of Minimum Mean Square Error", minPt)

    xaxis = range(len(cvCurve))
    plt.plot(xaxis, cvCurve)
    plt.xlabel("Steps Taken")
    plt.ylabel(("Mean Square Error"))
    plt.show()

    # -------------------------------glmnet larsWine2------------------------------------------------
    # select value for alpha parameter
    alpha = 1.0
    # make a pass through the data to determine value of lambda that
    # just suppresses all coefficients.
    # start with betas all equal to zero.
    xy = [0.0] * ncols
    for i in range(nrows):
        for j in range(ncols):
            xy[j] += xNormalized[i][j] * labelNormalized[i]

    maxXY = 0.0
    for i in range(ncols):
        val = abs(xy[i]) / nrows
        if val > maxXY:
            maxXY = val

    # calculate starting value for lambda
    lam = maxXY / alpha

    # this value of lambda corresponds to beta = list of 0's
    # initialize a vector of coefficients beta
    beta = [0.0] * ncols

    # initialize matrix of betas at each step
    betaMat = []
    betaMat.append(list(beta))

    # begin iteration
    nSteps = 100
    lamMult = 0.93  # 100 steps gives reduction by factor of 1000 in
    # lambda (recommended by authors)
    nzList = []
    for iStep in range(nSteps):
        # make lambda smaller so that some coefficient becomes non-zero
        lam = lam * lamMult

        deltaBeta = 100.0
        eps = 0.01
        iterStep = 0
        betaInner = list(beta)
        while deltaBeta > eps:
            iterStep += 1
            if iterStep > 100:
                break
            # cycle through attributes and update one-at-a-time
            # record starting value for comparison
            betaStart = list(betaInner)
            for iCol in range(ncols):
                xyj = 0.0
                for i in range(nrows):
                    # calculate residual with current value of beta
                    labelHat = sum([xNormalized[i][k] * betaInner[k] for k in range(ncols)])
                    residual = labelNormalized[i] - labelHat

                    xyj += xNormalized[i][iCol] * residual

                uncBeta = xyj / nrows + betaInner[iCol]
                betaInner[iCol] = S(uncBeta, lam * alpha) / (1 + lam * (1 - alpha))

            sumDiff = sum([abs(betaInner[n] - betaStart[n]) for n in range(ncols)])
            sumBeta = sum([abs(betaInner[n]) for n in range(ncols)])
            deltaBeta = sumDiff / sumBeta
        print(iStep, iterStep)
        beta = betaInner
        # add newly determined beta to list
        betaMat.append(beta)
        # keep track of the order in which the betas become non-zero
        nzBeta = [index for index in range(ncols) if beta[index] != 0.0]
        for q in nzBeta:
            if q not in nzList:
                nzList.append(q)
    # print out the ordered list of betas
    nameList = [names[nzList[i]] for i in range(len(nzList))]
    print(nameList)
    nPts = len(betaMat)
    plot_betaMat2(nPts, betaMat)  # 绘制系数曲线

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1569968.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux基础篇:文件系统介绍——根目录下文件夹含义与作用介绍

Linux文件系统介绍——文件夹含义与作用 Linux文件系统是一个组织和管理文件的层次结构。它包括了目录、子目录和文件&#xff0c;这些都是按照一定的规则和标准进行组织的。以下是Linux文件系统的一些关键组成部分&#xff1a; 1./bin&#xff1a; 该目录包含了系统启动和运…

Anaconda/Python快速安装jieba 【win/mac】

一、直接上命令 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jieba 我是在PyCharm里面的终端输进去。 之后就很快速的看到成功的下图。 二、官网 官网下载的速度太慢了——这是官网地址https://pypi.org/project/jieba/#files 点进去之后点击下载&#xff0c…

一文掌握线程池实现原理

线程池简介 Java在使用线程执行程序时&#xff0c;需要调用操作系统内核的API创建一个内核线程&#xff0c;操作系统要为线程分配一系列的资源&#xff1b;当该Java线程被终止时&#xff0c;对应的内核线程也会被回收。因此&#xff0c;频繁的创建和销毁线程需要消耗大量资源。…

书生·浦语大模型实战营 | 第2次学习笔记

前言 书生浦语大模型应用实战营 第二期正在开营&#xff0c;欢迎大家来学习。&#xff08;参与链接&#xff1a;课程升级&#xff0c;算力免费&#xff0c;书生浦语实战营第二期学员招募&#xff5c;活动预告https://mp.weixin.qq.com/s/YYSr3re6IduLJCAh-jgZqg&#xff09; …

蓝桥杯:七步诗 ← bfs

【题目来源】https://www.lanqiao.cn/problems/3447/learning/【题目描述】 煮豆燃豆苴&#xff0c;豆在釜中泣。本是同根生&#xff0c;相煎何太急?---曹植 所以&#xff0c;这道题目关乎豆子! 话说赤壁之战结束后&#xff0c;曹操的船舰被刘备烧了&#xff0c;引领军队从华容…

域名如何端口映射?

域名端口映射是一种重要的网络技术&#xff0c;它可以实现不同设备之间的远程通信。在全球互联网的背景下&#xff0c;人们之间的通信变得非常便捷&#xff0c;但随之而来的问题是如何有效地实现设备之间的互联互通。域名端口映射正是为了解决这个问题而出现的。 天联组网 天联…

单片机之LED与按键

目录 LED LED灯亮的原理图 LED灯光闪烁 电路设计 keil文件 LED流水灯的实现 keil文件 单片机之按键 键盘的结构 按键消抖 软件消抖 硬件消抖 键盘的分类 独立式键盘 行列式键盘 键盘的识别 独立按键案例 电路图 keil文件 行列式键盘案例 电路图 对应按键…

该主机与 Cloudera Manager Server 失去联系的时间过长。 该主机未与 Host Monitor 建立联系

该主机与 Cloudera Manager Server 失去联系的时间过长。 该主机未与 Host Monitor 建立联系 这个去集群主机cm界面上看会出现这个错误 排查思路&#xff1a; 一般比较常见的原因可能是出问题的主机和集群主节点的时间对应不上了。还有就是cm agent服务出现问题了 去该主机的…

开源模型应用落地-chatglm3-6b模型小试-入门篇(三)

一、前言 刚开始接触AI时&#xff0c;您可能会感到困惑&#xff0c;因为面对众多开源模型的选择&#xff0c;不知道应该选择哪个模型&#xff0c;也不知道如何调用最基本的模型。但是不用担心&#xff0c;我将陪伴您一起逐步入门&#xff0c;解决这些问题。 在信息时代&#xf…

安卓开机动画

目录 一、开机动画的2种模式1.1 android模式1.2 movie模式 二、开机动画代码运行位置三、删除开机动画四、自定义开机动画实践 一、开机动画的2种模式 一种是使用两张图片利用某种效果来造成动态&#xff0c;另一种则是用一个图包循环显示的方式来形成动态。当然&#xff0c;这…

JAVA基础03-scanner,输出,循环,if的使用以及eclipse的安装

目录 scanner的使用 if语句的使用 eclipse的使用 switch语句的使用 输出方法的使用 循环语句 scanner的使用 实现用户数据的交互&#xff0c;用户通过终端输入数据 注意&#xff1a;使用Scanner需要导包 在程序开头加上&#xff1a;import java.util.Scanner; //由于S…

【设计原则】CQRS

文章目录 概述组成与特点优缺点何时使用 CQRS 模式推荐阅读 概述 CQRS&#xff08;Command Query Responsibility Segregation&#xff09;是一种软件设计模式&#xff0c;其核心设计理念是将一个对象的数据访问&#xff08;查询&#xff09;和数据操作&#xff08;命令&#…

QT----YOLOv5检测平台

目录 1 opencv环境安装1.1 报错Could NOT find CUDNN (missing: CUDNN_LIBRARY CUDNN_INCLUDE_DIR) (Required is at least version "7.5")1.2 使用camkevs编译opencv4.8.01.3 报错operator !":重载函数具有类似的转换(编译源文件 H:\opencv-4.8.0\opencv-4.8.0…

PAC性能开销权衡及优化措施

PAC性能开销&#xff1f;如何进行优化&#xff1f;本博客探讨这些问题。

[StartingPoint][Tier0]Mongod

Task 1 How many TCP ports are open on the machine? (机器上打开了多少个 TCP 端口&#xff1f;) Example: $ sudo nmap -sS -T4 10.129.222.112 -p 27017,22 2 Task 2 Which service is running on port 27017 of the remote host? (哪个服务正在远程主机的端口 270…

NASA数据集——1980 年至 2020 年北美 3km分辨率气温(摄氏度)、相对湿度(%)、风速(米/秒)、风向(真北偏角)、总降水量(雨+雪)等数据集

Daily SnowModel Outputs Covering the ABoVE Core Domain, 3-km Resolution, 1980-2020 简介 文件修订日期&#xff1a;2023-01-27 数据集版本: 1 摘要 该数据集提供了 1980 年 9 月 1 日至 2020 年 8 月 31 日期间 3 千米网格上的 SnowModel 每日模拟输出&#xff0c;涵…

Java快速入门系列-3(Java基础)

第三章&#xff1a;Java基础 3.1 Java语法基础3.1.1 Java程序入口点&#xff1a;main方法3.1.2 注释3.1.3 变量声明与赋值3.1.4 数据类型3.1.5 标识符与关键字 3.2 数据类型与变量3.2.1 基本数据类型3.2.2 引用数据类型 3.3 控制流程3.3.1 条件语句3.3.2 循环结构 3.4 数组与集…

mbti,ESTP型人格的心理问题分析

什么是ESTP型人格 ESTP分别代表外向&#xff0c;实感&#xff0c;理智&#xff0c;依赖&#xff0c;而ESTP型人格则是一种性格上十分激进&#xff0c;喜欢冒险&#xff0c;并且总是因为情绪起伏过大&#xff0c;而一下子做出应激行为的相对冒险的人格。具有ESTP型人格的人一般…

页面刚加载的时候显示自己定义的{{***}}然后一闪而过

这时候别用插值表达式语法了&#xff0c;直接用v-text或者v-html就能解决这个问题 但是有个问题&#xff0c;如下图所示&#xff1a; 具体bind使用方式&#xff0c;如下图所示&#xff1a; 但是v-bind也可以进行简写&#xff0c;就是去掉v-bind&#xff0c;直接写&#xff1a…

提高空调压缩机能效的通用方法

压缩机的能效提高主要依靠技术改进而不是大幅度增加材料的消耗&#xff0c;这也是技术经济性最好的节能手段。 1、改进电机效率&#xff0c;电机效率的提高意味着压缩机电效率的提高和压缩机总体效率的提高&#xff1b; 1.1、降低定子铜耗 降低定子绕组中电流通过所产生的铜耗…