一个强大算法模型,广义线性模型 !!
- 2025-07-30 15:16:00
哈喽,大家好~
今儿和大家聊聊回归算法方面的广义线性模型。
首先,带大家回顾一下回归算法:
回归算法是一种预测数值的工具。比如:
预测房价 预测明天温度 预测一个产品卖多少钱
只要你的问题是“想预测一个具体的数值”,那多半就会用到回归算法。
最基础的回归算法是线性回归。
核心思想是:
用一个直线公式(比如 y = a * x + b
)来描述输入 x
和输出 y
的关系。
比如:你想根据「房子的面积」来预测「房子的价格」,假设你发现:面积越大,价格越高,而且是差不多成比例的,那就可以用直线来表达它们的关系。
广义线性模型
那什么是广义线性模型(Generalized Linear Model,GLM)?
可以这么理解:
普通线性回归,只能解决“输入和输出之间关系是线性的,输出是连续数值”的问题。
但现实中的问题更复杂,比如:
输出可能是一个概率(比如预测某人得病的概率) 输出可能是一个整数(比如预测某地一天卖出多少个汉堡)
这时候,普通的线性回归就搞不定了。 所以我们就扩展它,变得“更通用”一些,这就是广义线性模型。
GLM 怎么“广义”了?
GLM 相比普通线性回归,多了两点:
不一定要求输出是连续数值(可以是整数、概率等) 使用一个“链接函数”(Link Function)来连接输入和输出
简单说就是:我们不直接让输入乘权重后输出结果,而是先经过一个“变换函数”,让它能适应不同类型的输出。
原理详解
数学原理
广义线性模型是一种统计建模方法,用来处理响应变量(因变量)分布不是正态分布的情况。
GLM 的数学模型包括以下三部分:
1. 随机成分(Random Component)
指响应变量 的概率分布。
在 GLM 中,要求 来自指数分布族(Exponential Family)。
2. 系统成分(Systematic Component)
解释变量(自变量)通过一个**线性预测函数(Linear Predictor)**组合起来:
其中:
:线性预测值(不是最终输出) :输入向量(特征) :待学习的权重向量
3. 链接函数(Link Function)
连接“线性预测值” 和“响应变量的期望值” :
这个函数 就是“链接函数”。
GLM 的形式就是:
指数分布族的定义(Exponential Family)
GLM 要求响应变量 的分布属于指数族分布,其一般形式如下:
其中:
:自然参数(natural parameter) :尺度参数(如标准差的平方) :规范函数(保证正则性) :与 和 相关的函数,但和 无关
常见的属于这个族的分布:
GLM 的极大似然估计推导(MLE)
GLM 是通过**极大似然估计(Maximum Likelihood Estimation, MLE)**来求解参数 。
1. 构造似然函数
给定 个独立样本 ,假设 ,那么联合似然为:
取对数,得到对数似然函数(便于优化):
注意: 通过链接函数间接由 决定,即:
,或 是 的函数
2. 求导:得一阶导数(梯度)
我们对对数似然函数 关于 求导,得到:
这个链式法则说明了每一步的变量依赖关系。
在实际求解中,一般使用**迭代加权最小二乘法(Iteratively Reweighted Least Squares,IRLS)**来逼近解。
完整案例
这里,咱们给出一个广义线性模型(GLM)在实际场景中的完整案例分析。
案例名:预测医疗保险费用
某医疗保险公司希望根据被保险人的个人信息(如年龄、性别、吸烟与否、BMI 等)来预测其年医疗保险费用。数据不满足普通线性模型的正态假设,因此使用**广义线性模型(GLM)**更合适。
导入数据
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# 设置中文字体与图像风格
plt.rcParams['font.sans-serif'] = ['SimHei']
sns.set_style('whitegrid')
sns.set_palette("Set1")
# 读取数据
df = pd.read_csv("https://raw.githubusercontent.com/stedy/Machine-Learning-with-R-datasets/master/insurance.csv")
数据预览与处理
print(df.head())
print(df.info())
# 将类别变量进行独热编码
df_encoded = pd.get_dummies(df, drop_first=True)
# 特征与目标分开
X = df_encoded.drop("charges", axis=1)
y = df_encoded["charges"]
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
数据标准化(提高稳定性)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
模型训练:使用 GLM + Gamma 分布 + 对数链接函数
医疗费用是正数且右偏,适合用伽马分布和对数链接函数。
X_train_const = sm.add_constant(X_train_scaled)
glm_gamma = sm.GLM(y_train, X_train_const, family=sm.families.Gamma(sm.families.links.log()))
result = glm_gamma.fit()
print(result.summary())
数据可视化分析
1. 不同性别医疗费用分布
plt.figure(figsize=(8, 5))
sns.boxplot(data=df, x="sex", y="charges", hue="smoker")
plt.title("Medical Charges by Sex and Smoking Status")
plt.ylabel("Charges")
plt.xlabel("Sex")
plt.show()

吸烟者明显比非吸烟者费用高 女性与男性差异不大,但吸烟行为是主因
2. 年龄 vs 医疗费用(回归曲线)
plt.figure(figsize=(10, 6))
sns.scatterplot(data=df, x="age", y="charges", hue="smoker", alpha=0.6)
sns.lineplot(data=df, x="age", y="charges", color="red", label="趋势线", linewidth=2)
plt.title("年龄 vs 医疗费用(含吸烟者标记)")
plt.xlabel("Age")
plt.ylabel("Charges")
plt.legend()
plt.show()

年龄与费用整体呈正相关 吸烟者的费用更高,呈指数上升
总的来说,广义线性模型(GLM)是一个结构清晰、理论扎实的回归工具,尤其适合需要考虑目标分布特征和模型可解释性的任务。虽然它在处理复杂非线性关系或极端精度追求上不如现代集成学习或深度学习算法,但在很多传统行业中仍然是首选建模方法。
最后



- 点赞 (0)
-
分享
微信扫一扫
-
加入群聊
扫码加入群聊