电力窃漏电用户自动识别的实验报告

电力窃漏电用户自动识别实验报告


提示

参考书:张良均《Python数据分析与挖掘实战》等。

数据文件:课本自带数据。

使用软件:Pycharm。

类别:实验。

关键字:拉格朗日插值法、CART决策树、KNN。

温馨提示:特别注意后面的各个易错点、疑难点,该实验是跟张良均这本书配合使用的,代码运行于Pycharm。


一、 实验目的

1、基于Python,了解分类算法的使用。

2、使用拉格朗日插值法进行缺失值处理的方法。

3、使用CART决策树分类模型和K近邻算法模型的方法。


二、 实验环境

1、操作系统:Windows10。

2、代码运行环境:Jupyternotebook或Pycharm。


三、 实验原理

1、Python开发平台的搭建。

2、Python使用入门。

3、Python数据分析工具。

4、K近邻算法和CART决策树


四、 实验步骤与实验结果

1、实验步骤要求:

<1> 对存在缺失值的用户用电数据表“miss_data.xls”,利用拉格朗日插值法补全数据。

<2> 对所有窃漏电用户及其正常用户的电量、告警及线损数据和该用户在当天是否窃漏电的标识,按窃漏电评价指标进行处理并选取其中291个样本数据,得到专家样本,数据文件为“model.xls”。

<3> 数据80%作为训练样本,剩下的20%作为测试样本。

<4> 对数据文件“model.xls”使用CART决策树实现分类预测模型,再利用混淆矩阵和ROC曲线对模型进行评价。

<5> 对数据文件“model.xls”使用K近邻算法实现分类预测模型,再利用混淆矩阵和ROC曲线对模型进行评价。

2、实验结果:

(1)第<1>小题的拉格朗日插值:

【1】温馨提示:

在这里插入图片描述

【2】代码:

# -*- coding:utf-8 -*-

# 拉格朗日插值代码
# 导入数据分析库Pandas
import pandas as pd
# 导入拉格朗日插值函数
from scipy.interpolate import lagrange

# 输入数据的路径,需要使用Excel格式
input_file = 'missing_data.xls'
# 输出数据的路径,需要使用Excel格式
output_file = 'missing_data_processed.xls'

# 读入数据
data = pd.read_excel(input_file, header=None)
# print(data)

# 自定义列向量插值函数
# col为列向量; pos为被插值的位置; num为取前后的数据个数,默认为5。
def column_interpolation(col, pos, num=5):
   
   '''使用这行代码:
   y = s[list(range(pos - num, pos + num + 1))] 或
   y = col[list(range(pos - num, pos)) + list(range(pos + 1, pos + num + 1))]
   会报错!
   原因: Series不支持反向索引,也就是类似于pd.Series[-1]
   第一个缺失值位于第三位 pos - num 出现负值,所以报错。
   第一种解决方案: y = col.reindex(list(range(pos - num, pos)) + list(range(pos + 1, pos + num + 1)))
   第二种解决方案: 忽略 pos - num < 0 的缺失值
   '''
   # (1)取数
   y = col.reindex(list(range(pos - num, pos)) + list(range(pos + 1, pos + num + 1)))
   # (2)剔除空值
   y = y[y.notnull()]
   # (3)插值并返回插值结果
   return lagrange(y.index, list(y))(pos)

# 逐个元素判断是否需要插值
for m in data.columns:
   for n in range(len(data)):
       if(data[m].isnull())[n]:
           # 如果为空值,则插值
           data[m][n] = column_interpolation(data[m], n)

# 输出结果
data.to_excel(output_file, header=None, index=False)

【3】运行结果:
在这里插入图片描述

(2)第<2~5>题的CART决策树模型:

【1】温馨提示:

在这里插入图片描述

【2】代码:

# -*- coding: utf-8 -*-
# 构建并测试CART决策树模型
# 导入数据分析库
import pandas as pd
# 导入随机函数shuffle,用来打算数据
from random import shuffle
import matplotlib.pyplot as plt

# 数据名
datafile = 'model.xls'
# 读取数据,数据的前三列是特征,第四列是标签
data = pd.read_excel(datafile)
# 将表格转换为矩阵
data = data.values
# 随机打乱数据
shuffle(data)
# 设置训练数据比例
p = 0.8
# 前80%为训练集
train = data[:int(len(data)*p), :]
# 后20%为测试集
test = data[int(len(data)*p):, :]


# 构建CART决策树模型
# 导入决策树模型
from sklearn.tree import DecisionTreeClassifier

# 模型输出名字
treefile = 'tree.pkl'
# 建立决策树模型
tree = DecisionTreeClassifier()
# 训练模型
tree.fit(train[:, :3], train[:, 3])
# 保存模型
# from sklearn.externals
import joblib
joblib.dump(tree, treefile)


# 导入自行编写的混淆矩阵可视化函数
def cm_plot(y, yp):  # 混淆矩阵可视化函数
    # 导入混淆矩阵函数
    from sklearn.metrics import confusion_matrix
    # 混淆矩阵
    cm = confusion_matrix(y, yp)

    # 导入作图库
    import matplotlib.pyplot as plt
    # 画混淆矩阵图,配色风格使用cm.Greens,更多风格请参考官网。
    plt.matshow(cm, cmap=plt.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')
    # x,y坐标轴标签
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    return plt

# 显示混淆矩阵可视化结果
cm_plot(train[:, 3], tree.predict(train[:, :3])).show()
# 注意到Scikit-Learn使用predict方法直接给出预测结果。


# 导入ROC曲线函数
from sklearn.metrics import roc_curve

fpr, tpr, thresholds = roc_curve(test[:, 3], tree.predict_proba(test[:, :3])[:, 1], pos_label=1)
# 作出ROC曲线
plt.plot(fpr, tpr, linewidth=2, label='ROC of CART', color='green')
# 坐标轴标签
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()

【3】运行结果:

在这里插入图片描述

在这里插入图片描述

(3)第<2~5>题的KNN模型:

【1】温馨提示:

在这里插入图片描述

【2】代码:

# -*- coding: utf-8 -*-

import pandas as pd
from random import shuffle
import matplotlib.pyplot as plt

data_file = 'model.xls'
data = pd.read_excel(data_file)
data = data.values
shuffle(data)
# 设置训练数据比例
p = 0.8
train = data[:int(len(data)*p), :]
test = data[int(len(data)*p):, :]


# 使用 KNN 算法
from sklearn import neighbors
# KNN 模型
knn = neighbors.KNeighborsClassifier()
# 训练模型
knn.fit(train[:, :3], train[:, 3])
# 模型输出名字
knn_file = 'Knn-demo.pkl'
# 保存模型
import joblib
joblib.dump(knn, knn_file)


# 导入自行编写的混淆矩阵可视化函数
def cm_plot(y, yp):  # 混淆矩阵可视化函数
    # 导入混淆矩阵函数
    from sklearn.metrics import confusion_matrix
    # 混淆矩阵
    cm = confusion_matrix(y, yp)

    # 导入作图库
    import matplotlib.pyplot as plt
    # 画混淆矩阵图,配色风格使用cm.Greens,更多风格请参考官网。
    plt.matshow(cm, cmap=plt.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')
    # x,y坐标轴标签
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    return plt

# 显示混淆矩阵可视化结果
cm_plot(train[:, 3], knn.predict(train[:, :3])).show()
# 注意到Scikit-Learn使用predict方法直接给出预测结果。


# 导入ROC曲线函数
from sklearn.metrics import roc_curve

fpr, tpr, thresholds = roc_curve(test[:, 3], knn.predict_proba(test[:, :3])[:, 1], pos_label=1)
# 作出ROC曲线
plt.plot(fpr, tpr, linewidth=2, label='ROC of KNN', color='green')
# 坐标轴标签
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()

【3】运行结果:

在这里插入图片描述

在这里插入图片描述

(4)第<2~5>题的CART决策树模型与KNN模型的比较分析:

【1】CART决策树模型与KNN模型在分类准确率以及用户误判方面的对比如下图所示:

在这里插入图片描述

结论:KNN模型的分类准确率略优于CART决策树模型,但相差不大。

【2】CART决策树模型的ROC曲线比KNN模型的ROC曲线的比较:
在这里插入图片描述
在这里插入图片描述

结论:CART决策树的ROC曲线比KNN更加靠近单位方形的左上角且CART决策树的ROC曲线下的面积更大,则CART决策树预测模型的分类性能更好,更适合应用于窃漏电用户自动识别当中。将处理后的数据作为模型输入数据,利用构建好的模型计算用户的窃漏电结果,并与实际调查结果做对比,对模型进行优化,可以进一步提高识别准确率。


五、疑难点

【1】注意:看清电力窃漏电用户自动识别实验的文件路径图,看清楚代码中的文件路径,数据文件跟代码文件都在同一目录下。

【2】实验代码1的疑难点1:

使用这行代码:    y = s[list(range(pos - num, pos + num + 1))] 或    
y = col[list(range(pos - num, pos)) + list(range(pos + 1, pos + num + 1))]    
会报错!Series不支持反向索引,也就是类似于pd.Series[-1]   

第一个缺失值位于第三位 pos - num 出现负值,所以报错。    
第一种解决方案: y = col.reindex(list(range(pos - num, pos)) + list(range(pos + 1, pos + num + 1)))    
第二种解决方案: 忽略 pos - num < 0 的缺失值

【3】实验代码2的疑难点1:

data_matrix = data.as_matrix() 已不支持,
实验中若是使用会出现
AttributeError: 'DataFrame' object has no attribute 'as_matrix'。
现在,大致被 data = data.values 替代。

【4】实验代码2的疑难点2:

# 实验过程中若是
from sklearn.externals import joblibjoblib.dump(tree, treefile)
会无法导入模块,就使用
import joblibjoblib.dump(tree, treefile)

【5】扩展知识点1:

data = pd.DataFrame(data_train)data_matrix = data.as_matrix()运行结果:dataframe输出的:Diabetes 8.123400 0.041000matrix输出的['Diabetes' 8.1234 0.040999999999999995]
问题:为什么 0.041000 会变成 0.040999999999999995 ?
解析:浮点数存在两种误差:
(1)一个是本身精度的误差。比如0.1,在10进制里是一个有限小数,用二进制表示,就是无限循环小数,但是浮点数只能存n位有限的尾数,那么浮点数的表示就有误差。误差又因为四则运算被扩大。一个极端的情况,对两个范围差别很大的不精确的浮点数做加减,那么比较小的那个数误差会变大。
(2)另一个是和10进制的转换误差,将2进制转换为10进制,尾数不能精确表示的,也会有误差。最后,浮点数在不同环境下,运算可能结果不同。比如说,采用传统的x87浮点处理器,内部保存80位,而sse指令只保存64位。这导致不同的设备计算的结果还可能不同。

【6】实验代码3的疑难点1:

使用 Pycharm 做实验过程中有警告:
UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect.self.figure.tight_layout()
是因为想要在matplotlib里面添加控件进行交互,结果报警告了(可忽略)。

【7】实验代码3的疑难点2:

# 画混淆矩阵图,配色风格使用cm.Greens,更多风格请参考官网。plt.matshow(cm, cmap=plt.cm.Greens)

猜你喜欢

转载自blog.csdn.net/xu_yushu/article/details/124552745
今日推荐