实战保险花销预测:全流程解析
一、项目背景与目标
目标:基于保险数据(年龄、性别、BMI、子女数量、吸烟状态、地区等特征),预测个人的年度医疗保险费用。
数据集:insurance.csv
,包含1338条样本,目标变量为charges
(保险费用)。
二、技术流程
1. 数据提取与初探
import pandas as pd
# 读取数据
data = pd.read_csv('./data/insurance.csv')
print(data.head(6)) # 查看前6行数据
- 特征分析:数值型特征(
age
,bmi
,children
)与分类型特征(sex
,smoker
,region
),目标变量为charges
。
2. 数据探索(EDA)
import matplotlib.pyplot as plt
# 目标变量分布分析
plt.hist(data['charges'], bins=20)
plt.show()
# 对数变换调整右偏
import numpy as np
plt.hist(np.log(data['charges']), bins=20)
plt.show()
- 发现:
charges
呈现右偏分布,取对数后接近正态分布,符合线性回归对目标变量的假设。
3. 特征工程
# 独热编码处理分类变量
data = pd.get_dummies(data, columns=['sex', 'smoker', 'region'])
# 分割特征与标签
X = data.drop('charges', axis=1)
y = data['charges']
# 数据集分割
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
# 标准化处理
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler().fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 多项式特征扩展(degree=2)
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2, include_bias=False)
X_train_scaled = poly.fit_transform(X_train_scaled)
X_test_scaled = poly.transform(X_test_scaled)
- 关键操作:
- 独热编码:将分类型特征转换为数值型。
- 标准化:消除量纲差异,加速模型收敛。
- 多项式扩展:引入交互项与高次项,捕捉非线性关系。
4. 模型训练与评估
4.1 线性回归
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
reg = LinearRegression()
reg.fit(X_train_scaled, np.log1p(y_train)) # 对y取对数
# 预测与评估
y_pred = reg.predict(X_test_scaled)
rmse_test = np.sqrt(mean_squared_error(y_test, np.exp(y_pred)))
print(f"RMSE (Test): {rmse_test:.2f}") # 输出约5043.78
4.2 Ridge回归
from sklearn.linear_model import Ridge
ridge = Ridge(alpha=0.4)
ridge.fit(X_train_scaled, np.log1p(y_train))
y_pred_ridge = ridge.predict(X_test_scaled)
rmse_ridge = np.sqrt(mean_squared_error(y_test, np.exp(y_pred_ridge)))
print(f"Ridge RMSE (Test): {rmse_ridge:.2f}") # 输出约5043.95
4.3 梯度提升回归
from sklearn.ensemble import GradientBoostingRegressor
booster = GradientBoostingRegressor()
booster.fit(X_train_scaled, np.log1p(y_train))
y_pred_boost = booster.predict(X_test_scaled)
rmse_boost = np.sqrt(mean_squared_error(y_test, np.exp(y_pred_boost)))
print(f"GBoost RMSE (Test): {rmse_boost:.2f}") # 输出约4740.46
5. 结果对比与优化方向
模型 | 测试集RMSE | 特点 |
---|---|---|
线性回归 | 5043.78 | 简单,但易过拟合 |
Ridge回归 | 5043.95 | 通过正则化缓解过拟合 |
梯度提升回归 | 4740.46 | 捕捉非线性关系,效果最优 |
优化方向:
- 特征工程:
- 增加BMI分段(如过重、肥胖等级)
- 构造年龄与吸烟的交互项
- 模型调参:
- 梯度提升的
n_estimators
和learning_rate
调优 - 尝试其他模型(如XGBoost、随机森林)
- 梯度提升的
- 目标变量处理:
- 尝试Box-Cox变换替代对数变换
三、总结
本案例完整展示了从数据预处理到模型评估的机器学习流程。尽管梯度提升模型取得了相对较好的效果,但RMSE仍较高,说明数据中可能存在未被捕捉的非线性关系或重要特征。后续可通过更精细的特征工程和模型优化进一步提升预测精度。
完整代码与数据集:gitee仓库
实战建议:尝试增加“吸烟与BMI的交互作用”等特征,观察模型表现变化。