matlab电力企业的窃漏电用户自动识别
目录
一、数据预处理
1、缺失值处理(此处为拉格朗日插值)
主函数:Lagrange_interpolation.m
%% 拉格朗日插值算法
clear;
% 参数初始化
% 输入数据路径,需要使用Excel格式;
inputfile='..\data\missing_data.xls';
%输出数据路径,需要使用Excel格式
outputfile='..\tmp\missing_data_processed.xls';
%% 拉格朗日插值
% 读入文件
data=xlsread(inputfile);
[rows,cols]=size(data);
% 按照每列进行插值处理
% 其中ployinterp_column为自定义函数,针对列向量进行插值
for j=1:cols
data(:,j)=ployinterp_column(data(:,j));
end
%% 写入文件
xlswrite(outputfile,data);
被调用函数:ployinterp_column.m
function outputdata= ployinterp_column(columndata)
%% 针对每列进行插值
% 输入参数说明:
% columndata: 输入的列数据,含有缺失值
% 输出参数说明:
% output: 输出插值过的数据
%% 把输入列数据分为非缺失值和缺失值数据
nans = isnan(columndata); % 区分columndata中为NaN的数据下标
notzeroIndexes = find(nans); % 寻找缺失值下标
%zeroIndexes = find(nans==0); % 寻找非缺失值下标
rows=size(columndata); %原始数据的行数
%currentValues=zeros(size(zeroIndexes));% 初始化当前值矩阵
for i=1:size(notzeroIndexes)
pre5=findPre5(notzeroIndexes(i),columndata);
last5=findLast5(notzeroIndexes(i),rows(1),columndata);
[pre5rows,pre5cols]=size(pre5);
[last5rows,last5cols]=size(last5);
missingValue=polyinterp([1:pre5cols,pre5cols+2:last5cols+pre5cols+1],...
[pre5,last5],pre5cols+1); % 拉格朗日插值
columndata(notzeroIndexes(i),1)=missingValue;
end
% 返回插值后的数据
outputdata=columndata;
end
function pre5=findPre5(index,columndata)
%% 在columndata中寻找给定下标index前面5个数值(非NaN),不足5个的按实际情况返回
if index<=0
disp('非法下标');
exit;
end
num=5;
pre5=nan(1,5);
for i=index-1:-1:1
if isnan(columndata(i))==0 % 判断第i个值是否为NaN
pre5(num)=columndata(i);
num=num-1;
end
if num==0 % 只取前5个
break;
end
end
pre5=pre5(~isnan(pre5)); % 去除NaN的值
end
function last5=findLast5(index,rows,columndata)
%% 在columndata中寻找给定下标index后面5个数值(非NaN),不足5个的按实际情况返回
if index<=0 || index>rows
disp('非法下标');
exit;
end
num=0;
last5=nan(1,5); % 初始化
for i=index+1:rows
if isnan(columndata(i))==0 % 判断第i个值是否为NaN
num=num+1;
last5(num)=columndata(i);
end
if num==5 % 只取后5个
break;
end
end
last5=last5(~isnan(last5)); % 去除NaN的值
end
被调用函数:polyinterp.m
function v = polyinterp(x,y,u)
%% 拉格朗日插值算法
% x:下标序列;
% y: 时间序列值;
% u:缺失值下标序列;
n = length(x);
v = zeros(size(u));
for k = 1:n
w = ones(size(u));
for j = [1:k-1 k+1:n]
w = (u-x(j))./(x(k)-x(j)).*w;
end
v = v + w*y(k);
end
end
二、构建模型
1、数据集划分
主函数:split_data.m
%% 把数据分为两部分:训练数据、测试数据
clear;
% 参数初始化
datafile = '../data/model.xls'; % 数据文件
trainfile = '../tmp/train_model.xls' ; % 训练数据文件
testfile = '../tmp/test_model.xls' ; % 测试数据文件
proportion =0.8 ; % 设置训练数据比例
%% 数据分割
[num,txt]= xlsread(datafile);
% split2train_test 为自定义函数,把num变量数据(按行分布)分为两部分
% 其中训练数据集占比proportion
[train,test] = split2train_test(num,proportion);
%% 数据存储
xlswrite(trainfile,[txt;num2cell(train)]); % 写入训练数据
xlswrite(testfile,[txt;num2cell(test)]); % 写入测试数据
disp('数据分割完成!');
被调用函数:
function [train, test] = split2train_test( input,proportion )
%% 把输入数据随机分为训练和测试样本
% 输入参数:
% input : 原始矩阵,默认使用行作为一个样本
% proportion: 训练样本比重
% 输出参数:
% train:训练数据
% test:测试数据
rows=size(input,1);
%split=cvpartition(1:rows,'holdout',0.1);
split=randindex(rows,proportion);
train=input(split==0,:);
test=input(split==1,:);
end
function randindex=randindex(n,proportion)
%% 返回给定长度n,以及比例的数据下标
randindex=zeros(n,1);
rng('default'); % 固定随机化种子
for i=1:n
if rand(1)>proportion
randindex(i)=1;
end
end
end
2、构建LM神经网络模型
construct_lm_model.m
%% LM 神经网络模型构建
clear;
% 参数初始化
% 训练数据
trainfile = '..\data\train_model.xls';
% 构建的神经网络模型存储路径
netfile = '..\tmp\net.mat';
% 训练数据模型输出文件
trainoutputfile = '..\tmp\lm_train_output_data.xls' ;
%% 读取数据并转化
[data,txt] = xlsread(trainfile);
input=data(:,1:end-1);
targetoutput=data(:,end);
% 所有数据都加1,方便调用ind2vec
targetoutput = targetoutput+1;
% 输入数据变换
input=input';
targetoutput=targetoutput';
targetoutput=full(ind2vec(targetoutput));
%% 新建LM神经网络,并设置参数
net = patternnet(10,'trainlm');
net.trainParam.epochs=1000;
net.trainParam.show=25;
net.trainParam.showCommandLine=0;
net.trainParam.showWindow=0;
net.trainParam.goal=0;
net.trainParam.time=inf;
net.trainParam.min_grad=1e-6;
net.trainParam.max_fail=5;
net.performFcn='mse';
% 训练神经网络模型
net= train(net,input,targetoutput);
%% 使用训练好的神经网络测试原始数据
output = sim(net,input);
%% 画混淆矩阵图
plotconfusion(targetoutput,output);
%% 数据写入到文件
save(netfile,'net'); % 保存神经网络模型
output = vec2ind(output);
output = output';
xlswrite(trainoutputfile,[txt,'模型输出';num2cell([data,output-1])]);
disp('LM神经网络模型构建完成!');
3、CART决策树模型
construct_dt_model.m
%% 构建CART决策树模型
clear;
% 参数初始化
% 训练数据
trainfile = '..\data\train_model.xls';
% 构建的决策树模型存储路径
treefile = '..\tmp\tree.mat';
% 训练数据模型输出文件
trainoutputfile = '..\tmp\dt_train_output_data.xls' ;
%% 读取数据,并提取输入输出
[data,txt]=xlsread(trainfile);
input=data(:,1:end-1);
targetoutput=data(:,end);
% 使用训练数据构建决策树
tree= fitctree(input,targetoutput);
%% 使用构建好的决策树模型对原始数据进行测试
output=predict(tree,input);
% 变换数据并画混淆矩阵图
output=output';
targetoutput=targetoutput';
output= full(ind2vec(output+1));
targetoutput = full(ind2vec(targetoutput+1));
plotconfusion(targetoutput,output);
%% 保存数据
save(treefile,'tree'); % 保存决策树模型
output = vec2ind(output);
output = output';
xlswrite(trainoutputfile,[txt,'模型输出';num2cell([data,output-1])]);
disp('CART决策树模型构建完成!');
4、模型评价
test_lm_dt_model.m
%% LM神经网络和CART决策树模型测试
clear;
% 参数初始化
testfile = '..\data\test_model.xls'; % 训练数据
treefile = '..\tmp\tree.mat'; % 决策树模型存储路径
netfile = '..\tmp\net.mat'; % 神经网络模型存储路径
% 测试数据模型输出文件
dttestoutputfile = '..\tmp\dt_test_output_data.xls' ;
% 测试数据模型输出文件
lmtestoutputfile = '..\tmp\lm_test_output_data.xls' ;
[data,txt] = xlsread(testfile);
input = data(:,1:end-1);
target = data(:,end);
%% 使用构建好的决策树模型对原始数据进行测试
load(treefile); % 载入决策树模型
output_tree=predict(tree,input);
% 决策树输出数据变换以及画ROC曲线图
output_tree= full(ind2vec(output_tree'+1));
targetoutput = full(ind2vec(target'+1));
figure(1)
plotroc(targetoutput,output_tree);
%% 使用构建好的神经网络模型对原始数据进行测试
load(netfile); % 载入神经网络模型
output_lm = sim(net,input');
% 测试数据数据变换以及画ROC曲线图
figure(2)
plotroc(targetoutput,output_lm);
%% 写入数据
output_lm=vec2ind(output_lm);
output_lm = output_lm'-1;
output_tree=vec2ind(output_tree);
output_tree=output_tree'-1;
xlswrite(lmtestoutputfile,[txt,'模型输出';num2cell([data,output_lm])]);
xlswrite(dttestoutputfile,[txt,'模型输出';num2cell([data,output_tree])]);
disp('CART决策树模型和LM神经网络模型测试完成!');
参考文献:《matlab数据分析与挖掘实战》 by 张良均、杨坦、肖刚、徐圣兵 等