数学建模——一些基本概念(线性回归)和相对应的python代码实现
- 首先分析一下我们需要什么:
- 我们需要解决什么数学问题?这个问题该用什么模型?
- 找到一个模型使用的区别准则。这是根据1来讲的,这句话的意思,是用于体现不同模型与实际未知模型有多少偏差的准则。
- 同时做出预测时也要有一个判定的准则(标准)。
- 关键是具体该怎么做?这上面三个问题对应了以下三个步骤:
- 按照一个或一些选出的模型类型对数据进行拟合
- 从一些已经拟合的类型中选取最适合的模型。
- 根据模型和另外搜集到的一些数据做出预测
- 几个问题:线性拟合,损失函数,最小二乘与最大似然估计
所以问一个问题:什么是线性拟合?
依我看来线性拟合就是:用搜集到的几组数据分别作为自变量与因变量与你认为正确的模型进行拟合,找到一个损失函数并算出模型函数式子的过程。
所以有有人会问什么是损失函数与模型函数?
损失函数说的直白点就是用于表示计算值与实际值可能的误差大小,一般是所有误差值绝对值之和或者是平方之和,分别称为LAD回归和OLS回归。一般情况下使用的是OLS,它的普适性更高。
模型函数则是最后的表达式他是关于自变量与因变量的表达式,理论上代入x就可以预测出y。
那怎么计算误差函数呢?有两个常用方法:最小二乘和最大似然估计。这两个都是纯《概率论与数理统计》知识。
具体概念推荐同济大学的MOOC课程和数学建模第三版:
最大似然估计:
最小二乘法:
https://blog.csdn.net/qq_41938259/article/details/94557712
代码在这:
# -*- coding: UTF-8 -*-
"""
此脚本用于比较LAD线性回归和OLS线性回归
"""
import statsmodels.api as sm
from sklearn import linear_model
from statsmodels.regression.quantile_regression import QuantReg
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
def generate_data():
"""
随机生成数据
"""
np.random.seed(4889)
# Python2和Python3的range并不兼容,所以使用list(range(10, 29))
x = np.array([10] + list(range(10, 29)))
error = np.round(np.random.randn(20), 2)
y = x + error
# 增加异常点
x = np.append(x, 29)
y = np.append(y, 29 * 10)
return pd.DataFrame({"x": x, "y": y})
def train_OLS(x, y):
"""
训练OLS线性回归模型,并返回模型预测值
"""
model = linear_model.LinearRegression()
model.fit(x, y)
re = model.predict(x)
return re
def train_LAD(x, y):
"""
训练LAD线性回归模型,并返回模型预测值
"""
X = sm.add_constant(x)
model = QuantReg(y, X)
model = model.fit(q=0.5)
re = model.predict(X)
return re
def visualize_model(x, y, ols, lad):
"""
模型结果可视化
"""
# 创建一个图形框
fig = plt.figure(figsize=(6, 6), dpi=80)
# 在图形框里只画一幅图
ax = fig.add_subplot(111)
# 设置坐标轴
ax.set_xlabel("$x$")
ax.set_xticks(range(10, 31, 5))
ax.set_ylabel("$y$")
# 画点图,点的颜色为蓝色,半透明
ax.scatter(x, y, color="b", alpha=0.4)
# 将模型结果可视化出来
# 用红色虚线表示OLS线性回归模型的结果
ax.plot(x, ols, 'r--', label="OLS")
# 用黑色实线表示LAD线性回归模型的结果
ax.plot(x, lad, 'k', label="LAD")
plt.legend(shadow=True)
# 展示上面所画的图片。图片将阻断程序的运行,直至所有的图片被关闭
# 在Python shell里面,可以设置参数"block=False",使阻断失效
plt.show()
def OLS_vs_LAD(data):
"""
比较OLS模型和LAD模型的差异
"""
features = ["x"]
label = ["y"]
ols = train_OLS(data[features], data[label])
lad = train_LAD(data[features], data[label])
visualize_model(data[features], data[label], ols, lad)
if __name__ == "__main__":
data = generate_data()
OLS_vs_LAD(data)
END