线性模型
概念:试图学得一个通过属性的线性组合来进行预测的函数
形式:
可解释性:
性能度量
常用性能度量均方误差:
最小二乘法
基于均方误差最小化进行模型求解的方法
求解w和b使均方误差最小化的过程称为线性回归模型的最小二乘参数估计(parameter eatimation)
基于最小二乘法求解一元线性回归
对w求导
对b求导
令导数等于0,解w和b
,
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
基于最小二乘法求解多元线性回归
由,使b看成x0*b,且x0恒等于1
矩阵形式输入可以表示成,求解w转换成
对w求导,使导入等于0解
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
- 时间序列的假设检验:单位根,协整和其他
- 用于时间序列分析的描述性统计数据和过程模型
- 完整的StateSpace建模框架
- 生存分析:
- 比例风险回归(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()
结果输出