python手写线性回归

线性模型

概念:试图学得一个通过属性的线性组合来进行预测的函数

形式:f(\boldsymbol{x})=\boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}+b

可解释性:

性能度量

常用性能度量均方误差:

\left(w^{*}, b^{*}\right)=\underset{(w, b)}{\arg \min } \sum_{i=1}^{m}\left(f\left(x_{i}\right)-y_{i}\right)^{2}

最小二乘法

基于均方误差最小化进行模型求解的方法

求解w和b使均方误差最小化的过程称为线性回归模型的最小二乘参数估计(parameter eatimation)

基于最小二乘法求解一元线性回归

对w求导

\frac{\partial E_{(w, b)}}{\partial w}=2\left(w \sum_{i=1}^{m} x_{i}^{2}-\sum_{i=1}^{m}\left(y_{i}-b\right) x_{i}\right)

对b求导

\frac{\partial E_{(w, b)}}{\partial b}=2\left(m b-\sum_{i=1}^{m}\left(y_{i}-w x_{i}\right)\right)

令导数等于0,解w和b

w=\frac{\sum_{i=1}^{m} y_{i}\left(x_{i}-\bar{x}\right)}{\sum_{i=1}^{m} x_{i}^{2}-\frac{1}{m}\left(\sum_{i=1}^{m} x_{i}\right)^{2}}b=\frac{1}{m} \sum_{i=1}^{m}\left(y_{i}-w x_{i}\right)

python实现

示例数据

中国平安和沪深300指数的日收益率数据,使用中国平安收益率作为特征收入,沪深300作为标准输出

Date 沪深300 中国平安
2015/6/23 0.03214 0.0496
2015/6/24 0.01965 0.0052

最小二乘法求解w和b

def least_square(feature, label):
    """
    最小二乘法求解一元线性回归
    :param feature: 特征,m行1列
    :param label: 标注,m行1列
    :return:
    """
    m = np.shape(feature)[0]
    sp1 = 0
    sp2 = 0
    sp3 = (np.sum(feature, 0) ** 2) / m
    avg_x = float(np.mean(feature, 0))
    for index in range(len(feature)):
        sp1 += label[index] * (feature[index] - avg_x)
        sp2 += feature[index] ** 2
    w = sp1 / (sp2 - sp3)
    b = sum([label[i] - w * feature[i] for i in range(len(feature))]) / m
    return w, b

输入数据处理

def load_data(file_path):
    """
    加载数据,并转换成特征和标记矩阵
    :param file_path: 
    :return: 
    """
    data = pd.read_csv(file_path)
    feature = data[u'中国平安']
    label = data[u'沪深300']
    return np.mat(feature.values.tolist()).T, np.mat([label.values.tolist()]).T

主函数和输出结果

if __name__ == '__main__':
    feature, label = load_data('data/data.csv')
    w, b = least_square_one(feature, label)
    print(float(w), float(b))
    plt.figure(figsize=(10, 6))
    x = feature.T.tolist()[0]
    y = label.T.tolist()[0]
    plt.plot(x, y, 'o')
    plt.plot(x, [i * float(w) + float(b) for i in x], 'r--')
    plt.show()

解得:w=0.7125595486627018 b=-0.0008229618070458702

则线性方程 y=0.7125595486627018x-0.0008229618070458702

基于最小二乘法求解多元线性回归

f(\boldsymbol{x})=\boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}+b,使b看成x0*b,且x0恒等于1

矩阵形式输入可以表示成\mathbf{X}=\left(\begin{array}{ccccc} 1&x_{11} & x_{12} & \ldots & x_{1 d} \\ 1 &x_{21} & x_{22} & \ldots & x_{2 d} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 1& x_{m 1} & x_{m 2} & \ldots & x_{m d} \end{array}\right),求解w转换成\hat{\boldsymbol{w}}^{*}=\underset{\hat{\boldsymbol{w}}}{\arg \min }(\boldsymbol{y}-\mathbf{X} \hat{\boldsymbol{w}})^{\mathrm{T}}(\boldsymbol{y}-\mathbf{X} \hat{\boldsymbol{w}})

对w求导\frac{\partial E_{\hat{w}}}{\partial \hat{w}}=2 \mathbf{X}^{\mathrm{T}}(\mathbf{X} \hat{\boldsymbol{w}}-\boldsymbol{y}),使导入等于0解\hat{\boldsymbol{w}}^{*}=\left(\mathbf{X}^{\mathrm{T}} \mathbf{X}\right)^{-1} \mathbf{X}^{\mathrm{T}} \boldsymbol{y}

python实现

还是相同的示例数据,则最小二乘求解可以写成

def least_square(feature,label):
    """
    小二乘法求解多元线性回归
    :param feature: 
    :param label: 
    :return: 
    """
    w = (feature.T * feature).I * feature.T *label
    return w

加载输入数据改写成

def load_data(file_path):
    """
       加载数据,并转换成特征和标记矩阵
       :param file_path:
       :return:
       """
    data = pd.read_csv(file_path)
    feature = data[u'中国平安']
    label = data[u'沪深300']
    feature = np.mat([np.ones((1, feature.shape[0])).tolist()[0], feature.values.tolist()]).T
    label = np.mat([label.values.tolist()]).T
    return feature, label

主函数和输出结果

if __name__ == '__main__':
    feature, label = load_data('data/data.csv')
    weight = least_square(feature, label)
    print(weight)
    plt.figure(figsize=(10, 6))
    x = feature.T.tolist()[1]
    y = label.T.tolist()[0]
    plt.plot(x, y, 'o')
    plt.plot(x, [float(i * weight) for i in feature], 'r--')
    plt.show()

解得w=[[-0.00082296],[ 0.71255955]]

可以理解成线性方程y=0.712559548662701x-0.000822961807045868

使用statsmodels进行回归分析

statsmodels是一个包含统计模型、统计测试和统计数据挖掘python模块。对每一个模型都会生成一个对应的统计结果。统计结果会和现有的统计包进行对比来保证其正确性。

特点

  • 线性回归模型:
    • 普通最小二乘法
    • 广义最小二乘法
    • 加权最小二乘法
    • 具有自回归误差的最小二乘法
    • 分位数回归
    • 递归最小二乘法
  • 具有混合效应和方差成分的混合线性模型
  • GLM:支持所有一参数指数族分布的广义线性模型
  • 用于二项式和泊松的贝叶斯混合GLM
  • GEE:单向聚类或纵向数据的广义估计方程
  • 离散模型:
    • Logit和Probit
    • 多项式logit(MNLogit)
    • 泊松和广义泊松回归
    • 负二项式回归
    • 零充气计数模型
  • RLM:鲁棒的线性模型,支持多个M估计量。
  • 时间序列分析:时间序列分析模型
    • 完整的StateSpace建模框架
      • 季节性ARIMA和ARIMAX模型
      • VARMA和VARMAX模型
      • 动态因子模型
      • 未观察到的组件模型
    • 马尔可夫切换模型(MSAR),也称为隐马尔可夫模型(HMM)
    • 单变量时间序列分析:AR,ARIMA
    • 向量自回归模型,VAR和结构VAR
    • 矢量纠错模型,VECM
    • 指数平滑,Holt-Winters
    • 时间序列的假设检验:单位根,协整和其他
    • 用于时间序列分析的描述性统计数据和过程模型
  • 生存分析:
    • 比例风险回归(Cox模型)
    • 幸存者功能估计(Kaplan-Meier)
    • 累积入射函数估计
  • 多变量:
    • 缺少数据的主成分分析
    • 旋转因素分析
    • MANOVA
    • 典型相关
  • 非参数统计量:单变量和多变量内核密度估计量
  • 数据集:用于示例和测试的数据集
  • 统计:广泛的统计测试
    • 诊断和规格测试
    • 拟合优度和正态性检验
    • 多重测试功能
    • 各种其他统计检验
  • 使用MICE进行插补,阶数统计量回归和高斯插补
  • 调解分析
  • 图形包括用于视觉分析数据和模型结果的绘图功能
  • 输入输出
    • 用于读取Stata .dta文件的工具,但pandas具有较新的版本
    • 表输出到ascii,latex和html
  • 杂项模型
  • Sandbox:statsmodels包含一个沙箱文件夹,其中包含处于开发和测试各个阶段的代码,因此不被视为“生产就绪”。其中包括
    • 广义矩估计(GMM)估计器
    • 内核回归
    • scipy.stats.distributions的各种扩展
    • 面板数据模型
    • 信息理论测度

python代码

import pandas as pd
import matplotlib.pyplot as plt
import datetime as dt
import statsmodels.api as sm
plt.rcParams['font.sans-serif']=['SimHei']  #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False
data = pd.read_csv('data/data.csv', index_col='Date')
data.index = [dt.datetime.strptime(x, '%Y-%m-%d') for x in data.index]
x = data['中国平安'].values
X = sm.add_constant(x)  #添加常数项
y = data['沪深300'].values
model = sm.OLS(y, X)
results = model.fit()
results.params
plt.figure(figsize=(10, 6))
plt.plot(x, y, 'o', label='中国平安-沪深300')
plt.plot(x, results.fittedvalues, 'r--', label='ordinary least square')
plt.legend()
plt.xlabel('中国平安')
plt.ylabel('沪深300')
plt.grid(True)
plt.show()

结果输出

猜你喜欢

转载自blog.csdn.net/weixin_41579863/article/details/106488647