-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathSGF.m
79 lines (70 loc) · 2.52 KB
/
SGF.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
78
function [nmi, label] = SGF(data, truth, knn, beta, gamma, tol, tol2)
% Use similarity graph fusion (SGF) 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
affinity = cell(1, v);
original_affinity = 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('kernel%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_affinity{i} = W;
if knn ~= 0 % not using fully connected graph
[W, idx{i}] = kNN(W, knn);
[~, tp] = extract_from_idx(ONE, idx{i});
knn_idx = knn_idx | logical(tp); % common kNN index for all views
end
affinity{i} = W;
end
if knn ~= 0
for i=1:v
for j=1:v
if j~=i
[~, tp] = extract_from_idx(original_affinity{i}, idx{j});
affinity{i} = affinity{i} + (tp + tp')/2;
end
end
end
end
% make knn index symmetric
if knn~=0
knn_idx = knn_idx | knn_idx'; %#ok<*BDSCA>
else
knn_idx = true(n);
end
[com_affinity, E, A] = consistent_graph(affinity, knn_idx, self_b, cross_b, tol, tol2);
% do kNN again
com_a = kNN(com_affinity, knn);
[label] = SpectralClustering(com_a, numClust, 3); % obtain lable for each instance, label # starts from 1
nmi = NMImax(truth, label);
% [ACC, MIhat, Purity] = ClusteringMeasure(truth, label);
fprintf('knn:%2d, beta:%1.0e, gamma:%1.0e, NMI: %.3f\n', knn, self_b, cross_b, nmi)