电力窃漏电用户自动识别实验学习笔记
**[ 《Python数据分析与挖掘实战》第六章案例代码总结与修改分析
](https://blog.csdn.net/fy_1852003327/article/details/10659265) **
一、实验目的
1.掌握拉格朗日插值算法进行缺失值处理的方法。
2.掌握LM神经网络和CART决策树构建分类模型的方法。
二、实验要求
1.利用拉格朗日插值算法补全数据用户的用电数据存在的缺失值。对拉格朗日插值法公式的理解,然后参考拉格朗日插值算法进行编程,将数据中的缺失值利用多项式函数对缺失值进行补充
2.构建分类模型对窃漏电用户进行识别,两模型为LM神经网络和CART决策树。通过建立模型研究窃漏电用户的行为特征,总结出窃漏电用户的特征指标,对比LM神经网络和CART决策树算法在窃漏电用户的识别效果,从中选取最优模型进行窃漏电诊断,从而了解数据挖掘的整个过程,并对其相应的算法熟练运用。
三、实验环境
Windows10系统
Pycharm软件
Python3.5.4
第三方库keras2.1.4、pandas0.25.3、Scikit-Learn0.22.2.post1
四、实验分析及思路
1.首先做题目需求分析
①我们需要对样本数据进行预处理,包括数据清洗、缺失值处理和数据变换。此处我们实验只说“缺失值处理”因为数据中存在缺失的想象,若将这些缺失值抛弃掉,会严重影响供出电量的计算结果,最终导致日线损率数据误差很大,为了达到较好的建模效果,需要对缺失值处理。插值方法有:拉格朗日插值法、牛顿插值法。拉格朗日插值法的最大毛病就是每次引入一个新的插值节点,基函数都要发生变化,这在一些实际生产环境中是不合适的,有时候会不断的有新的测量数据加入插值节点集,因此,通过寻找n个插值节点构造的的插值函数与n+1个插值节点构造的插值函数之间的关系,形成了牛顿插值法。由于能力有限,本次实验采用拉格朗日插值法对缺失值进行插补。
②构建专家样本完成后,需要划分测试样本和训练样本,随机选取20%作为测试样本,剩下的作为训练样本。窃漏电用户识别可通过构建分类预测模型来实现,比较常用的分类预测模型有LM神经网络和CART决策树,各个模型都有各自的优点,故采用这两种方法构建窃漏电用户识别,并从中选择最优的分类模型。构建LM神经网络和CART决策树模型时输人项包括电量趋势下降指标、线损类指标和告警类指标,输出项为窃漏电标识。使用LM神经网络和CART决策树实现分类预测模型,利用混淆矩阵和ROC曲线对模型进行评价
2.涉及到的数据
用户的用电数据存在缺失值的数据即为样本数据
专家样本即对所有窃漏电用户及正常用户的电量、告警及线损数据和该用户在当天是否窃漏电的标识,按窃漏电评价指标进行处理并选取其中291个样本数据
3.主要设计思路
(1)缺失值处理(拉格朗日插值法补值思路)
首先从原始数据集中确定因变量和自变量,取出缺失值前后5个数据(前后数据中遇到数据不存在或者为空的,直接将数据舍去,将仅有的数据组成一组),根据取出来的10个数据组成一组。然后采用拉格朗日多项式插值公式:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200601230505701.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
其中,x为缺失值对应的下标序号,Ln(x)为缺失值的插值结果,x为非缺失值y的下标序号。对全部缺失数据依次进行插补,直到不存在缺失值为止实验过程
(2)模型的构建及评价
①构建窃漏电用户识别模型,先对原始数据进行划分,分为训练数据和测试数据;再建立LM神经网络使用
Keras库为我们建立神经网络模型。设定LM神经网络的输入节点数为3,输出节点数为1,隐层节点数为10,使用Adam方法求解。对于激活函数,在隐藏层使用Relu(x)=max(x,0)作为激活函数,实验表明该激活函数能够大幅提高模型的准确率。根据训练样本建模的混淆矩阵可以算得分类准确率、正常用户被误判为窃漏电用户占正常用户的概率、窃漏电用户被误判为正常用户占正常窃漏电用户的概率;之后建立CART决策树通过Scikit-
Lean利用训练样本构建CART决策树模型,得到混淆矩阵可以算出分类准确率、正常用户被误判为窃漏电用户占正常用户的概率、窃漏电用户被误判为正常用户占正常窃漏电用户的概率。
②对构建的模型进行对比和评价。对于训练样本比较LM神经网络和CART决策树的分类准确率。评估模型分类的性能则利用测试样本对两个模型进行评价,采用ROC曲线评价方法进行评估,一个优秀分类器所对应的ROC曲线应该是尽量靠近左上角的。分别画出LM神经网络和CART决策树在测试样本下的ROC曲线,然后两图比较
五、实验结果及分析
1.拉格朗日插值法
代码:
#-*- coding: utf-8 -*-
#拉格朗日插值代码
import pandas as pd #导入数据分析库Pandas
from scipy.interpolate import lagrange #导入拉格朗日插值函数
inputfile = 'F:/大二下合集/Python数据分析与挖掘/missing_data.xls' #输入数据路径,需要使用Excel格式;
outputfile = 'F:/大二下合集/Python数据分析与挖掘/missing_data_processed.xls' #输出数据路径,需要使用Excel格式
data = pd.read_excel(inputfile, header=None) #读入数据
#自定义列向量插值函数
#s为列向量,n为被插值的位置,k为取前后的数据个数,默认为5
def ployinterp_column(s, n, k=5):
y = s.reindex(list(range(n - k, n)) + list(range(n + 1, n + 1 + k))) # 取数
y = y[y.notnull()] #剔除空值
return lagrange(y.index, list(y))(n) #插值并返回插值结果
#逐个元素判断是否需要插值
for i in data.columns:
for j in range(len(data)):
if (data[i].isnull())[j]: #如果为空即插值。
data[i][j] = ployinterp_column(data[i], j)
data.to_excel(outputfile, header=None, index=False) #输出结果
运行图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200601230554587.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
运行结果:(补全数据vs原数据)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200601230649728.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
2. 利用训练样本构建LM神经网络的混淆矩阵及绘制模型的ROC曲线
代码 :
#-*- coding: utf-8 -*-
#构建并测试CART决策树模型
import matplotlib.pyplot as plt
import pandas as pd #导入数据分析库
from random import shuffle #导入随机函数shuffle,用来打算数据
datafile = 'F:/大二下合集/Python数据分析与挖掘/model.xls' #数据名
data = pd.read_excel(datafile) #读取数据,数据的前三列是特征,第四列是标签
data = data.values #将表格转换为矩阵
shuffle(data) #随机打乱数据
p = 0.8 #设置训练数据比例
train = data[:int(len(data)*p),:] #前80%为训练集
test = data[int(len(data)*p):,:] #后20%为测试集
#构建CART决策树模型
from sklearn.tree import DecisionTreeClassifier #导入决策树模型
treefile = 'F:/大二下合集/Python数据分析与挖掘/tree.pkl' #模型输出名字
tree = DecisionTreeClassifier() #建立决策树模型
tree.fit(train[:,:3], train[:,3]) #训练
#保存模型
from sklearn.externals import joblib
joblib.dump(tree, treefile)
from cm_plot import * #导入自行编写的混淆矩阵可视化函数
cm_plot(train[:,3], tree.predict(train[:,:3])).show() #显示混淆矩阵可视化结果
#注意到Scikit-Learn使用predict方法直接给出预测结果。
from sklearn.metrics import roc_curve #导入ROC曲线函数
fpr, tpr, thresholds = roc_curve(test[:,3], tree.predict_proba(test[:,:3])[:,1], pos_label=1)
plt.plot(fpr, tpr, linewidth=2, label = 'ROC of CART', color = 'green') #作出ROC曲线
plt.xlabel('False Positive Rate') #坐标轴标签
plt.ylabel('True Positive Rate') #坐标轴标签
plt.ylim(0,1.05) #边界范围
plt.xlim(0,1.05) #边界范围
plt.legend(loc=4) #图例
plt.show() #显示作图结果
运行图及结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200602082858536.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020060208291551.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200602082954543.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
分类准确率为:(163+57)/(163+57+4+8)≈94.8%
正常用户被误判为窃漏电用户占正常用户的:8/(163+8)≈4.6%
窃漏电用户被误判为正常用户占正常用户的:4/(4+57)≈6.5%
3.利用训练样本构建CART决策树的混淆矩阵及绘制模型的ROC曲线
代码:
#-*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt
from random import shuffle
datafile = 'F:/大二下合集/Python数据分析与挖掘/model.xls'
data = pd.read_excel(datafile)
data = data.as_matrix()
shuffle(data)
p = 0.8 #设置训练数据比例
train = data[:int(len(data)*p),:]
test = data[int(len(data)*p):,:]
#构建LM神经网络模型
from keras.models import Sequential #导入神经网络初始化函数
from keras.layers.core import Dense, Activation #导入神经网络层函数、激活函数
netfile = 'F:/大二下合集/Python数据分析与挖掘/net.model' #构建的神经网络模型存储路径
net = Sequential() #建立神经网络
net.add(Dense(input_dim = 3, output_dim = 10)) #添加输入层(3节点)到隐藏层(10节点)的连接
net.add(Activation('relu')) #隐藏层使用relu激活函数
net.add(Dense(input_dim = 10, output_dim = 1)) #添加隐藏层(10节点)到输出层(1节点)的连接
net.add(Activation('sigmoid')) #输出层使用sigmoid激活函数
net.compile(loss = 'binary_crossentropy', optimizer = 'adam') #编译模型,使用adam方法求解
net.fit(train[:,:3], train[:,3], nb_epoch=1000, batch_size=1) #训练模型,循环1000次
net.save_weights(netfile) #保存模型
predict_result = net.predict_classes(train[:,:3]).reshape(len(train)) #预测结果变形
'''这里要提醒的是,keras用predict给出预测概率,predict_classes才是给出预测类别,而且两者的预测结果都是n x 1维数组,而不是通常的 1 x n'''
from cm_plot import * #导入自行编写的混淆矩阵可视化函数
cm_plot(train[:,3], predict_result).show() #显示混淆矩阵可视化结果
from sklearn.metrics import roc_curve #导入ROC曲线函数
predict_result = net.predict(test[:,:3]).reshape(len(test))
fpr, tpr, thresholds = roc_curve(test[:,3], predict_result, pos_label=1)
plt.plot(fpr, tpr, linewidth=2, label = 'ROC of LM') #作出ROC曲线
plt.xlabel('False Positive Rate') #坐标轴标签
plt.ylabel('True Positive Rate') #坐标轴标签
plt.ylim(0,1.05) #边界范围
plt.xlim(0,1.05) #边界范围
plt.legend(loc=4) #图例
plt.show() #显示作图结果
运行图及结果:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200602083017275.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200602083027268.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200602083046856.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
分类准确率为:(163+56)/(163+56+8+5)≈94.3%
正常用户被误判为窃漏电用户占正常用户的:5/(163+5)≈2.9%
窃漏电用户被误判为正常用户占正常用户的:8/(8+56)≈12.5%
4.模型评价
对于训练样本,LM神经网络和CART决策树的分类准确率相差不大,分别为94.8%和94.3%。为进一步评估模型分类的性能,故利用测试样本对两个模型进行评价,采用ROC曲线评价方法进行评估,一个优秀分类器所对应的ROC曲线应该是尽量靠近左上角的。
LM神经网络和CART决策树在测试样本下的ROC曲线,如下所示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200602083100206.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Z5XzE4NTIwMDMzMjc=,size_16,color_FFFFFF,t_70)
经过对比发现CART神经网络的ROC曲线比LM决策树的ROC曲线更加靠近单位方形的左上角,CART神经网络ROC曲线下的面积更大,说明CART神经网络模型的分类性能较好,能应用于窃漏电用户识别。