Data Fountain光伏发电量预测 Top1 开源分享

知乎第一篇文章,开源我们DataInsight团队的全部思路和python代码,主要分享给数据分析和竞赛初学者,(我去年6月开始学习用R分析数据,第一次和维克多老师学到了线性回归和R语言,积累了一年多其实也没会太多,然而要说比赛需要多高的代码能力,或者什么背景,都是瞎扯。。我原来就是个焊电路板的,机器学习的知识,大多都是问同学,网上找,凭兴趣学。)

从今年3月开始关注数据比赛和举办比赛的平台,知道了国际有名的Kaggle,国内的比较活跃的应该有阿里天池,Data Fountain,Data Castle,个人感觉参加比赛是学习数据分析很好的途径,简单的说,赢了拿奖金,输了攒经验。。

有了比赛这个想法后3月参加了一个天池的给出体检数据,预测高血压高血糖的比赛,万事开头难,花了7天才把数据整理成可以使用的状态,最后冲击复赛失败,排名152/3000被淘汰,现在看来很正常,因为前7天花在清洗数据,清理好了就急着跑模型,当时刚听说xgb lgb这类东西,别人写好的拿来就能用,真的舒服,而且在datacamp(不错的学习网站,推荐)学到了一招叫做模型融合,后面一个月全花在模型融合上了,因为跑一次融合要6-8个小时。。在当时看来,融合是最最牛逼的黑科技,可以超越一切的力量!现在看来,数据探索性分析,异常值判定和预处理,特征工程,模型,融合,可能没法说哪个更重要,只是投入产出比不同(融合属于投入多,提升少的)。想要超过别人,只用现成的东西可能不太够,说白了你会的网上都查得到,那么大家都知道,那么怎么搞!后面会写到,不盲目相信任何经验,只有叛逆和创新才会帮你。。

Data Fountain与国家电投这个系列赛,7-9月同时举办4个比赛,为什么要参加光伏发电预测这个比赛呢?因为这是数据集看起来最简单的比赛! 就一个csv文件,2M多点,9000条训练数据,8000条测试,对机器没啥要求,容易上手啊,快速出结果啊,马上出排名啊,刺激。

团队: DataInsight 最终排名: A, B榜第一,和三个队友们一起战斗是一生铭记的快乐时光。

目录:这个目录可以看做是相对完整的参加比赛的思路和流程


1 数据探索与数据预处理

  • 1.1 赛题回顾
  • 1.2 数据探索性分析与异常值处理
  • 1.3 相关性分析

2 特征工程

  • 2.1 光伏发电领域特征
  • 2.2 高阶环境特征

3 模型构建与调试

  • 3.1 预测模型整体结构
  • 3.2 LSTM模型
  • 3.3 模型融合与总结

4 参考文献

1 数据探索与数据预处理

1.1 赛题回顾

赛题目标很简单,给一组特征,预测瞬时发电量,训练集9000个点,测试集8000个,特征包含光伏板的属性和外部环境等,具体说明可以参考官网:

光伏电站人工智能运维大数据处理分析 - DF,CCF大数据竞赛平台


1.2 数据探索性分析与异常值处理

探索性分析个人理解可以首先做图,帮助自己了解一下数据,比如下图是训练集ID-发电量的散点图,可见发电量是有周期性的,因为一天中从早到晚,发电量随着光强变化。同时发现,一个周期即一天大概有200个ID,那么训练集9000条应该是45天左右的数据。

发电量的周期性

比如下图,是一些特征的散点图,可见异常值的存在。

几个特征的散点图

发现异常值接下来比较关键的是异常值的处理,包括异常值判定,即什么样的数值算是异常值,还有异常值处理,即如何处置异常值。

常用的异常值判定方法可以参考以下连接,我没学过统计,也没学会高等数学,不太懂其中原理,就不乱说了

有哪些比较好的做异常值检测的方法?

这个比赛里我们在判定异常值之前做了另外一组图:观察各个特征的分布

转换效率的分布
平均功率的分布

大多数特征符合正态分布的,或者两个峰的分布(可以看做是两个正态分布?)那么异常值的判定就用最基本的方法: 平均值 \pm 3*标准差之外的任何值,即为异常值。

那么接下来需要处理异常值:

由于这些测量点是有时序关系的,直接用上一个有效值代替异常值。

关于异常值、空缺值的处理,想多写一点点:
面对异常值/空缺值的情况,首先一定要判断这些值是怎么空缺的,比如完全随机的空缺 (比如设备临时没电,测不出值了,只好空缺)和有规律的空缺处理(比如做问卷时候,收入很高而且来源不正经的人可能会乱写、不写自己的收入)

完全随机空缺,删除改行的问题不大,甚至数据某一列空缺比例过高,直接删除也OK,但是如果是有规律的空缺,可能填补一下比较稳妥,比如用已有其他的值做个回归,听起来比较靠谱一些。基本上可以参考这个图来进行处理:

towardsdatascience.com/


对于异常值、空缺值的判断和处理有多重要呢?

分享个小事故,没有组队之前,我自己做这个题目大概第7天的时候,跑了个LightGBM,排名记得是60多,有一天早上发现了数据的周期性,随后只是按照上述的方法判定,填补了异常值,直接第一了,那时候是比赛初期,我的A榜成绩到了0.848(成绩算法:1/(1+RMSE))多,第二的队伍在0.845多,(参加的同学知道这是多么大的差距)导致我在接下来的一周都处于领先。。(并借此陆续招募了3位比我强很多的队友。。)当然其他队也会发现这一点,最后我们A榜成绩定格在0.8532,大家一点点把精确度逼向极限,也是比赛的乐趣吧。所以异常值的判断,处理得好,是可以对预测精确度有极大帮助的!但是对于不同的数据,究竟使用什么方法呢?我觉得最靠谱的是依据数据的规律,比如这里的周期性和分布特征,多尝试不同方法。根据线下成绩来定。

1.3 相关性分析

首先我们观察了各特征与发电量的皮尔森相关系数,结果记录在表1中,这可以在一定程度上判断特征对于预测的作用。

通过数据可视化,我们发现光照强度/40的曲线基本和发电量的曲线一致,平均功率除以480的曲线基本和发电量的曲线一致,如图。

也看看其他特征,相关度似乎不明显。

至于不明显相关的变量,后面会尝试各种组合和变换。到这里探索性分析就结束了。这一步还是很值得花时间的,投入产出比很高。对于数据越了解,后面构造特征的思路就越多,个人觉得比赛千万不能求快,略过探索性分析和可视化。



2 特征工程

特征工程就是想尽一些办法,发现和制造对于预测有帮助的特征。为什么要做特征工程?

"Applied machine learning" is basically feature engineering.

— Andrew Ng, Machine Learning and AI via Brain simulations[1]

这句话算是我们比赛的指导思想的一部分,虽然我们是带着一种挑战各种算法,不信任何经验,只看实际效果的叛逆精神在比赛,但是这句话是真的必须要信的。。。

说白了基本上特征决定了你模型能达到的准确度极限,模型只能帮你逼近这个极限。换句话说,没有好的特征组合,模型再强也是没用。

特征工程大概可以从两个方面入手:领域特征,多项式特征。领域特征就是寻找在问题专业领域内起作用的特征,乱说个例子,没有根据的,可能医学上,血液中钙和钾的含量不会直接影响你的某个指标,但是钙钾比例会影响,多项式特征就有点玄学了,通过选取一些已有特征,对他们进行加减乘除各种运算都可以,构造一些特征,只要能帮助你预测,就是好特征。

  • 2.1 光伏发电领域特征

领域特征是通过查阅文献、不断尝试得到的:

查阅文献就是可以搜索哪些因素可以显著影响发电量,拿来直接用上,有很多论文讨论影响发电量的因素的。那么为什么查阅文献后,还有“不断尝试”呢?你以为所有论文都那么稳妥那么靠谱吗?很多论文的很多结论,会帮你掉很多分哈哈哈。

举几个例子,有用的,可以加分的

  1. 距离周期内峰值的距离(dis2peak), 反应一个测量点在一天,也就是一个周期中的位置,考虑是,每天中差不多的时间,太阳,温度等状态都差不多,发电量也就相似。

2. 温差(板温-现场温度), 原有特征板温,现场温度看起来与发电量都没太大关系,但是做个差值,会发现温差与发电量强相关。(对比以下两图)

3. 电压A/转换效率=实际板面所受光照, 板面所受光照应该是直接影响发电量的,由于一天中日照角度的变化,数据提供的光照强度不能直接反应板面所受光照。通过查阅有关资料,转换效率计算方法为光伏板输出功率/日照功率, 其中光伏板输出功率我们用电压A代表,已知转换效率的情况下,电压A/转换效率可以表示板面实际光光照。

2.2 高阶环境特征

特种工程中一种思想是利用已有特征的组合,计算其高阶特征, 我们发现 '板温','现场温度','光照强度','风速','风向' 即环境因素的两两之间的2阶交互项可以提供较好的预测效果。

对于这个多项式特征,Python有个Poly feature可以使用,只要你选择几个特征,它直接帮你生成若干高阶特征,但是个人认为这里的特征选择很重要,没有根据的选择特征去生成高阶特征,是不可取的,容易引发维度灾难等情况,多次试验表明,这个题目,只有使用环境特征的2阶交互项,才是最优的,加上或者减去一个或者若干个,都不行。我觉得可能的解释是,光照会影响发电量,温度会影响发电量,而光照又影响温度,所以他们的交互项是有意义的,同理光照和风速,风向的交互也一样,互相影响,同时共同影响发电量。


原始特征有20个,特征工程后,我们有60多个特征。


3 模型构建与调试

这部分先给融合模型,对于初学的同学如果这部分看的不太理解,不了解这里面的单模型,很建议后面简单了解下XGBoost, LghtGBM, LSTM,DNN这些当前比较流行的一些预测器,都算是大家经常提到的比赛大杀器,其实一般的使用也就Python一句话的事,了解下输入输出是什么,如何调参就可以了,不需要知道太多细节。当然了解的多当然好,有时候修改底层代码可以让你单模型夺冠,比如阿里的某一个比赛中,第一的队伍是依靠修改了Xgboost的二阶导数让模型更快地收敛。所以学习的深度大家根据需求和时间自己确定。

3.1 预测模型整体结构

这是一个连续目标变量回归预测问题,很多模型都能有效的解决此类问题。但是,不同的模型原理和所得结果之间是存在差异的。在比赛中我们借鉴了Stacking的思想,融合了LightGBM、XGBoost以及LSTM三个模型。其中前两类可以看作是树模型,LSTM为神经网络模型。这两类模型原理相差较大,产生的结果相关性较低,融合有利于提高预测准确性。我们提出的具体的模型结构如图,说明如下:

这是一个我们想出来的四层的融合结构,第一层我们使用Xgboost_1对特征组合F1进行学习,得到Xgboost_1的预测结果(包括对于训练集和测试集的预测结果),该结果会作为新特征,加入特征组合F2,F3中,分别作为第二层LightGBM_1 和 LightGBM_2的输入特征,LightGBM_1的结果再次作为新特征,加入特征组合F4中,作为第三层Xgboost_2的输入特征,同时第三层包含一个LSTM模型,该模型使用特征组合F5训练,第二层LightGBM_2的结果则与第三层Xgboost_2,LSTM的预测结果进行加权融合作为最终结果。


3.2 基于LSTM的模型构建与调试

这个应该是我们获胜的一个关键点了,所以这里特殊说明。队长大佬一个人把LSTM提到了和我们三个人一起弄的树模型差不多的分数,再去融合,确实不容易。这也就是分工的好处,几个人的特征都不一样。

长短期记忆网络(Long Short-Term Memory, LSTM)是一种循环神经网络,能够处理一些由长时信息引起的问题。在本次比赛中,我们使用了一个包含200个单元的LSTM单层网络,结构如图。由于赛题的时序性质,LSTM效果很好。

LSTM结构
LSTM训练过程

3.3 模型融合与总结

在本问题中,一个严重的问题是过拟合,我们发现模型在训练样本中表现优越,但是在验证数据集以及测试数据集中表现不佳,在采取了特征,样本抽样进入训练,减少树深度和正则化参数后等常规方法后,我们发现和验证以下创新的方法可以提升融合后的模型表现。

1. 重复使用部分特征

在Light GBM模型中,我们对于环境特征(板温,现场温度,光照强度,风速,风向)执行了一次复制,即这些特征会在训练中出现两次,结果显示训练集误差几乎一致,但是线上线下验证集误差都更小,也就是说,使用重复特征,减少了过拟合的程度,使得模型的泛化,预测效果更佳。

对比加入重复特征的训练集与普通训练集的训练曲线,如图15,可见使用重复特征的模型验证误差小于不使用重复特征的模型,而两者的训练误差几乎相同的。

很多文献和实验表明特征选择时去除相关性高的特征是有利的,但是在本问题中我们发现重复特征虽然和已有特征的相关性很高,但是这种做法是可以提高预测准确度的,我们认为这有可能与单个树模型在抽样特征的时候,重复特征会有更大的机率被抽到有关,这限制了模型的学习能力。

关于这一点是否具有通用性,需要其他数据集的实验验证。

2.在每折交叉验证后进行预测

单模型的参数调整对于模型的表现有很大的影响,我们使用了网格搜索,交叉验证的方法,获得规定参数范围内最优的参数组合,在确定参数后,对于单模型再次在训练中使用交叉验证,一方面是可以对比不同模型的效果,一方面是我们在4折交叉验证中,每折训练结束后,都对测试集用本折交叉验证得到的模型进行一次预测。具体的说,比如对Xgboost模型,4折交叉验证,得到4个不同的“Xgboost模型”,用这4个模型分别对测试集做一次预测,最后Xgboost的预测结果是4次预测结果的平均值,这个过程可以看作是对于训练集合的一次抽样,Xgboost最终结果实际上是4个子模型结果的融合,抽样和融合可以减少过拟合,我们发现这样的处理对于本题目的预测精度有提高。

3.每个单模型所使用的特征都不同

每个单模型(包括LSTM),我们有90%的特征是一致的,还有大约10%特征是每个单模型独有的,通过这种方式增加模型间的差异性,摆脱对于单一特征组合的依赖,增加了模型的泛化能力,可以获得更好的融合效果。

现在各种平台的比赛,用单模型很难拿好成绩,传说Kaggle冠军曾用600多个模型融合才拿到第一,所以融合单模型是一个必然的趋势,想用融合的同学,Kaggle的融合导论可以研究看一看,包含各种比赛获胜的融合经验:

Kaggle Ensembling Guide

我们也是从中学习他人经验,同时既然是比赛,我们就想尝试用一点别人没用过的东西。



我们团队四个人是QQ群认识的,网络一线牵,我们全程不管是落后多少,始终在查找新的文献资料,始终在思考性的突破口。正是一次又一次的尝试,让我们的特征更加强效,模型更加完善,最终产出高分结果。

总结一下,有以下几个方面对于提高成绩很有帮助:

l 合理的数据预处理

我们观察到了数据中的异常点,并将训练数据和测试数据使用相同的方式进行异常值修复(前值填充)

l 高效的特征构造与选择

我们通过查阅光伏发电领域文献与资料,构造了如二极管节点流,计算转换效率等强有力的特征。

l 精心设计融合模型

基于LightGBM、XGBoost和LSTM三种模型而构造的融合模型,可以综合三种模型的互补优势,同时减小过拟合的影响。


参考文献

[1] 王坤. 考虑多重不确定性因素的光伏出力预测研究[D]. 华北电力大学, 2013.

[2] 王玉清. PN结反向饱和电流的实验研究[J]. 延安大学学报(自然科学版), 2010, 29(1):53-55.

[3] 吕学梅, 孙宗义, 曹张驰. "电池板温度及辐射量对光伏发电量影响的趋势面分析." 创新驱动发展 提高气象灾害防御能力——S6短期气候预测理论、方法与技术 2013:922-927.

[4] 窦砚林. 风力发电机风速、功率、功率曲线的分析[J]. 科学导报, 2014(z2)

[5] Hall M A. Correlation-based feature selection for machine learning[J]. 1999.

[6] colah.github.io/posts/2

[7] kaggle.com/willkoehrsen


最后引用决赛现场华北电力大学王老师的一句话:这个队,从一开始的宣传视频,就能看出很有激情。

发布于 2018-09-18