基于SOM-层次聚类结果的新数据类别预测
整个MATLAB代码的背景:
- 有一组数据,几百行,每一行为一个样本,有24列,即24维。
- 现在对这份数据进行聚类处理,先通过SOM聚类得到100个神经元,再用层次聚类把100个神经元进一步聚类得到5类,最终把数据分为了5类。
- 以上聚类模型结束后,需要进行预测模型,用DNN深度神经网络,输入一条新的数据样本(同样24维),判断它属于之前聚类得到的5类中的哪一类。
- 预测模型需要对这个无监督学习分类的模型(就是聚类模型)进行输入,最后输出预测的类别。
问题
聚类模型已经没有问题,可以运行,但是DNN预测的代码(代码第2部分)有问题,代码在后面部分。如何修改?
代码第一部分
clc;
clear;
%%%%%%%%%%%%%%%%%% 数据预处理 %%%%%%%%%%%%%%%%%%
% 指定Excel文件
excelFileName = '123.xlsx';
sheetName = '第一份';
dataRange = 'C2:Z366';
data = xlsread(excelFileName, sheetName, dataRange);
% knn预处理
k = 5;
% 遍历每一行数据
for i = 1:size(data, 1)
% 获取当前行数据
currentRow = data(i, :);
% 判断当前行数据是否全为0
if all(currentRow == 0)
disp(['第', num2str(i), '行数据全为0,跳过KNN算法']);
continue; % 跳过当前循环,继续下一行数据的处理
end
% 执行KNN算法
% 使用 knnimpute 进行预处理
data_preprocessed = knnimpute(data, k);
end
% 计算 zscore
M11 = zscore(data_preprocessed');
x = M11;
%%%%%%%%%%%%%%%%%%%%%% S O M %%%%%%%%%%%%%%%%%%%%
% Create a Self-Organizing Map
dimension1 = 10;
dimension2 = 10;
net = selforgmap([dimension1 dimension2]);
% Choose Plot Functions
% For a list of all plot functions type: help nnplot
net.plotFcns = {'plotsomtop','plotsomnc','plotsomnd', ...
'plotsomplanes', 'plotsomhits', 'plotsompos'};
% Train the Network
[net,tr] = train(net,x);
% Test the Network
y = net(x);
%%%%%%%%%%%%%%%%%%%%%% 层 次 聚 类 %%%%%%%%%%%%%%%%%%%%%%%%
% 获取 SOM 的输出(每个数据点对应的最终神经元索引)
som_output = vec2ind(y);
% 使用 SOM 输出作为 AGNES 的输入
agnes_input = net.IW{1}; % 获取 SOM 输出层的权重矩阵,每行对应一个样本
% 使用层次聚类(AGNES)进行进一步的聚类
Z = linkage(agnes_input, 'complete', 'euclidean'); % 使用complete linkage和欧氏距离
% 设置希望的最大簇的数量
max_clusters = 50;
% 显示 AGNES 的聚类结果
T = cluster(Z, 'maxclust', max_clusters);
% disp('AGNES聚类结果:');
% disp(T);
% 可视化层次聚类树
figure;
dendrogram(Z);
% 根据需要选择最终聚类结果,例如,选择前 k 个聚类
final_clusters = 5;
selected_clusters = cluster(Z, 'maxclust', final_clusters);
% 获取每个类别的数据
clustered_data = cell(final_clusters, 1);
for i = 1:final_clusters
clustered_data{i} = data_preprocessed(selected_clusters == i, :);
end
% 计算每个聚类的平均曲线
cluster_center_curves = zeros(final_clusters, size(data_preprocessed, 2));
for i = 1:final_clusters
cluster_center_curves(i, :) = mean(clustered_data{i}, 1);
end
以上代码都没有问题,可以运行
下面代码第2部分运行有问题,总是显示:
错误使用 trainNetwork
无效网络。
原因:
网络: 缺少输入层。网络必须有至少一个输入层。
层 1: 未连接的输入。每个层输入必须连接到另一个层的输出。
代码第2部分
%%%%%%%%%%%%%%%%%%% 构建和训练DNN模型 %%%%%%%%%%%%%%%%%%%%%%%%
% 假设你的DNN模型包含一个输入层,若干隐藏层,和一个输出层
input_size = size(x, 2); % 输入层大小等于数据维度
output_size = final_clusters; % 输出层大小等于聚类数目
% 构建DNN模型
layers = [
fullyConnectedLayer(50)
reluLayer
fullyConnectedLayer(20)
reluLayer
fullyConnectedLayer(output_size)
softmaxLayer
classificationLayer];
% 设置训练选项
options = trainingOptions('adam', ...
'MaxEpochs', 100, ...
'MiniBatchSize', 32, ...
'InitialLearnRate', 0.001, ...
'LearnRateSchedule', 'piecewise', ...
'LearnRateDropPeriod', 50, ...
'LearnRateDropFactor', 0.1, ...
'Shuffle', 'every-epoch', ...
'Verbose', false);
% 训练DNN模型
dnn_model = trainNetwork(x', categorical(selected_clusters), layers, options);
%%%%%%%%%%%%%%%%%%% 使用DNN进行分类 %%%%%%%%%%%%%%%%%%%%%%
% 假设新的24维数据样本存储在名为 new_data 的向量中
new_data = [ ];
% 预处理新数据,确保与训练数据相同的处理
% knn预处理
k = 5;
% 遍历每一行数据
for i = 1:size(new_data, 1)
% 获取当前行数据
currentRow = new_data(i, :);
% 判断当前行数据是否全为0
if all(currentRow == 0)
disp(['第', num2str(i), '行数据全为0,跳过KNN算法']);
continue; % 跳过当前循环,继续下一行数据的处理
end
% 执行KNN算法
% 使用 knnimpute 进行预处理
newData = knnimpute(new_data, k);
end
% 对新数据进行预处理,例如 zscore
newData_preprocessed = zscore(newData);
% 使用训练好的 DNN 模型进行分类
predicted_labels = classify(dnn_model, newData_preprocessed');
% 输出预测结果
disp('预测结果:');
disp(predicted_labels);