-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHypergraphSVM.m
More file actions
148 lines (118 loc) · 5.54 KB
/
HypergraphSVM.m
File metadata and controls
148 lines (118 loc) · 5.54 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
classdef HypergraphSVM
methods (Static)
%% stochastic matrix for graph
function [theta, Pi] = computeStochasticMatrix_graph(G)
%G is an adjacency matrix
outDegree = sum(G, 2);
invOutDegree = outDegree.^(-0.5);
Dv = diagonalize(outDegree);
invDv = diagonalize(invOutDegree);
%beta = 0.9;
%n = size(G, 1);
%theta = beta*invDv*G + (1-beta)*ones(n,n)*(1/n);
%Pi = beta*Dv/trace(Dv) + (1-beta)*speye(n,n)*(1/n);
theta = invDv*G*invDv;
theta = full(theta);
Pi = outDegree/trace(Dv);
%theta = (Pi^0.5*theta*Pi^-0.5 + Pi^-0.5*theta'*Pi^0.5)/2;
end
%% stochastic matrix for hypergraph
function [theta, Pi] = computeStochaticMatrix_hypergraph(H, W)
dv = sum(H*W, 2); %vertex degree vector
invdv = dv.^(-0.5);
Dv = diagonalize(dv);
invDv = diagonalize(invdv);
de = sum(H, 1)-1; %edge degree vector
De = diagonalize(de); %edge degree diagonal matrix
theta = invDv*H*W*De^(-1)*H'*invDv; % stochastic matrix
theta(eye(size(theta))==1) = 0;
Pi = dv/trace(Dv);
end
%% Compute weights to maximize purity
function W = computeWeights(H, fixLabels)
display('Computing weights of hyperedges');
e = size(H, 2);
W = zeros(e,3);
for i = 1:e
labelk = fixLabels(H(:,i)==1);
labelk = labelk(labelk~=-1); %considering only known instances
%if isempty(labelk)
% fprintf('%d\n', i);
%end
[yPos, freq] = mode(labelk); %max occuring label and its frequency
yNegLengthk = length(labelk) - length(find(labelk==yPos)); %number of instances with other labels
numNegativeInstances = length(find(fixLabels~=yPos)) - length(find(fixLabels==-1));
hellingerSimilarity = ( (freq/length(find(fixLabels==yPos)))^0.5 - (yNegLengthk/numNegativeInstances)^0.5 )^2;
%hellingerSimilarity = ( (freq/length(labelk))^0.5 - (yNegLengthk/length(labelk))^0.5 )^2;
W(i,:) = [i i hellingerSimilarity];
end
index = ~isnan(W(:,3));
W(isnan(W)) = mean(W(index,3));
W = spconvert(W);
end
%% Combine Pi
function [Pi_mix, Theta_mix] = combineRandomWalk(pi, theta, alpha)
% pi is nXd matrix where n is the number of instances and d is
% the number of views
if length(alpha)==1
Pi_mix = pi;
Theta_mix = theta{1};
return;
end
n = size(pi, 1);
Pi_mix = sparse(n, 1);
for i=1:length(alpha)
Pi_mix = Pi_mix + alpha(i)*pi(:, i);
end
beta = zeros(size(pi));
for i = 1:length(alpha)
beta(:, i) = alpha(i)*(pi(:, i)./Pi_mix);
end
clear pi;
Theta_mix = sparse(n, n);
for i=1:length(alpha)
Theta_mix = Theta_mix + diagonalize(beta(:, i))*theta{i};
end
% Theta_mix = sparse(Theta_mix);
end
%% learn weights
function clusterLabels = predict(H, fixLabels, alpha)
%H is a cell array with H{k} representing
%kth hypergraph
%fixLabels contain class labels of instances. fixLabels = -1
%for instances whose class labels are not known.
numInstances = size(H{1}, 1);
numGraphs = length(H);
Pi = zeros(numInstances, numGraphs);
for i = numGraphs:-1:1
W = HypergraphSVM.computeWeights(H{i}, fixLabels);
[theta{i}, Pi(:, i)] = HypergraphSVM.computeStochaticMatrix_hypergraph(H{i}, W);
H{i} = [];
end
[PiMix, thetaMix] = HypergraphSVM.combineRandomWalk(Pi, theta, alpha);
clear theta Pi;
PiMix = diagonalize(PiMix);
% laplacian = eye(size(thetaMix)) - ((PiMix*thetaMix + thetaMix'*PiMix)/2)*PiMix^(-1);
%
% d = eigs(laplacian, 1);
% kernel = (eye(size(laplacian)) + (1/d)*laplacian)^(-1);
kernel = (thetaMix + thetaMix')/2;
kernel(eye(size(kernel))==1) =1;
% minEig = eigs(kernel, 1, 'sm');
% fprintf('Smallest eigen value of kernel : %d\n', minEig);
%
% if minEig<0
% display('Error : Kernel is not PSD');
% end
display('Calculated Kernel');
numTrain = length(find(fixLabels~=-1));
numTest = length(find(fixLabels==-1));
addpath('/home/SaiNageswar/Matlab/libsvm-3.17/matlab');
model = libsvmtrain(fixLabels(fixLabels~=-1), [(1:numTrain)' , kernel(fixLabels~=-1, fixLabels~=-1)], '-t 4'); %kernel matrix of train-train
predicted = libsvmpredict(ones(numTest, 1), [(1:numTest)' , kernel(fixLabels==-1, fixLabels~=-1)], model); %kernel matrix of test-train
predictedLabels = fixLabels;
predictedLabels(fixLabels==-1) = predicted;
clusterLabels = predictedLabels;
end
end
end