数据预处理:删除零值数据和缺省数据;众数补全(matlab)

%%场景二
%%节点数据预处理
function [X,Y]=nodedata_pro()
%导入班节点数据
[num_2ban1,~,raw_2ban1]=xlsread('sen2ban1.xlsx');
[num_2ban2,~,raw_2ban2]=xlsread('sen2ban2.xlsx');
[num_2ban3,~,raw_2ban3]=xlsread('sen2ban3.xlsx');
[num_2ban4,~,raw_2ban4]=xlsread('sen2ban4.xlsx');
[num_2ban5,~,raw_2ban5]=xlsread('sen2ban5.xlsx');
[num_2ban6,~,raw_2ban6]=xlsread('sen2ban6.xlsx');
[num_2ban7,~,raw_2ban7]=xlsread('sen2ban7.xlsx');
[num_2ban8,~,raw_2ban8]=xlsread('sen2ban8.xlsx');
%导入排节点数据
[num_2pai1,~,raw_2pai1]=xlsread('sen2pai1.xlsx');
[num_2pai2,~,raw_2pai2]=xlsread('sen2pai2.xlsx');
[num_2pai3,~,raw_2pai3]=xlsread('sen2pai3.xlsx');
%将ban1~ban3前三行无效信息删去,使得ban1~ban3节点与其余节点格式保持一致
num_2ban1=num_2ban1(:,4:end);
num_2ban2=num_2ban2(:,4:end);
num_2ban3=num_2ban3(:,4:end);
raw_2ban1=raw_2ban1(:,4:end);
raw_2ban2=raw_2ban2(:,4:end);
raw_2ban3=raw_2ban3(:,4:end);
[m,n]=size(num_2ban1);
k=[5,8,11,14,17,20];             %有效信息所在的列数
feature=cell(1,length(k));       %提取有效特征名称
feature_data=zeros(11*m,length(k)+1);  %创建存储特征数据的数组feature_data;11为节点总个数
% original_data为(删去了ban1~ban3前三列后的)原始数据;
ban_table=3*ones(m,1);                 %加入节点类别,班级别为3
pai_table=2*ones(m,1);                 %加入节点类别,排级别为2
original_data=[num_2ban1,ban_table;num_2ban2,ban_table;num_2ban3,ban_table;num_2ban4,ban_table;num_2ban5,ban_table;num_2ban6,ban_table;num_2ban7,ban_table;num_2ban8,ban_table;
    num_2pai1,pai_table;num_2pai2,pai_table;num_2pai3,pai_table];
for i=1:length(k)+1
    if i<length(k)+1                      %输入特征
    feature{1,i}=raw_2ban1{1,k(i)};     
    feature_data(:,i)=original_data(:,k(i));
    else
         feature_data(:,i)=original_data(:,end);  %输入节点类别
    end      
end
% 按行(时间点)遍历
% ①利用Flag判断每个时间点数据是否有效,每个时间点拥有一个Flag,初始Flag=0;
% 判断第一个特征是否是NAN 【isnan(feature(:,1))】,是则Flag=Flag+1;
% ②除了特征1以外的特征,若为0,Falg=Flag+1;若为NAN,Flag=Flag+1;
% ③判断Flag是否大于等于特征数目的一半,若是,则删去该时间点的数据;if Flag>=size(feature_data,2)-1
% ④得到最终数据【保留有有效信息的数据】
%% 遍历所有时间点的特征数据,开始删除0和nan过多的无效数据
[m1,n1]=size(feature_data);
Flag=zeros(m1,1);
data_pro1=[];
count=1;
for j=1:m1                      
    Flag(j)=0;
    if isnan(feature_data(j,1))==1
        Flag(j)=Flag(j)+1;
    end
    rest_feature=feature_data(j,2:end-1);    %剩余特征为除了第一列外的其他特征
    Flag(j)=Flag(j)+sum(isnan(rest_feature))+length(find(rest_feature==0)); 
    %Flag为第一列是否为NAN,sum()为统计剩余特征中nan的个数;length()为统计剩余特征中0的个数
    if Flag(j)<(n1-1)/2 %Flag<特征总数的一半,保留该特征
        data_pro1(count,:)=feature_data(j,:);
        count=count+1;
    end       
end

%% 删除无效特征(按列)(无意义的零值和NAN数据数目超过总样本数一半的)
[m2,n2]=size(data_pro1);
nan_0_num=zeros(1,n2-1);  %统计特征1的nan个数;统计其他特征0+nan的个数
count1=1;
count2=1;
data_pro2=[];             %存储删除无效特征后的数据
for k=1:n2-1              %n2的最后一行为类别,不计入特征,所以为n2-1
    if k==1
        nan_0_num(k)=sum(isnan(data_pro1(:,k)));
    else
        nan_0_num(k)=sum(isnan(data_pro1(:,k)))+length(find(data_pro1(:,k)==0));
    end
        if nan_0_num(k)<m2/2                  % 特征中的无效数据数目小于总样本数的一半,则该特征予以保留
        data_pro2(:,count1)=data_pro1(:,k);
        count1=count1+1;
        else
            feature_delete_index(count2)=k;   % 特征中的无效数据数目大于等于总样本数的一半,则删除该特征,并返回特征序号,存储子啊feature_delete_index中
            count2=count2+1;
        end
end    
%数据补全:对零值数据和NAN数据进行众数补全
data_pro3=data_pro2;
for i=1:size(data_pro2,2)
    if i==1
        index_1_nan=find(isnan(data_pro2(:,1))==1);       %返回第一列中为nan数值的样本序号;
        data_pro3(index_1_nan,1)=mode(data_pro2(:,1));    %用众数补全的方法补全第一列的nan缺省数据
    else
        index_1_nan=find(isnan(data_pro2(:,i))==1); 
        data_pro3(index_1_nan,i)=mode(data_pro2(:,i));    %用众数补全的方法补全第i列的nan缺省数据,也可以替换成拉格朗日补全
        index_2_nan=find(data_pro2(:,i)==0); 
        data_pro3(index_2_nan,i)=mode(data_pro2(:,i));    %用众数补全的方法补全第i列的nan缺省数据
    end
end
data_pro3=[data_pro3,data_pro1(:,end)];                   %加入各个样本的类别
X=data_pro3(:,1:end-1);                                   %X是补全后的特征数据
Y=data_pro3(:,end);                                       %Y是X对应的类别(3是班节点,2是排节点)

 

posted @ 2020-05-24 21:50  Feynmania  阅读(1077)  评论(0编辑  收藏  举报