-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathDGF.m
79 lines (71 loc) · 2.48 KB
/
DGF.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
function [nmi, label] = DGF(data, truth, knn, beta, gamma, tol, tol2)
% Use distance graph fusion (DGF) algorithm to perform multi-view clustering.
% Inputs:
% data - a cell matrix which contains some feature matrices with each row being an instance
% truth - a column vector, the target label for all instances
% knn - number of k-nearest neighbors (set knn=0 if using fully connected graph)
% beta, gamma - hyperparameters for the algorithm
% Optional Inputs:
% tol, tol2 - the tolerance that determines convergence of algorithm
% Outputs:
% nmi - normalized mutual information
% label - label generated by spectral clustering on the learned unified graph
% See "Youwei Liang, Dong Huang, and Chang-Dong Wang. Consistency Meets
% Inconsistency: A Unified Graph Learning Framework for Multi-view
% Clustering. 2019 IEEE International Conference on Data Mining(ICDM)."
% for a detailed description of the algorithm.
% Author: Youwei Liang
% 2019/08/31
if nargin < 6
tol = 1e-4;
tol2 = 1e-2;
end
self_b = beta; cross_b = gamma;
v = length(data); % number of views
distance = cell(1, v);
original_distance = cell(1, v);
idx = cell(1, v);
n = length(truth);
numClust = length(unique(truth));
ONE = ones(n);
knn_idx = false(n);
for i=1:v
try
s = sprintf('dist%d.mat', i); % try to read the weight matrix (if saved previously)
load(s)
catch
[~, W] = make_affinity_matrix(data{i}, 'euclidean');
% save(s, 'W') % weight matrix may be saved for repeating experiments
end
original_distance{i} = W;
if knn ~= 0
[W, idx{i}] = distance_kNN(W, knn);
[~, tp] = extract_from_idx(ONE, idx{i});
knn_idx = knn_idx | logical(tp);
end
end
% make knn index symmetric
if knn~=0
knn_idx = knn_idx | knn_idx'; %#ok<*BDSCA>
else
knn_idx = true(n);
end
for i=1:v
if knn ~= 0
distance{i} = logical_extraction(original_distance{i}, knn_idx);
else
distance{i} = original_distance{i};
end
end
com_distance = consistent_graph(distance, knn_idx, self_b, cross_b, tol, tol2);
sigma = mean(mean(com_distance));
affinity_matrix = zeros(n,n);
affinity_matrix(knn_idx) = exp(-com_distance(knn_idx)/(2*sigma));
for i=1:n
affinity_matrix(i, i) = 0;
end
% do kNN again
com_a = kNN(affinity_matrix, knn);
[label] = SpectralClustering(com_a, numClust, 3); % obtain lable for each instance, label # starts from 1
nmi = NMImax(truth, label);
fprintf('knn:%2d, beta:%1.0e, gamma:%1.0e, NMI: %.3f\n', knn, self_b, cross_b, nmi)