线性回归python实现详解(附公式推导)

这篇具有很好参考价值的文章主要介绍了线性回归python实现详解(附公式推导)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1线性回归

1.1简单线性回归

线性回归python实现详解(附公式推导)

在简单线性回归中,输入x只有一个特征,通过调整a和b的参数值,来拟合从x到y的线性关系。下图为进行拟合所需要优化的目标,也即是MES(Mean Squared Error),只不过省略了平均的部分(除以m)。

线性回归python实现详解(附公式推导)

对于简单线性回归,只有两个参数a和b,通过对MSE优化目标求导后取极值点极值(最小二乘法),即可求得最优a和b如下,所以在训练简单线性回归模型时,也只需要根据数据求解这两个参数值即可。

线性回归python实现详解(附公式推导)

下面使用波士顿房价数据集中,索引为5(第6个特征)的特征RM (average number of rooms per dwelling:每个住宅的平均房间数)来进行简单线性回归。其中使用的评价指标为:

线性回归python实现详解(附公式推导)
线性回归python实现详解(附公式推导)
线性回归python实现详解(附公式推导)

以及R方指标。这里R方指标一般情况下可以将对模型的评价压缩到[0,1]之间(也可能是负数),值越接近1效果越好。在式子分子分母中的两项都可以认作在算均方误差,只不过分子使用我们训练的线性回归模型的输出,分母则使用真实标签数据的平均值来做均方误差,表示对每个样本,都是一个固定值瞎猜结果,其值等价于实际标签值的方差。通过模型的均方误差和瞎猜产生的误差做对比,就可以将评价指标限定在[0,1](如果模型比瞎猜还差就会成为负数)。

线性回归python实现详解(附公式推导)
线性回归python实现详解(附公式推导)
# 以sklearn的形式对simple linear regression 算法进行封装
import numpy as np
import sklearn.datasets as datasets
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error,mean_absolute_error
np.random.seed(123)

class SimpleLinearRegression():
    def __init__(self):
        """
        initialize model parameters
        """
        self.a_=None
        self.b_=None

    def fit(self,x_train,y_train):
        """
        training model parameters

        Parameters
        ----------
            x_train:train x ,shape:data [N,]
            y_train:train y ,shape:data [N,]
        """
        assert (x_train.ndim==1 and y_train.ndim==1),\
            """Simple Linear Regression model can only solve single feature training data"""
        assert len(x_train)==len(y_train),\
            """the size of x_train must be equal to y_train"""

        x_mean=np.mean(x_train)
        y_mean=np.mean(y_train)
        self.a_=np.vdot((x_train-x_mean),(y_train-y_mean))/np.vdot((x_train-x_mean),(x_train-x_mean))
        self.b_=y_mean-self.a_*x_mean

    def predict(self,input_x):
        """
        make predictions based on a batch of data

        Parameters
        ----------
            input_x:shape->[N,]
        """
        assert input_x.ndim==1 ,\
            """Simple Linear Regression model can only solve single feature data"""

        return np.array([self.pred_(x) for x in input_x])

    def pred_(self,x):
        """
        give a prediction based on single input x
        """
        return self.a_*x+self.b_

    def __repr__(self):
        return "SimpleLinearRegressionModel"

if __name__ == '__main__':
    boston_data = datasets.load_boston()
    print(boston_data['DESCR'])
    x = boston_data['data'][:, 5]  # total x data (506,)
    y = boston_data['target']  # total y data (506,)
    # keep data with target value less than 50.
    x = x[y < 50]  # total x data (490,)
    y = y[y < 50]  # total x data (490,)

    plt.scatter(x, y)
    plt.show()

    # train size:(343,) test size:(147,)
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)

    regs = SimpleLinearRegression()
    regs.fit(x_train, y_train)
    y_hat = regs.predict(x_test)

    rmse = np.sqrt(np.sum((y_hat - y_test) ** 2) / len(x_test))
    mse = mean_squared_error(y_test, y_hat)
    mae = mean_absolute_error(y_test, y_hat)
    # notice
    R_squared_Error = 1 - mse / np.var(y_test)

    print('mean squared error:%.2f' % (mse))
    print('root mean squared error:%.2f' % (rmse))
    print('mean absolute error:%.2f' % (mae))
    print('R squared Error:%.2f' % (R_squared_Error))

    a = regs.a_
    b = regs.b_
    x_plot = np.linspace(4, 8, 50)
    y_plot = x_plot * a + b
    plt.scatter(x, y)
    plt.plot(x_plot, y_plot, color='red')
    plt.show()

输出结果:

mean squared error:26.74
root mean squared error:5.17
mean absolute error:3.85
R squared Error:0.50

数据的可视化:

线性回归python实现详解(附公式推导)

1.2 多元线性回归的正规方程解

线性回归python实现详解(附公式推导)

多元线性回归中,单个x的样本拥有了多个特征,也就是上图中带下标的x。
其结构可以用向量乘法表示出来:
为了便于计算,一般会将x增加一个为1的特征,方便与截距bias计算。

线性回归python实现详解(附公式推导)
线性回归python实现详解(附公式推导)

而多元线性回归的优化目标与简单线性回归一致。

线性回归python实现详解(附公式推导)

通过矩阵求导计算,可以得到方程解,但求解的时间复杂度很高。

线性回归python实现详解(附公式推导)

下面使用正规方程解的形式,来对波士顿房价的所有特征做多元线性回归。

from math import sqrt
import numpy as np
#from PlayML.metrics import r2_score
from sklearn.model_selection import train_test_split
import sklearn.datasets as datasets
#from PlayML.metrics import  root_mean_squared_error
np.random.seed(123)


def mean_squared_error(y_true, y_predict):
    """计算y_true和y_predict之间的MSE"""
    assert len(y_true) == len(y_predict), \
        "the size of y_true must be equal to the size of y_predict"

    return np.sum((y_true - y_predict)**2) / len(y_true)
def r2_score(y_true, y_predict):
    """计算y_true和y_predict之间的R Square"""
    return 1 - mean_squared_error(y_true, y_predict)/np.var(y_true)

def root_mean_squared_error(y_true, y_predict):
    """计算y_true和y_predict之间的RMSE"""

    return sqrt(mean_squared_error(y_true, y_predict))

class LinearRegression():
    def __init__(self):
        self.coef_=None # coeffient
        self.intercept_=None # interception
        self.theta_=None

    def fit_normal(self, x_train, y_train):
        """
        use normal equation solution for multiple linear regresion as model parameters

        Parameters
        ----------
        theta=(X^T * X)^-1 * X^T * y
        """
        assert x_train.shape[0] == y_train.shape[0],\
            """size of the x_train must be equal to y_train """
        X_b=np.hstack([np.ones((len(x_train), 1)), x_train])
        self.theta_=np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train) # (featere,1)
        self.coef_=self.theta_[1:]
        self.intercept_=self.theta_[0]

    def predict(self,x_pred):
        """给定待预测数据集X_predict,返回表示X_predict的结果向量"""
        assert self.intercept_ is not None and self.coef_ is not None, \
            "must fit before predict!"
        assert x_pred.shape[1] == len(self.coef_), \
            "the feature number of X_predict must be equal to X_train"
        X_b=np.hstack([np.ones((len(x_pred),1)),x_pred])
        return X_b.dot(self.theta_)

    def score(self,x_test,y_test):
        """
        Calculate evaluating indicator socre

        Parameters
        ---------
            x_test:x test data
            y_test:true label y for x test data
        """
        y_pred=self.predict(x_test)
        return r2_score(y_test,y_pred)

    def __repr__(self):
        return "LinearRegression"


if __name__ == '__main__':
    # use boston house price dataset for test
    boston_data = datasets.load_boston()
    x = boston_data['data']  # total x data (506,)
    y = boston_data['target']  # total y data (506,)
    # keep data with target value less than 50.
    x = x[y < 50]  # total x data (490,)
    y = y[y < 50]  # total x data (490,)
    # train size:(343,) test size:(147,)
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3,random_state=123)

    regs = LinearRegression()
    regs.fit_normal(x_train, y_train)

    # calc error
    score=regs.score(x_test,y_test)
    rmse=root_mean_squared_error(y_test,regs.predict(x_test))

    print('R squared error:%.2f' % (score))
    print('Root mean squared error:%.2f' % (rmse))


输出结果:

R squared error:0.79
Root mean squared error:3.36

1.3 使用梯度下降求解多元线性回归

使用梯度下降的方法,在数据比较多的情况下会比方程解快很多。代码也不难,只是关于参数梯度的向量化推导有一点复杂,还有就是训练前要先进行数据标准化。
损失函数与之前相同,还是使用MSE损失。

线性回归python实现详解(附公式推导)
线性回归python实现详解(附公式推导)
线性回归python实现详解(附公式推导)
线性回归python实现详解(附公式推导)

为了让梯度为列向量,再做依次转置,得到最终的结果。文章来源地址https://www.toymoban.com/news/detail-410123.html

线性回归python实现详解(附公式推导)
import numpy as np
from math import sqrt
import sklearn.datasets as datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

def accuracy_score(y_true, y_predict):
    """计算y_true和y_predict之间的准确率"""
    assert len(y_true) == len(y_predict), \
        "the size of y_true must be equal to the size of y_predict"

    return np.sum(y_true == y_predict) / len(y_true)


def mean_squared_error(y_true, y_predict):
    """计算y_true和y_predict之间的MSE"""
    assert len(y_true) == len(y_predict), \
        "the size of y_true must be equal to the size of y_predict"

    return np.sum((y_true - y_predict)**2) / len(y_true)


def root_mean_squared_error(y_true, y_predict):
    """计算y_true和y_predict之间的RMSE"""

    return sqrt(mean_squared_error(y_true, y_predict))


def mean_absolute_error(y_true, y_predict):
    """计算y_true和y_predict之间的MAE"""
    assert len(y_true) == len(y_predict), \
        "the size of y_true must be equal to the size of y_predict"

    return np.sum(np.absolute(y_true - y_predict)) / len(y_true)


def r2_score(y_true, y_predict):
    """计算y_true和y_predict之间的R Square"""

    return 1 - mean_squared_error(y_true, y_predict)/np.var(y_true)


class LinearRegression:

    def __init__(self):
        """初始化Linear Regression模型"""
        self.coef_ = None
        self.intercept_ = None
        self._theta = None

    def fit_normal(self, X_train, y_train):
        """根据训练数据集X_train, y_train训练Linear Regression模型"""
        assert X_train.shape[0] == y_train.shape[0], \
            "the size of X_train must be equal to the size of y_train"

        X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
        self._theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train)

        self.intercept_ = self._theta[0]
        self.coef_ = self._theta[1:]

        return self

    def fit_gd(self, X_train, y_train, eta=0.01, n_iters=1e4):
        """根据训练数据集X_train, y_train, 使用梯度下降法训练Linear Regression模型"""
        assert X_train.shape[0] == y_train.shape[0], \
            "the size of X_train must be equal to the size of y_train"

        def J(theta, X_b, y):
            try:
                return np.sum((y - X_b.dot(theta)) ** 2) / len(y)
            except:
                return float('inf')
            
        def dJ(theta, X_b, y):
            return X_b.T.dot(X_b.dot(theta) - y) * 2. / len(y)

        def gradient_descent(X_b, y, initial_theta, eta, n_iters=1e4, epsilon=1e-8):

            theta = initial_theta
            cur_iter = 0

            while cur_iter < n_iters:
                gradient = dJ(theta, X_b, y)
                last_theta = theta
                theta = theta - eta * gradient
                if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon):
                    break

                cur_iter += 1

            return theta

        X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
        initial_theta = np.zeros(X_b.shape[1])
        self._theta = gradient_descent(X_b, y_train, initial_theta, eta, n_iters)

        self.intercept_ = self._theta[0]
        self.coef_ = self._theta[1:]

        return self

    def predict(self, X_predict):
        """给定待预测数据集X_predict,返回表示X_predict的结果向量"""
        assert self.intercept_ is not None and self.coef_ is not None, \
            "must fit before predict!"
        assert X_predict.shape[1] == len(self.coef_), \
            "the feature number of X_predict must be equal to X_train"

        X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
        return X_b.dot(self._theta)

    def score(self, X_test, y_test):
        """根据测试数据集 X_test 和 y_test 确定当前模型的准确度"""

        y_predict = self.predict(X_test)
        return r2_score(y_test, y_predict)

    def __repr__(self):
        return "LinearRegression()"

if __name__ == '__main__':
    # use boston house price dataset
    boston_data = datasets.load_boston()
    x = boston_data['data']  # total x size (506,)
    y = boston_data['target']  # total y size (506,)
    # keep data with target value less than 50.
    x = x[y < 50]  # total x size (490,)
    y = y[y < 50]  # total x size (490,)

    # notice! need data normalize
    scaler=StandardScaler().fit(x)
    x=scaler.transform(x)

    # train size:(343,) test size:(147,)
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=123)

    regs = LinearRegression()
    regs.fit_gd(x_train, y_train)

    # calc error
    score = regs.score(x_test, y_test)
    rmse = root_mean_squared_error(y_test, regs.predict(x_test))

    print('R squared error:%.2f' % (score))
    print('Root mean squared error:%.2f' % (rmse))

    print('coeffient:', regs.coef_.shape)
    print('interception:', regs.intercept_.shape)

1.4 sklearn中的线性回归模型

import sklearn.datasets as datasets
from sklearn.linear_model import LinearRegression
import numpy as np
from sklearn.model_selection import train_test_split
from math import sqrt
np.random.seed(123)

def mean_squared_error(y_true, y_predict):
    """计算y_true和y_predict之间的MSE"""
    assert len(y_true) == len(y_predict), \
        "the size of y_true must be equal to the size of y_predict"

    return np.sum((y_true - y_predict)**2) / len(y_true)

def root_mean_squared_error(y_true, y_predict):
    """计算y_true和y_predict之间的RMSE"""
    return sqrt(mean_squared_error(y_true, y_predict))

if __name__ == '__main__':
    # use boston house price dataset
    boston_data = datasets.load_boston()
    x = boston_data['data']  # total x size (506,)
    y = boston_data['target']  # total y size (506,)
    # keep data with target value less than 50.
    x = x[y < 50]  # total x size (490,)
    y = y[y < 50]  # total x size (490,)
    # train size:(343,) test size:(147,)
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=123)

    regs = LinearRegression()
    regs.fit(x_train, y_train)

    # calc error
    score = regs.score(x_test, y_test)
    rmse = root_mean_squared_error(y_test, regs.predict(x_test))

    print('R squared error:%.2f' % (score))
    print('Root mean squared error:%.2f' % (rmse))

    print('coeffient:',regs.coef_.shape)
    print('interception:',regs.intercept_.shape)
R squared error:0.79
Root mean squared error:3.36
coeffient: (13,)
interception: ()

到了这里,关于线性回归python实现详解(附公式推导)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 标准高斯过程回归(Gaussian Processes Regression, GPR)从零开始,公式推导

    一、什么是高斯过程回归,他是用来干什么的 高斯过程回归是一种监督学习方法,我们可以将回归理解为拟合,比如:线性拟合,就是将一些数据拟合成一条直线。那么 高斯过程回归就是将数据拟合成高斯过程,进而实现预测。 举个例子 :我们在同一地点从上午八点开始,

    2024年04月09日
    浏览(39)
  • PnP算法详解(超详细公式推导)

    博主缺粉丝希望大家能给个关注!!! PnP(Perspective-n-Point)是求解3D到2D点的对应方法。它描述了当知道n个3D空间点及其位置,如何估计相机的位姿。如果两张图像中的一张特征点3D位置已知,那么至少需要3个点对(以及至少一个额外验证点验证结果)就可以计算相机的运动。 P

    2024年02月03日
    浏览(39)
  • 利用python实现多元线性回归

    本文介绍了如何用python进行回归分析 直线回归分析是研究两变量(自变量和因变量)之间的依存关系及其关系的具体方程的形式。分析中所形成的这种关系式称为回归模型,其中以一条直线方程表明的两个变量的依存关系的模型叫一元线性回归模型。 一元线性回归模型研究

    2024年02月11日
    浏览(38)
  • Python-线性回归的sklearn实现

    hello大家好这里是小L😊, 这学期开启机器学习之旅。在这里想和大家一起学习一起进步。💪 这次笔记内容:学习线性回归的sklearn实现 线性回归最后要找的是一条直线 (1)代码 (2)求斜率(数学公式) sklearn.linear_model.LinearRegression ( ) 超参数 fit_ intercept:截距,是否计算该模型

    2024年02月07日
    浏览(38)
  • python机器学习(五)逻辑回归、决策边界、代价函数、梯度下降法实现线性和非线性逻辑回归

    线性回归所解决的问题是把数据集的特征传入到模型中,预测一个值使得误差最小,预测值无限接近于真实值。比如把房子的其他特征传入到模型中,预测出房价, 房价是一系列连续的数值,线性回归解决的是有监督的学习。有很多场景预测出来的结果不一定是连续的,我们

    2024年02月15日
    浏览(88)
  • 多元线性回归(OLS+稳健误)python代码实现

    多元线性回归主要适用于应变量和自变量具有较强的线性关系,且主要研究 因变量(被解释变量) 和 自变量(解释变量) 之间的 相关关系 ,从而达到解释或者预测的作用。而且一般用于处理 横截面数据 ,横截面数据一般为同一时间段的不同对象的数据,比如同一年中的

    2024年02月03日
    浏览(42)
  • AI-应试-机器学习公式推导与代码实现-预备

    (AI算法系列) 机器学习 背景 训练过程 应用场景 局限及挑战 未来 2.1机器学习 模型:要学习的决策函数或条件概率分布 策略:决定按什么标准选最优模型-》loss 分类:对数、交叉熵 回归:均方 算法:具体的优化求解算法:梯度下降、牛顿法、拟牛顿法 2.2 核心:从数据中最

    2024年02月03日
    浏览(52)
  • Python实现稳健线性回归模型(rlm算法)项目实战

    说明:这是一个机器学习实战项目(附带 数据+代码+文档+视频讲解 ),如需 数据+代码+文档+视频讲解 可以直接到文章最后获取。 稳健回归可以用在任何使用最小二乘回归的情况下。在拟合最小二乘回归时,我们可能会发现一些异常值或高杠杆数据点。已经确定这些数据点

    2024年01月22日
    浏览(53)
  • 【人工智能】简单线性回归模型介绍及python实现

    简单线性回归是人工智能和统计学中一个基本的预测技术,用于分析两个连续变量之间的线性关系。在简单线性回归中,我们试图找到一个线性方程来最好地描述这两个变量之间的关系。 变量 :简单线性回归涉及两个变量 - 自变量(independent variable)和因变量(dependent vari

    2024年01月17日
    浏览(56)
  • 【数学建模】多元线性回归(Python&Matlab代码实现)

    目录 1 概述 2 算例1 2.1 算例 2.2 Python代码实现  2.3 结果 3 算例2  3.1 算例 3.2 Python代码 3.3 结果 4 算例3 4.1 算例 4.2 Python代码 4.3 结果 5 算例4——Matlab代码实现 5.1 算例 5.2 Matlab代码实现 5.3 结果  6 写在最后 一元线性回归模型研究的是一个因变量与一个自变量之间呈直线趋势的

    2023年04月15日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包