您的位置:首页 > 编程语言 > MATLAB

如何将UCI数据集转换成Matlab可用格式

2017-12-10 20:08 477 查看
在开始学习机器学习和数据挖掘的过程中,我的导师让我看了一篇关于聚类的论文 A testing based extraction algorithm for identifying significant communities in networks.pdf,该论文提出了一个基于假设检验的算法ESSC。导师说等我看明白之后就可以编程实现,我看了不到两周,然后试着用 Matlab 实现这个算法。

在实现过程中,我不单单是直接对着论文中的伪代码敲代码,还找了一个数据集作为假想敌。一边对照着伪代码,一边思考着如何才能保证代码在该数据集上跑起来不会有问题,这使我在实现该算法的过程中顺利了很多。

由于 UCI 网站上的数据集都是文本格式,所以我在得到在 Matlab 中比较方便的 .mat 格式遇到了一些困难。经过一番搜索,我把我寻找和得到数据集,再转换成可用格式的过程总结成了一篇博客:如何使用UCI数据集 - 菜鸟阿华

在第一个数据集上做了很多次实验之后,我跟导师反馈说实验效果一直都不是很好,导师建议我把数据进行一下归一化处理并且找一些其他的数据集实验。经过一番寻找,我找到了一个符合要求的数据集 Wine。当我打算用原来的方法得到可用格式数据时出现了一些问题,于是我查询了所使用函数 textread 的帮助文档 textread。原方法有一定问题,而且我忽略了Matlab提供的Note:



按照Matlab指示,我查看了 textscan 的帮助文档 textscan,学习了该函数的使用方法,对着 Matlab 提供的示例,一个一个敲出来观察实验结果。经过一番折腾,我终于得到了 Wine 数据集的可用格式,实现代码如下:

fileID = fopen('wine.data'); % 该数据文件需在当前目录下
C = textscan(fileID, '%f %f %f %f %f %f %f %f %f %f %f %f %f %f', 'delimiter', ','); % 返回cell格式的数据 %f个数为特征个数
fclose(fileID);
source_wine = cell2mat(C); % 将cell格式转换成mat格式
wine = source_wine(:, 2:14); % 第一列是类标签,去掉即可
save source_wine.mat source_wine; % 便于将来使用
save wine.mat wine;


新方法看起来原方法简单多了吧!这里仍有值得注意的两点:1. Matlab中的cell是什么? 2. cell2mat方法如何使用。不过博主对于这两点还不太清楚,于是赶紧滚去查一些大牛的博客啦~~

顺便贴一下我实现的ESSC代码吧(程序中还有bug但一直找不到,/哭泣):

function [ c_number ] = ESSC(dist_matrix, alpha)
% ESSC : ESSC主函数
% 参数dist_matrix:数据集中两两之间的距离矩阵
% 参数dataset:整个数据集 类似iris数值型数据
% 参数alpha: 显著性水平阈值

d = [1:size(dist_matrix, 1)]';      % vector 标识数据集中数据的index
v = d;                              % 提取一个社区后剩余的数据
c_number = 1;
proportion = 1/2;                   % 种子大小比例

while c_number
% 选取种子集合seedset
random = round(1 + (size(v, 1)-1)*rand);         % 产生1-size(v,1)随机数,四舍五入
seed = v(random);                                % 种子为剩余数据v中的第random条数据
seedset = [];                                    % 种子集合
seedset_size = round(size(v, 1) * proportion);   % 确定种子集合的大小:每次剩余数据的1/2
% 提取剩余数据集v中与seed数据距离最近的(seedset_size)条数据,距离最近的是seed本身
if seedset_size ~= 0
seed_dist_with_v = [v, dist_matrix(seed, v')'];
seed_dist_with_v_sort = sortrows(seed_dist_with_v, 2); % 按第2列距离排序
seedset = seed_dist_with_v_sort(1:seedset_size, 1);
elseif seedset_size == 0
seedset = [seed];
end

% Community-Search
b0 = seedset;                        % b0 第一次循环代表种子集合,之后代表上一次发现的社区
b1 =  [];                            % 每次社区更新后的结果
b_temp = b0;                         % 临时社区 第一次为b0

while ~(isempty(setdiff(b0, b1)) && isempty(setdiff(b1, b0))) % b0不等于b1
b0 = b1;                                   % b0代表上一次发现的社区 第一次为空集
group1 = b_temp;                 % 得到group1
group2 = setdiff(d, b_temp);     % 得到group2
b_temp = [];                     % 临时社区置空
% 对数据集d中的每一条数据i,计算数据i到两个group中每条数据的距离vector
group1_dist = [];
group2_dist = [];
pvalue = [[1:150]', ones(150,1)];
for i = 1: size(d, 1)
% 计算数据i到group1中每条数据的距离vector
group1_dist = dist_matrix(i, group1')';
% 计算数据i到group2中每条数据的距离vector
group2_dist = dist_matrix(i, group2')';
% 计算pvalue
if(size(group1_dist, 1) ~= 0 && size(group2_dist, 1) ~= 0)
pvalue(i, 2) = ranksum(group1_dist, group2_dist, 'tail', 'left');
end
end
% pvalue排序和使用FDR校正
pvalue_order = sortrows(pvalue, 2);
for i = 1:size(pvalue_order, 1)
if pvalue_order(i, 2) <= i*alpha/size(pvalue_order, 1)
b_temp = [b_temp; pvalue_order(i, 1)];
elseif pvalue_order(i, 2) > i*alpha/size(pvalue_order, 1)
break;
end
end
b1 = b_temp;
end

% 收集社区
c0 = b0;           % Community_search返回的社区b0
c = strcat('c', int2str(c_number)); %字符串c 代表第c_number个社区的名字
eval([c, '=c0;']); % 把c0的值赋值给名字为字符串c的变量中
if ~isempty(c0)
save(strcat('community_', strcat(int2str(c_number), '.mat')), c);
c_number = c_number + 1;
v = setdiff(v, c0);
if size(v, 1) == 0
break;
end
elseif isempty(c0)
break;
end

end

c_number = c_number -1;  % 社区个数
save('background.mat', 'v');

end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息