本项目的目标是通过电量异常数据,负荷异常数据,终端报警数据,主站报警,线损异常数据等信息,建立数据分析模型,来实时检测窃漏电情况或发现计量装置故障的作用。
主要任务是:归纳出窃漏电用户的关键特征,构建窃漏电用户的识别模型,利用实时监测数据,调用窃漏电用户识别模型实现实时诊断。
image.png1. 准备数据集
抽取某市近5年来所有的窃漏电用户有关数据和不同用电类型正常用电用户共208个用户的有关数据,同时包含每天是否由窃漏电情况的标识。
显然这是一个有监督的分类问题。
1.1 数据探索分析
本案例主要采用分布分析和周期性分析等方法对电量数据进行数据探索分析。
分布分析作图如下:
image.png
对正常用电用户的周期性分析如下:
image.png
窃漏电用户用电量的周期性分析为:
image.png根据正常用户和窃漏电用户的周期性分析对比结果可以发现:正常用户用电量保持基本稳定,而窃漏电用户用电量持续下降,故而可以根据这个特性来识别。
2. 数据预处理
包括由数据清洗,缺失值处理,数据变换等
数据清洗,此处发现非居民用电不可能存在窃漏电现象,故而将非居民用地那类别的用电数据过滤掉,同时,节假日和工作日相比会明显偏低,所以过滤掉节假日的用电数据。(话说,这样简化的太多了吧。)
本案例采用拉格朗日插值法对缺失值进行插补。
代码为:
#自定义列向量插值函数
#s为列向量,n为被插值的位置,k为取前后的数据个数,默认为5
def ployinterp_column(s, n, k=5):
y = s[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)
插值前后的对比结果为:
数据变换:原始的特征有时并不能非常好的表示类别之间的差异,所以有必要自己构建更具有特征意义的特征,这个也可以看成是特征工程。
本案例中,人为的建立了几种指标,比如电量趋势下降指标,线损指标,告警类指标来作为特征。
其中的电量趋势下降指标为:统计当天比前一天电量减少的天数之和,计算前后各5天,一共11天的情况。其意义在于:递减的天数越多,表明窃漏电的可能性越大。
线损指标用于衡量供电线路的损失比例,如果由用户发生窃漏电,那么当天的线损指标会上升,但考虑的是前后几天的线损率平均值。
告警类指标:与窃漏电相关的终端报警主要由电压缺相,电压断相,电流反极性等告警,计算这些告警的次数总和。
所以此处建立的数据集的特征就是这三个指标,标签为是否有窃漏电,这是一个标准的二分类问题。
如下为数据集的一部分:
image.png3. 构建模型
3.1 神经网络模型
from keras.models import Sequential #导入神经网络初始化函数
from keras.layers.core import Dense, Activation #导入神经网络层函数、激活函数
net = Sequential() #建立神经网络
net.add(Dense(10,activation='relu',input_shape=(3,))) # 此处有3个特征
net.add(Dense(1,activation='sigmoid')) #添加隐藏层(10节点)到输出层(1节点)的连接#输出层使用sigmoid激活函数
net.compile(loss = 'binary_crossentropy', optimizer = 'adam',metrics=['accuracy']) #编译模型,使用adam方法求解
net.fit(train.iloc[:,:-1], train.iloc[:,-1],
epochs=200, batch_size=10,
validation_data=(test.iloc[:,:-1],test.iloc[:,-1]))
image.png
image.png
image.png
由此可见,不管是train set还是val set,,都得到了0.9以上的准确率
3.2 Cart决策树模型
from sklearn.tree import DecisionTreeClassifier #导入决策树模型
tree = DecisionTreeClassifier() #建立决策树模型
tree.fit(train.iloc[:,:3],train.iloc[:,3]) #训练
cm = confusion_matrix(train.iloc[:,3], tree.predict(train.iloc[:,:3])) #混淆矩阵
plt.matshow(cm, cmap=plt.cm.Greens) #画混淆矩阵图,配色风格使用cm.Greens,更多风格请参考官网。
plt.colorbar() #颜色标签
for x in range(len(cm)): #数据标签
for y in range(len(cm)):
plt.annotate(cm[x,y], xy=(x, y), horizontalalignment='center', verticalalignment='center')
plt.ylabel('True label') #坐标轴标签
plt.xlabel('Predicted label') #坐标轴标签
from sklearn.metrics import roc_curve #导入ROC曲线函数
fpr, tpr, thresholds = roc_curve(test.iloc[:,3], tree.predict_proba(test.iloc[:,: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() #显示作图结果
image.png
image.png
参考资料:
《Python数据分析和挖掘实战》张良均等
网友评论