刚拿到家庭用电数据集时,我第一反应是这看起来就是个普通的CSV文件,但深入分析后发现其中藏着不少门道。这份数据记录了法国某家庭两年内每分钟的用电情况,包含9个关键字段,从日期时间到各种功率指标一应俱全。最让我意外的是,原始数据量竟然超过200万条记录,处理起来相当考验耐心和技巧。
数据预处理阶段我踩过不少坑。比如最初直接用pandas的read_csv加载数据时,发现内存直接爆了。后来改用chunksize分块读取才解决问题。缺失值处理也是个技术活,我试过均值填充、中位数填充,最后发现对于时序数据,滑动窗口填充效果最好。具体做法是取前后5个时间点的均值来填补缺失值,这样能保留数据的时间连续性。
python复制# 滑动窗口填充示例代码
def sliding_window_fill(series, window_size=5):
filled = series.copy()
for i in range(len(series)):
if pd.isna(series[i]):
start = max(0, i-window_size)
end = min(len(series), i+window_size+1)
filled[i] = series[start:end].mean()
return filled
数据可视化环节更是让我大开眼界。直接绘制原始数据就像一团乱麻,根本看不出规律。后来我尝试按小时、按天做聚合,才逐渐看清用电模式的周期性特征。特别是用seaborn绘制热力图时,发现有功功率和电流强度相关性高达0.98,这个发现直接影响了后续的特征选择策略。
分析家庭用电数据最有趣的部分是发现隐藏在数字背后的生活规律。我把一天划分为白天(8:00-18:00)和夜晚两个时段,发现厨房用电(Sub_metering_1)在工作日早晚各有一个高峰,明显对应早餐和晚餐时间。而周末这个模式就完全打乱了,高峰时段更加分散。
工作日和节假日的用电对比更是个宝藏。通过pandas的resample功能,我发现了几个关键规律:
python复制# 时段分析代码示例
def analyze_time_pattern(df):
df['hour'] = df['Time'].str[:2].astype(int)
df['is_weekday'] = df['Date'].dt.weekday < 5
df['is_holiday'] = df['Date'].isin(holiday_dates) # 需要预先定义节假日
# 按小时和日期类型分组统计
hourly_stats = df.groupby(['hour','is_weekday'])['Global_active_power'].mean()
return hourly_stats.unstack()
电压数据的分析结果特别有意思。与其他指标不同,电压在全天各个时段都保持稳定,标准差不到3伏特。这说明供电质量相当可靠,也提示我们在建模时可以考虑将电压作为基准特征。
面对这样的多变量时序预测问题,我首先排除了传统的ARIMA模型。不是它不好,而是当你有7个相互关联的特征时,ARIMA处理起来太吃力了。经过对比测试,我最终选择了XGBoost和LSTM两种主流方案。
XGBoost的实现相对简单,但有几个关键点需要注意:
python复制# XGBoost时序预测实现
def train_xgb(X_train, y_train):
params = {
'max_depth': 5,
'learning_rate': 0.1,
'n_estimators': 500,
'objective': 'reg:squarederror',
'early_stopping_rounds': 50
}
model = xgb.XGBRegressor(**params)
model.fit(X_train, y_train,
eval_set=[(X_test, y_test)],
verbose=10)
return model
LSTM模型虽然计算成本高,但在捕捉长期依赖关系上表现更好。我的最佳实践是先用CNN层提取局部特征,再用LSTM层处理时序关系。训练时batch_size设置很关键,太小会导致训练不稳定,太大会影响模型灵活性。经过多次实验,我发现64是个不错的折中选择。
模型调优是个需要耐心的过程。我记录了完整的调参经验,分享几个最有价值的发现:
首先是特征重要性分析。通过XGBoost内置的特征重要性评估,发现Global_intensity对预测结果影响最大,这与之前热力图分析的结果一致。但出乎意料的是,Sub_metering_2的重要性比预期低很多,后来发现是因为洗衣房设备使用频率较低。
超参数优化我比较了三种方法:
python复制# 贝叶斯优化示例
from skopt import BayesSearchCV
opt = BayesSearchCV(
xgb.XGBRegressor(),
{
'max_depth': (3, 10),
'learning_rate': (0.01, 0.3),
'n_estimators': (100, 500)
},
n_iter=32,
cv=5
)
opt.fit(X_train, y_train)
模型融合也带来了显著提升。简单加权平均XGBoost和LSTM的预测结果,RMSE指标改善了约15%。更复杂的stacking方法效果更好,但实现复杂度也成倍增加。
最后是业务层面的优化。通过聚类分析发现,这户家庭的用电模式可以清晰分为4类:工作日白天、工作日夜晚、周末白天和周末夜晚。针对不同模式分别建模后,预测准确率又提升了8%左右。
做完这个项目后,我总结了几个关键经验。首先是数据质量决定上限,在数据清洗阶段多花时间绝对值得。特别是对于这种长时间跨度的时间序列,要特别注意节假日等特殊日期的处理。
其次是模型选择要结合实际需求。如果追求部署便捷性,XGBoost是更好的选择;如果需要最高精度,LSTM更胜一筹。在实际项目中,我最终选择了XGBoost,因为它的训练速度比LSTM快20倍,精度差距却在可接受范围内。
硬件配置也是个容易被忽视的因素。训练LSTM模型时,我最初用的笔记本跑一个epoch要30分钟,后来换成带GPU的云服务器,时间缩短到3分钟。这提醒我们,在项目规划时就要考虑计算资源需求。
最后是模型监控的重要性。上线后持续跟踪预测效果发现,夏季预测误差明显增大。分析后发现是因为原始数据缺少极端高温天气的样本。这个教训告诉我,时序预测模型需要定期用新数据重新训练。