You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MissingNodes_S8b.m 81KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414
  1. function [ rand_score, purity, p_triads, missing_nodes_mapping, removed_nodes] = MissingNodes_S8b(dataFilePath, dataFileName, attributes, attUpperRange, attWeightVec, addMissingAttVec, normFactorVec, affinityType, ...
  2. num_missing_nodes_arr, attAffinityThreshold, imagesData, numImagesProfiles, imgMissProb, imgSimType, imgSimProbDiff, percentKnownPlaceholdersVec, dumpSmallFlag, dumpSmallDataPath, iter, missingNodes )
  3. %%global g_threshold; % Sigal - 15.10.13 remove warning
  4. % addpath 'Spectral Clustering' % sigal 13.8.12
  5. % addpath 'mex'% sigal 13.8.12
  6. p_triads = [];
  7. k = 0
  8. %create a log file for this run
  9. %date_now = clock;
  10. %date_now = strcat(num2str(date_now(1)),'_',num2str(date_now(2)),'_', num2str(date_now(3)),'_', num2str(date_now(4)), num2str(date_now(5)),'_', num2str(date_now(6)));
  11. %dump dir for save reduce graphs for GED
  12. %dumpSmallDataPath = sprintf('%sdumpSmallData_%s/', resultsDir, date_now);
  13. %diary(strcat('C:\missingnodes\Code\Log\log', date_now,'.log'));
  14. %affinity calculation types
  15. global affinity_calculation_shortest_path;
  16. global affinity_calculation_euclid;
  17. global affinity_calculation_common_friends;
  18. global affinity_calculation_random_clustering;
  19. global affinity_calculation_adamic_adar;
  20. global affinity_calculation_katz_beta_0_5;
  21. global affinity_calculation_katz_beta_0_05;
  22. global affinity_calculation_katz_beta_0_005;
  23. global affinity_calculation_AA_RCN;
  24. global affinity_boost;
  25. global affinity_boost2;
  26. affinity_calculation_shortest_path = 0;
  27. affinity_calculation_euclid = 1;
  28. affinity_calculation_common_friends = 2;
  29. affinity_calculation_random_clustering = 3;
  30. affinity_calculation_adamic_adar = 4;
  31. affinity_calculation_katz_beta_0_5 = 5;
  32. affinity_calculation_katz_beta_0_05 = 6;
  33. affinity_calculation_katz_beta_0_005 = 7;
  34. affinity_calculation_AA_RCN = 8;
  35. % sigal 12.3.13 add BOOST option
  36. affinity_boost = 9;
  37. affinity_boost2 = 8;
  38. %%%%% for distance as function of num placeholders %%%%
  39. expectedParms = 19;
  40. if nargin < expectedParms
  41. LogMsg(sprintf('*** ERROR: MissingNodes_S8b - Inavlid # of parameters, expected %d got %d',expectedParms,nargin));
  42. return;
  43. end
  44. percent_known_placeholders_vec = percentKnownPlaceholdersVec;
  45. if nargin >= expectedParms+1
  46. select_random_missing_nodes = 0;
  47. else
  48. select_random_missing_nodes = 1;
  49. end
  50. affinity_types = affinityType;
  51. compensate_for_unknown_placeholers = 0;
  52. compensate_vec = [0 0.3 0.65 1 1.5];
  53. unite_common_friends = 0; %should UNK nodes be united in accordance with the "friend of my friend principle"
  54. cluster_only_missing_nodes = 1;
  55. % if affinity_calculation_type == affinity_calculation_shortest_path || affinity_calculation_type == affinity_calculation_euclid
  56. % non_neighbors_distance = Inf;
  57. % elseif affinity_calculation_type == affinity_calculation_common_friends
  58. % non_neighbors_distance = 0;
  59. % end
  60. non_neighbors_distance = 0;
  61. ExpNormFactorVecLen = 3;
  62. normFactorVecLen = size(normFactorVec,2);
  63. if normFactorVecLen ~= ExpNormFactorVecLen
  64. LogMsg(sprintf('*** ERROR: MissingNodes_S8b - invalid normFactorVec expected len=%d got %d',ExpNormFactorVecLen, normFactorVecLen));
  65. return;
  66. end
  67. global netAffNormFactor1;
  68. global netAffNormFactor2;
  69. netAffNormFactor1 = normFactorVec(1);
  70. netAffNormFactor2 = normFactorVec(2);
  71. netAffNormFactor3 = normFactorVec(3);
  72. %compare SC to Kmean, 0=SC, 3=k-mean on PH (mxm), 2=k-mean on PH+Nodes (m*(m+n))
  73. %sigal 1=kmean on PH (with already cut affinitty)
  74. kmeanTypesVec = 1; %[0 1]; %1; %%2 3];
  75. %compare with/without attr, 0=MISC, 1=SAMI-A, 2=SAMI-N, 3=SAMI-AK (k-mean), 4=SAMI-NK
  76. % images => 5=PMI, 7=PMI+SAMI
  77. samiAttrVec = [0 3 5 7]; % [0 4]; % [0 1 3]; % 2];
  78. % Sigal - TODO - if no SAMI-N skip data_untouched_withAtt (~line 160)
  79. run_SAMI_N = 0;
  80. %read the full network, up to num_values links
  81. %disp('reading network information from file...');
  82. fprintf('reading network information from file %s%s ...\n', dataFilePath, dataFileName);
  83. data = load(strcat(dataFilePath, dataFileName), 'data');
  84. %use sparse data
  85. %a = struct2table(data);
  86. %LogMsg(sprintf('%s', a));
  87. data = cell2mat(struct2cell((data)));
  88. data = sparse(data); % THISS IS THE MMATRIX
  89. %sigal 25.11.12
  90. %combine the attributes with data as first #totalAttNum cols/rows
  91. %[dataWithAtt, totalAttNum] = CombineDataWithAttributes(data, attributes, attUpperRange, attWeight);
  92. sami_ind = find(samiAttrVec == 1);
  93. for sami = [1 2 3 4 7]
  94. sami_ind = sami_ind | find(samiAttrVec == sami);
  95. end
  96. if sum(sami_ind,2) > 0
  97. [attData, totalAttNum] = PreProcessDataAttributes(data, attributes, attUpperRange);
  98. else % sigal 31.1.14 support runs without attributes, i.e. only images
  99. attData = 0;
  100. totalAttNum = 0;
  101. end
  102. clear('graph');
  103. %rand_score = zeros(2, 2, size(num_missing_nodes_arr,2), 6, 2); %(normalized or not, unite common friends, num missing nodes, affinity calculation, cluster only missing)
  104. %rand_score_sq = rand_score;
  105. %purity = zeros(2, size(num_missing_nodes_arr,2), 6, 2);%(unite common friends, num missing nodes, affinity calculation, cluster only missing)
  106. %purity_sq = purity;
  107. rand_score = [];
  108. purity = [];
  109. graph_size = size(data,1); % DATA == MATRIX!
  110. graph_edges = nnz(data)/2; % number of edges
  111. %graph_attr_edges = 0; %% sigal 3.1.13: nnz(dataWithAtt)/2 - graph_edges; % number of attributes edges
  112. %num_missing_nodes_arr = round(num_missing_nodes_arr .* graph_size);
  113. %initialize the data matrix (binary adjacency)
  114. disp('generating network graph...');
  115. original_graph_size = size(data,1);
  116. original_data = data;
  117. original_attData = attData;
  118. graph_attr_edges = nnz(attData); % number of attributes edges
  119. avg_attr_edges = graph_attr_edges/original_graph_size;
  120. %original_dataWithAtt = dataWithAtt;
  121. missing_nodes_mapping = [];
  122. for num_missing_nodes_idx = 1 : size(num_missing_nodes_arr,2)
  123. if select_random_missing_nodes
  124. num_missing_nodes = num_missing_nodes_arr(1, num_missing_nodes_idx);
  125. else
  126. num_missing_nodes = length(missingNodes);
  127. end
  128. if num_missing_nodes > numImagesProfiles
  129. LogMsg(sprintf('*** ERROR: MissingNodes_S8b - invalid numImagesProfiles %d vs. numMissingNodes %d.',numImagesProfiles, num_missing_nodes));
  130. return;
  131. end
  132. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  133. %remove random nodes %
  134. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  135. %randomize the missing nodes indexes and sort in descending order
  136. %disp('selecting random missing nodes...');
  137. fprintf('selecting %d random missing nodes...\n',num_missing_nodes);
  138. %sigal - 25.11.12 - remove same nodes from data and dataWithAtt
  139. if select_random_missing_nodes
  140. %[data, missing_nodes_mapping] = RemoveRandomNodes( original_data, num_missing_nodes, missing_nodes_mapping, non_neighbors_distance );
  141. fprintf('testtesttes');
  142. fprintf('testsalam%i', num_missing_nodes);
  143. [data, attData, missing_nodes_mapping] = RemoveRandomNodesWithImages( original_data, original_attData, totalAttNum, num_missing_nodes, missing_nodes_mapping, numImagesProfiles );
  144. else
  145. %Sigal 13.10.13 - TODO - add option to pre selected missing node
  146. %Sigal - 23.1.14 - %%%%TODO - add option for images
  147. fprintf('*** ERROR: pre selected missing node is not suported for images \n');
  148. [data, attData, missing_nodes_mapping] = RemoveRandomNodes3( original_data, original_attData, totalAttNum, num_missing_nodes, missing_nodes_mapping, non_neighbors_distance, missingNodes);
  149. end
  150. data_untouched = data;
  151. if run_SAMI_N
  152. tic %att_combine_calc_time in seconds
  153. data_untouched_withAtt = CombineDataWithAttributes4(data, attData);
  154. att_combine_calc_time = toc;%att_combine_calc_time
  155. else
  156. fprintf('Combining attribtes ...==> Skip\n');
  157. att_combine_calc_time = 0;
  158. end
  159. % loop over addMissingAtt options
  160. for addMissingAtt = addMissingAttVec
  161. LogMsg(sprintf('S8b:astddMissingAtt=%.3f',addMissingAtt));
  162. % loop over partial data options
  163. for percent_known_placeholders = percent_known_placeholders_vec
  164. data0 = data_untouched;
  165. %sigal - TODO all reference to data0 and S ???
  166. % S is uncertainty vector when we don't known the placeholders
  167. S = zeros(1, size(data0,2));
  168. num_placeholders_to_remove = 0;
  169. placeholders_to_remove = [];
  170. num_placeholders = size(data0,1) - original_graph_size + num_missing_nodes ;
  171. last_known_node = size(data0,1) - num_placeholders;
  172. if percent_known_placeholders < 1
  173. num_placeholders_to_remove = round(num_placeholders * (1 - percent_known_placeholders));
  174. while size(placeholders_to_remove, 2) < num_placeholders_to_remove
  175. %randomly selecting unique placeholder indexes
  176. placeholders_to_remove = unique([placeholders_to_remove, randi(num_placeholders, 1, num_placeholders_to_remove - size(placeholders_to_remove, 2))]);
  177. end
  178. %rand_vec = rand(1, num_placeholders);
  179. %placeholders_to_remove = find(rand_vec > percent_known_placeholders) + last_known_node;
  180. placeholders_to_remove = placeholders_to_remove + last_known_node;
  181. %S is the group of neighbors of the unknown placeholders
  182. S = data0(placeholders_to_remove(1), :);
  183. for i = placeholders_to_remove
  184. S = S | data0(i,:);
  185. end
  186. %switch from binary vector to list of indexes
  187. % S = find(S);
  188. %data_all_placeholders = data0;
  189. data0(placeholders_to_remove,:) = [];
  190. data0(:,placeholders_to_remove) = [];
  191. num_placeholders = num_placeholders - num_placeholders_to_remove;
  192. end
  193. %save the removed nodes in each iteration
  194. removed_nodes{num_missing_nodes_idx} = missing_nodes_mapping(1,:);
  195. %save S
  196. orig_S = S;
  197. %sigal - adjust to withAttr flag TOCHECK
  198. %sigal - 12.6.13 - move after calcAffinity so we can calculate only the reduce entries
  199. % tic %att_affinity_calc_time in seconds
  200. % fprintf('calculating attribtes affinity matrix...\n');
  201. % attAffinity = CalcAttributesAffinity_S3(data0, attData, last_known_node, addMissingAtt, attAffinityThreshold);
  202. % att_affinity_calc_time = toc;%att_affinity_calc_time
  203. att_affinity_merge_time = 0;
  204. all_clustering = [];
  205. all_clustering_alg = [];
  206. all_att_clustering = [];
  207. all_att_clustering_alg = [];
  208. all_k1_clustering = [];
  209. all_k1_clustering_alg = [];
  210. all_k3_clustering = [];
  211. all_k3_clustering_alg = [];
  212. all_A2_clustering = [];
  213. all_A2_clustering_alg = [];
  214. all_A4_clustering = [];
  215. all_A4_clustering_alg = [];
  216. % sigal 12.6.13 - use as flag for first time calculation
  217. attAffinity = 0;
  218. phsAttAffinity = 0;
  219. phsAttAffinity2 = 0;
  220. phsImgAffinity = 0;
  221. % loop over different affinity_types
  222. for affinity_calculation_type = affinity_types
  223. % sigal 12.11.13 - use as flag for first time calculation
  224. phsNetAffinity = 0;
  225. if affinity_calculation_type == affinity_boost
  226. withAttrVec = affinity_boost; %[affinity_boost affinity_boost2];
  227. elseif affinity_calculation_type == affinity_calculation_random_clustering
  228. withAttrVec = 0;
  229. else
  230. % sigal 12.3.13 - run several times:
  231. % 0=original, 1=weighted affinity, 2=weighted dataWithAttr
  232. withAttrVec = samiAttrVec; %Sigal - 15.10.13
  233. end
  234. % sigal 25.11.12
  235. % run loop - once as original without attributes and next with attriutes
  236. for withAttr = withAttrVec
  237. netAffinity = 0; % sigal 24.10.13 - use as flag for first time calculation
  238. % sigal 5.3.13 - loop over weights
  239. if withAttr == 0
  240. attWeightVector = 0;
  241. elseif withAttr == affinity_boost || withAttr == affinity_boost2
  242. attWeightVector = [0.1 0.2 0.4]; % sigal - use OASCA per Affinity/kmean
  243. if kmeanTypesVec==0 % find(kmeanTypesVec==0) %
  244. attWeightVector = [0 attWeightVector];
  245. end
  246. % elseif withAttr == 1 && addMissingAtt > 0 % sigal 23.10.13
  247. % attWeightVector = 0.2:0.1:0.8; %0.8; %
  248. elseif affinity_calculation_type == affinity_calculation_common_friends
  249. if withAttr == 3
  250. attWeightVector = 0.3:0.1:0.5; %0.3:0.1:0.5;
  251. else
  252. attWeightVector = 0.2:0.1:0.4; %5; %%0.2:0.1:0.5; %0.3; %0.2:0.1:0.5; %0.3; %
  253. end
  254. elseif affinity_calculation_type == affinity_calculation_adamic_adar
  255. if withAttr == 4
  256. attWeightVector = 0.2:0.1:0.4; %0.3:0.1:0.5;
  257. else
  258. attWeightVector = 0.6:0.1:0.8; %0.4:0.1:0.6; %0.5:0.1:0.7; %8; %0.4:0.1:0.7; %0.8; %0.5:0.1:0.8;
  259. end
  260. elseif affinity_calculation_type == affinity_calculation_AA_RCN
  261. attWeightVector = 0.1:0.1:0.9; %0.3; %0.2:0.1:0.8; %
  262. elseif affinity_calculation_type == affinity_calculation_katz_beta_0_05
  263. attWeightVector = 0.1:0.1:0.4; %0.8; %0.2:0.1:0.8; %
  264. else
  265. attWeightVector = attWeightVec;
  266. end
  267. if find(withAttr == [3 5 7])
  268. attWeightVector = [0 attWeightVector 1];
  269. end
  270. % run loop for attWeight
  271. for attWeight = attWeightVector
  272. affinity = 0;
  273. phsAffinity = 0;
  274. withAttrWeight = (withAttr+attWeight)*10;
  275. % sigal 3.1.13 - data is the same the change is in the attAffinity
  276. if find(withAttr == [0 1 3 5 7 affinity_boost affinity_boost2])
  277. actual_graph_size = original_graph_size;
  278. num_attr_nodes = 0;
  279. data = data_untouched;
  280. elseif withAttr == 2 || withAttr == 4
  281. actual_graph_size = original_graph_size+totalAttNum;
  282. num_attr_nodes = totalAttNum;
  283. data = data_untouched_withAtt;
  284. else
  285. exception = MException(fprintf('Invalid Attribute Type %d',withAttr));
  286. throw(exception);
  287. end
  288. last_known_node = actual_graph_size - num_missing_nodes;
  289. first_unk_node = last_known_node + 1;
  290. num_added_nodes = size(data,1) - last_known_node;
  291. if withAttr == affinity_boost || withAttr == affinity_boost2
  292. fprintf('calculating best results for affinity matrix, type %d (withAttr=%d)...\n', affinity_calculation_type, withAttrWeight);
  293. % Sigal 10.3.13 - TODO calc best results
  294. if attWeight == 0.9
  295. [test_clustering, best_alg] = ChooseBestResults(all_att_clustering,all_att_clustering_alg,withAttr);
  296. elseif attWeight == 0.1
  297. [test_clustering, best_alg] = ChooseBestResults(all_k1_clustering,all_k1_clustering_alg,withAttr);
  298. elseif attWeight == 0.3
  299. [test_clustering, best_alg] = ChooseBestResults(all_k3_clustering,all_k3_clustering_alg,withAttr);
  300. elseif attWeight == 0.2
  301. [test_clustering, best_alg] = ChooseBestResults(all_A2_clustering,all_A2_clustering_alg,withAttr);
  302. elseif attWeight == 0.4
  303. [test_clustering, best_alg] = ChooseBestResults(all_A4_clustering,all_A4_clustering_alg,withAttr);
  304. else
  305. [test_clustering, best_alg] = ChooseBestResults(all_clustering,all_clustering_alg,withAttr);
  306. end
  307. % Sigal 10.3.13 - TODO sum all times
  308. affinity_calc_time = 0;
  309. graph_predict_time= 0;
  310. reduce_dim_time = 0;
  311. att_affinity_calc_time = 0;
  312. phs_att_affinity_calc_time = 0;
  313. phs_img_affinity_calc_time = 0;
  314. else
  315. % calculate the affinity / similarity matrix
  316. fprintf('calculating affinity matrix, type %d (withAttr=%d)...\n', affinity_calculation_type, withAttrWeight);
  317. if withAttr == 2
  318. tic %affinity_calc_time in seconds
  319. affinity = CalcAffinity( data, affinity_calculation_type, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, 0);
  320. affinity_calc_time = toc;%affinity_calc_time
  321. %sigal - 12.11.13 - calculate once for each type
  322. elseif nnz(netAffinity) == 0 && kmeanTypesVec==0 % find(kmeanTypesVec==0)%
  323. tic %affinity_calc_time
  324. %sigal - adjust to withAttr flag TOCHECK
  325. affinity = CalcAffinity( data, affinity_calculation_type, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, addMissingAtt);
  326. affinity_calc_time = toc;%affinity_calc_time
  327. netAffinity = affinity;
  328. % if affinity_calculation_type ~= affinity_calculation_AA_RCN
  329. % diffAff = affinity(first_unk_node:end,first_unk_node:end)-phsAffinity;
  330. % fprintf('nnz diffAff %d \n',full(nnz(diffAff)));
  331. % end
  332. else
  333. affinity = netAffinity;
  334. affinity_calc_time = 0;
  335. end
  336. if withAttr == 4
  337. tic %affinity_calc_time in seconds
  338. phsAffinity = CalcPHsAffinity( data, affinity_calculation_type, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, addMissingAtt);
  339. affinity_calc_time = toc;%affinity_calc_time
  340. %sigal - 12.11.13 - calculate once for each type
  341. elseif nnz(phsNetAffinity) == 0 && kmeanTypesVec==1 % find(kmeanTypesVec==1)%
  342. tic %affinity_calc_time in seconds
  343. phsNetAffinity = CalcPHsAffinity( data, affinity_calculation_type, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, addMissingAtt);
  344. phsAffinity = phsNetAffinity;
  345. affinity_calc_time = toc;%affinity_calc_time
  346. else
  347. %affinity_calc_time = 0;
  348. phsAffinity = phsNetAffinity;
  349. end
  350. %sigal - 12.6.13 - move after calcAffinity so we can calculate only the reduce entries
  351. if withAttr == 1 && nnz(attAffinity) == 0
  352. nodesToKeep = NodesToKeep(affinity, first_unk_node, 1);
  353. fprintf('nodesToKeep %d \n',full(sum(nodesToKeep)));
  354. % Sigal TODO - what if addMissingAtt > 0 ??
  355. tic %att_affinity_calc_time in seconds
  356. fprintf('calculating attribtes affinity matrix...\n');
  357. debugCalcAttr = 0; %% Sigal 17.10.13 debugging nodesToKeep & maxAttStat
  358. debugAddMissingAtt = 0; %% sigal 16.12.13 backward - use 0 instead of addMissingAtt;
  359. if debugCalcAttr == 1
  360. attAffinity = CalcAttributesAffinity_S5(data0, attData, last_known_node, debugAddMissingAtt, attAffinityThreshold);
  361. else
  362. attAffinity = CalcAttributesAffinity_S5(data0, attData, last_known_node, debugAddMissingAtt, attAffinityThreshold, nodesToKeep);
  363. end
  364. att_affinity_calc_time = toc;%att_affinity_calc_time
  365. end
  366. %sigal - 12.11.13 - calculate once for each type
  367. if (withAttr == 3 || withAttr == 7) && nnz(phsAttAffinity) == 0
  368. tic %att_affinity_calc_time in seconds
  369. phsAttAffinity = netAffNormFactor3*CalcPHsAffinityByAttributes(data0, attData, last_known_node, addMissingAtt, attAffinityThreshold);
  370. phs_att_affinity_calc_time = toc;%att_affinity_calc_time
  371. end
  372. %sigal - 22.2.14 - calculate once for each type %%%%% TODO
  373. if (withAttr == 5 || withAttr == 7) && nnz(phsImgAffinity) == 0
  374. tic %img_affinity_calc_time in seconds
  375. phsImgAffinity = netAffNormFactor3*CalcPHsAffinityByImages(data0, imagesData, last_known_node, missing_nodes_mapping, imgMissProb, imgSimType, imgSimProbDiff);
  376. phs_img_affinity_calc_time = toc;%att_affinity_calc_time
  377. end
  378. if withAttr == 3 %sigal - 22.2.14 - SAMI_AK
  379. if attWeight == 0
  380. if nnz(phsAttAffinity2) == 0
  381. tic %att_affinity_calc_time in seconds
  382. phsAttAffinity2 = netAffNormFactor3*CalcPHsAffinityByAttributes(data0, attData, last_known_node, addMissingAtt, attAffinityThreshold, 1);
  383. phs_att_affinity_calc_time = toc;%att_affinity_calc_time
  384. end
  385. phsAffinity = [netAffNormFactor2*phsAffinity phsAttAffinity2]; % sigal 5.11.13 original order with factor 10
  386. else
  387. phsAffinity = (1-attWeight)*phsAffinity+attWeight*phsAttAffinity;
  388. end
  389. elseif withAttr == 5 %sigal - 22.2.14 - PMI %%%%% TODO
  390. if attWeight == 0
  391. phsAffinity = [netAffNormFactor2*phsAffinity phsImgAffinity]; % sigal 5.11.13 original order with factor 10
  392. else
  393. phsAffinity = (1-attWeight)*phsAffinity+attWeight*phsImgAffinity;
  394. end
  395. elseif withAttr == 7 %sigal - 22.2.14 - PMI+SAMI %%%%% TODO
  396. if attWeight == 0
  397. if nnz(phsAttAffinity2) == 0
  398. tic %att_affinity_calc_time in seconds
  399. phsAttAffinity2 = netAffNormFactor3*CalcPHsAffinityByAttributes(data0, attData, last_known_node, addMissingAtt, attAffinityThreshold, 1);
  400. phs_att_affinity_calc_time = toc;%att_affinity_calc_time
  401. end
  402. phsAffinity = [netAffNormFactor2*phsAffinity phsAttAffinity2 phsImgAffinity];
  403. else
  404. phsAffinity = (1-attWeight)*phsAffinity+attWeight*(phsAttAffinity+phsImgAffinity)/2;
  405. end
  406. end
  407. end
  408. % sigal 3.1.13 - weighted affinity
  409. if withAttr == 1
  410. fprintf('merge affinity matrix with attributes affinity\n');
  411. if debugAddMissingAtt > 0
  412. e = size(affinity,1);
  413. else
  414. e=last_known_node;
  415. end
  416. tic %att_affinity_calc_time
  417. %Sigal - 16.6.13 - use full C implementation
  418. affinity = WeightedSum(affinity, attAffinity, attWeight, e);
  419. %Sigal - 17.6.13 free memory
  420. if original_graph_size > 20000
  421. fprintf('free attAffinity memory\n');
  422. clear('attAffinity');
  423. attAffinity = 0;
  424. fprintf('free netAffinity memory\n');
  425. clear('netAffinity');
  426. netAffinity = 0;
  427. end
  428. % affinity(1:e, 1:e)= affinity(1:e,1:e)*(1-attWeight)+attAffinity(1:e,1:e)*attWeight;
  429. % nnz1 = nnz(affinity);
  430. % nnz2 = nnz(affinity2);
  431. % aaa = affinity2-affinity;
  432. % nnz3 = nnz(aaa);
  433. % fprintf('nnz affinity: nnz1=%d, nnz2=%d, nnz3=%d\n',nnz1,nnz2,nnz3);
  434. att_affinity_merge_time = toc;%att_affinity_merge_time
  435. end
  436. %TODO: extend the dimension reduction to adding missing links / reclustering
  437. %Sigal/ron - ToRECEK ron TODO (done?)
  438. %Sigal - run always with 1 (ron)
  439. for reduce_dimensions = [1] %0 must be first because it does not change the affinity matrix
  440. reduce_dim_time = 0;
  441. skip_reduce_dimensions = find(withAttr == [3 4 5 7 affinity_boost affinity_boost2]); %Sigal 22.1.14 %%% TOCHECK
  442. if reduce_dimensions == 1 && nnz(affinity) > 0 && ~skip_reduce_dimensions
  443. fprintf('reduce dimensions\n');
  444. tic %ReduceDimensions
  445. [affinity, num_placeholders, first_unk_node] = ReduceDimensions(affinity, first_unk_node);
  446. reduce_dim_time = toc; %ReduceDimensions
  447. fprintf('new dimensions %d\n',size(affinity,1));
  448. end
  449. %sigal - why each iteration? simple calculation - can be done once
  450. %sigal - adjust to withAttr flag TODO
  451. fprintf('calculating true clustering\n');
  452. true_clustering = BuildTrueClustering(missing_nodes_mapping, original_graph_size, num_missing_nodes, percent_known_placeholders, placeholders_to_remove, last_known_node);
  453. %figure,imshow(affinity,[]), title('Affinity Matrix')
  454. %sigal - use 0:1 if we want to compare with unknown #missNodes
  455. % (type=2 wasn't tested by ron)
  456. for num_clusters_known = [1] %[0, 1]
  457. % sigal 29.7.13
  458. % Test other clustering kmean types
  459. if affinity_calculation_type == affinity_calculation_random_clustering || affinity_calculation_type == affinity_boost || affinity_calculation_type == affinity_boost2
  460. kmeanTypes = 1;
  461. elseif withAttr == 0
  462. kmeanTypes = kmeanTypesVec;
  463. elseif withAttr == 1 || withAttr == 2
  464. kmeanTypes = 0;
  465. elseif find(withAttr == [3 4 5 7])
  466. kmeanTypes = 1;
  467. else
  468. kmeanTypes = kmeanTypesVec;
  469. end
  470. % loop over added kmeanTypes (clustering types)
  471. for kmeanType = kmeanTypes
  472. %sigal - adjust to withAttr flag TODO - which params? data_untouched, original_graph_size
  473. k = DetermineNumberOfClusters(num_clusters_known, data_untouched, original_graph_size, num_missing_nodes, num_added_nodes);
  474. debugEstimateK = 0;
  475. if debugEstimateK == 1 && affinity_calculation_type == affinity_calculation_common_friends
  476. for type=[0,3,4,8]
  477. estK = DetermineNumberOfClusters(type, data_untouched, actual_graph_size, num_missing_nodes, num_added_nodes);
  478. fprintf('debugEstimateK: type=%d, estK=%d\n',type,estK);
  479. end
  480. end
  481. if num_clusters_known == 1
  482. withAttrC = 0;
  483. elseif num_clusters_known == 0
  484. withAttrC = 10;
  485. else
  486. withAttrC = num_clusters_known*10;
  487. end
  488. % sigal 15.10.13 - add kmeanType & num_clusters to alg type
  489. withAttrC = withAttrC+kmeanType;
  490. withAttrWeight = withAttrC*100+(withAttr+attWeight)*10;
  491. %sigal - first_unk_node might change after ReduceDimensions
  492. last_known_node = first_unk_node - 1;
  493. if withAttr ~= affinity_boost && withAttr ~= affinity_boost2
  494. %sigal - adjust to withAttr flag TOCHECK
  495. fprintf('predicting the graph\n');
  496. tic %graph_predict_time
  497. if kmeanType == 1
  498. [newData, test_clustering] = PredictGraph(phsAffinity, k, data, num_placeholders, affinity_calculation_type, cluster_only_missing_nodes, kmeanType);
  499. else
  500. [newData, test_clustering] = PredictGraph(affinity, k, data, num_placeholders, affinity_calculation_type, cluster_only_missing_nodes, kmeanType);
  501. end
  502. graph_predict_time = toc; %graph_predict_time
  503. end
  504. out_data = newData;
  505. out_clusterrr = test_clustering;
  506. %sigal - when to use - only if there are unknown placeholders
  507. if compensate_for_unknown_placeholers == 1
  508. fprintf('*** running with compensate_for_unknown_placeholers mode ...\n');
  509. S = orig_S;
  510. if size(newData,1) > size(S,2)
  511. %for breakpoint
  512. tttt = 98;
  513. end
  514. sigma = 1/4;
  515. S = S(1:size(newData,1));
  516. S = S + randn(size(S)) * sigma;
  517. sorted_S = sort(S, 'descend');
  518. %sum over the columns and find the columns which
  519. %indicate at least one neighbor
  520. %neighbors_of_new_nodes = find(sum(newData(first_unk_node:size(newData,1), :)));
  521. first_united_node = size(newData,1) - k +1;
  522. if affinity_calculation_type == affinity_calculation_katz_beta_0_05
  523. newAffinity = CalcAffinityByKatzBeta_Sparse( newData, 0.05, 4 );
  524. elseif affinity_calculation_type == affinity_calculation_adamic_adar
  525. newAffinity = CalculateAffinityByAdamicAdar_Sparse(newData, size(newData,1), 0, 0);
  526. elseif affinity_calculation_type == affinity_calculation_common_friends
  527. newAffinity = CalcAffinityByCommonNeighbors_Sparse(newData, size(newData,1), 0);
  528. end
  529. newNodesAffinity = newAffinity(first_united_node:size(newAffinity,1), :);
  530. newNodesAffinity(newNodesAffinity>=1) = 0;
  531. newNodesAffinity = newNodesAffinity / max(max(newNodesAffinity));
  532. %newNodesAffinity = newNodesAffinity / 2;
  533. newNodesAffinity(newData(first_united_node:size(newAffinity,1), :) >= 1) = 0;
  534. newNodesAffinity = (newNodesAffinity / max(max(newNodesAffinity)));
  535. %%%%trying to take only the
  536. %%%%k highest affinities
  537. sortedNewNodesAffinity = sort(newNodesAffinity(:), 'descend');
  538. %affinityThreshold = sortedNewNodesAffinity(k + size(neighbors_of_new_nodes, 2));
  539. newNodesAffinity_orig = newNodesAffinity;
  540. end % compensate_for_unknown_placeholers == 1
  541. if percent_known_placeholders < 1 && compensate_for_unknown_placeholers == 1
  542. %calculating as a function of number of links added
  543. meanNumLinks = mean(sum(data(1:last_known_node, 1:last_known_node)));
  544. maxNumLinksToAdd = meanNumLinks * num_placeholders;
  545. maxNumLinksToAdd = min(maxNumLinksToAdd, 25);
  546. %sigal 27.6.13
  547. linksToAdd = round(compensate_vec*num_missing_nodes);
  548. else
  549. maxNumLinksToAdd = 0;
  550. %sigal 27.6.13
  551. linksToAdd = 0;
  552. end
  553. %%%%% for distance as
  554. %%%%% function of num
  555. %%%%% placeholders %%%%
  556. %max_neighbors = S >= sorted_S(maxNumLinksToAdd);
  557. %sigal 27.6.13
  558. %for numLinksToAdd = 0 : maxNumLinksToAdd
  559. origWithAttrWeight = withAttrWeight;
  560. for linksInx = 1:size(linksToAdd,2)
  561. numLinksToAdd = linksToAdd(linksInx);
  562. %Sigal - 13.10.13 - TODO - fix withAttr flag calculation
  563. withAttrXX = compensate_vec(linksInx)*100; % numLinksToAdd
  564. withAttrWeight = origWithAttrWeight+1000*withAttrXX;
  565. if compensate_for_unknown_placeholers == 1
  566. newNodesAffinity = newNodesAffinity_orig;
  567. neighbors = [];
  568. if numLinksToAdd > 0
  569. neighbors = find(S >= sorted_S(numLinksToAdd), numLinksToAdd);
  570. end
  571. newDataWithMissingLinks = newData; % partial graph with the clustered nodes
  572. newDataForClustering = data0; % partial graph with partial PHs
  573. for neighbor = neighbors
  574. [value, closest_new_node] = max(newNodesAffinity(:,neighbor));
  575. closest_new_node = closest_new_node(1);
  576. newDataWithMissingLinks(first_united_node + closest_new_node - 1, neighbor) = 1;
  577. newDataWithMissingLinks(neighbor, first_united_node + closest_new_node - 1) = 1;
  578. newPlaceholder = zeros(1, size(newDataForClustering,2));
  579. newPlaceholder(neighbor) = 1;
  580. newDataForClustering = [newDataForClustering, newPlaceholder'; newPlaceholder, 0];
  581. end
  582. affinityWithS = CalcAffinity( newDataForClustering, affinity_calculation_type, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, addMissingAtt);
  583. if reduce_dimensions == 1
  584. [affinityWithS, num_placeholdersWithS, first_unk_node_with_s] = ReduceDimensions(affinityWithS, first_united_node);
  585. else
  586. num_placeholdersWithS = num_placeholders + length(neighbors);
  587. first_unk_node_with_s = first_united_node;
  588. end
  589. % Sigal 15.10.13 - we are not using the new clusteing result as in this
  590. % cases we are using the GED as the main measure
  591. fprintf('^%s', newPredictedGraph)
  592. %remap the original data so that the known nodes match the
  593. %predicted data and the missing nodes match the predicted
  594. % nodes created from each cluster
  595. %sigal - adjust to withAttr flag TODO original_data
  596. perm_vector = 1:size(original_data,1);
  597. perm_vector(missing_nodes_mapping(1,:)) = [];
  598. perm_vector = [perm_vector, missing_nodes_mapping(1,:)];
  599. remapped_data = original_data(perm_vector,perm_vector);
  600. [small_data, indices_to_remove] = DecreaseGraphSize(remapped_data, first_united_node : size(remapped_data,1), neighbors); %changed from neighbors to perm(max_neighbors) - to be fair when there are more nieghbors
  601. %small_data2 = DecreaseGraphSize(newData, last_known_node+1 : size(newData,1));
  602. %new_nodes_affinity_sum = sum(sum(newNodesAffinity));
  603. %in case there is an empty cluster, the unrelated nodes may contain node index that does not exist
  604. %in the predicted graph (which may contain less nodes)
  605. indices_to_remove(indices_to_remove > size(newPredictedGraph,2)) = [];
  606. small_data2 = newData;
  607. small_data2(indices_to_remove,:) = [];
  608. small_data2(:,indices_to_remove) = [];
  609. %small_data3 = DecreaseGraphSize(newDataWithMissingLinks, last_known_node+1 : size(newDataWithMissingLinks,1));
  610. small_data3 = newDataWithMissingLinks;
  611. small_data3(indices_to_remove,:) = [];
  612. small_data3(:,indices_to_remove) = [];
  613. small_data4 = newPredictedGraph;
  614. small_data4(indices_to_remove,:) = [];
  615. small_data4(:,indices_to_remove) = [];
  616. Sigal 27.1.13 - save reduce graphs for GED
  617. if dumpSmallFlag == 1
  618. saveSmallData(dumpSmallDataPath, dataFileName, iter, affinity_calculation_type, withAttrWeight, num_missing_nodes, small_data, 1);
  619. saveSmallData(dumpSmallDataPath, dataFileName, iter, affinity_calculation_type, withAttrWeight, num_missing_nodes, small_data2, 2);
  620. end
  621. %only calculate on the first iteration to save time
  622. if numLinksToAdd == 0
  623. edit_distance = 99; %GraphEditDistance( small_data, small_data2, num_missing_nodes );
  624. edit_distance2 = edit_distance;
  625. edit_distance3 = edit_distance;
  626. else
  627. edit_distance2 = 99; %GraphEditDistance( small_data, small_data3, num_missing_nodes );
  628. edit_distance3 = 99; %GraphEditDistance( small_data, small_data4, num_missing_nodes );
  629. if dumpSmallFlag == 1
  630. saveSmallData(dumpSmallDataPath, dataFileName, iter, affinity_calculation_type, withAttrWeight, num_missing_nodes, small_data3, 3);
  631. saveSmallData(dumpSmallDataPath, dataFileName, iter, affinity_calculation_type, withAttrWeight, num_missing_nodes, small_data4, 4);
  632. end
  633. end
  634. elseif withAttr == affinity_boost || withAttr == affinity_boost2 % NOT compensate_for_unknown_placeholers == 1
  635. if dumpSmallFlag == 1
  636. saveSmallData(dumpSmallDataPath, dataFileName, iter, affinity_calculation_type, withAttrWeight, num_missing_nodes, best_alg, 1);
  637. saveSmallData(dumpSmallDataPath, dataFileName, iter, affinity_calculation_type, withAttrWeight, num_missing_nodes, best_alg, 2);
  638. end
  639. else % NOT compensate_for_unknown_placeholers == 1
  640. %sigal - adjust to withAttr flag TODO original_data
  641. perm_vector = 1:size(original_data,1); % set values 1:n
  642. perm_vector(missing_nodes_mapping(1,:)) = []; % according to 1st line of missing nodes remove indexes from perm
  643. perm_vector = [perm_vector, missing_nodes_mapping(1,:)]; % add missing node as last indexes
  644. remapped_data = original_data(perm_vector,perm_vector); % return original graph according to perm
  645. out_data_p = out_data%(perm_vector,perm_vector);
  646. graphs_out = sprintf('../output/graphed_%d.mat', iter);
  647. save(graphs_out, 'out_data_p', 'out_data', 'remapped_data', 'original_data');
  648. %sigal - return data only with missing nodes and their friends
  649. % reduce size to improve GED calulation
  650. [small_data, indices_to_remove] = DecreaseGraphSize(remapped_data, (size(remapped_data,1) - num_missing_nodes + 1) : size(remapped_data,1), []); %changed from neighbors to perm(max_neighbors) - to be fair when there are more nieghbors
  651. %Sigal - now according to original data remove indexes,
  652. %adjust/reduce the predict grpah return at newData
  653. small_data2 = newData;
  654. %sigal - adjust to withAttr flag - remove att nodes TOCHECK
  655. if num_attr_nodes > 0
  656. small_data2(1:num_attr_nodes,:) = [];
  657. small_data2(:,1:num_attr_nodes) = [];
  658. end
  659. %sigal 26.11.12 - change newData to small_data2 after resizing
  660. indices_to_remove(indices_to_remove > size(small_data2,2)) = [];
  661. small_data2(indices_to_remove,:) = [];
  662. small_data2(:,indices_to_remove) = [];
  663. %fprintf('&%s', small_data2)
  664. %fprintf('&&%s', small_data)
  665. Sigal 27.1.13 - save reduce graphs for GED
  666. withAttrWeight = origWithAttrWeight+1000*(1-percent_known_placeholders)*10;
  667. if dumpSmallFlag == 1
  668. saveSmallData(dumpSmallDataPath, dataFileName, iter, affinity_calculation_type, withAttrWeight, num_missing_nodes, small_data, 1);
  669. saveSmallData(dumpSmallDataPath, dataFileName, iter, affinity_calculation_type, withAttrWeight, num_missing_nodes, small_data2, 2);
  670. end
  671. %sigal 6.12.12 - *** TODO *** temporary for test only TODO
  672. %edit_distance = GraphEditDistance( small_data, small_data2, num_missing_nodes );
  673. edit_distance = 99;
  674. % Sigal 10.3.13 - save results (without random)
  675. if attWeight ~= 1 && affinity_calculation_type ~= affinity_calculation_random_clustering
  676. currAlg = affinity_calculation_type*1000+withAttrWeight;
  677. % sigal 21.10.13 (only on SC)
  678. if kmeanType == 0
  679. res_index = size(all_clustering,2) + 1;
  680. all_clustering(:, res_index) = test_clustering;
  681. all_clustering_alg(res_index) = currAlg;
  682. if withAttr ~= 0
  683. att_index = size(all_att_clustering,2) + 1;
  684. all_att_clustering(:, att_index) = test_clustering;
  685. all_att_clustering_alg(att_index) = currAlg;
  686. end
  687. end
  688. % sigal 17.10.13 - find best based on kmeanType == 2
  689. if kmeanType == 1
  690. k_index = size(all_k1_clustering,2) + 1;
  691. all_k1_clustering(:, k_index) = test_clustering;
  692. all_k1_clustering_alg(k_index) = currAlg;
  693. if affinity_calculation_type == affinity_calculation_common_friends
  694. k_index = size(all_A2_clustering,2) + 1;
  695. all_A2_clustering(:, k_index) = test_clustering;
  696. all_A2_clustering_alg(k_index) = currAlg;
  697. elseif affinity_calculation_type == affinity_calculation_adamic_adar
  698. k_index = size(all_A4_clustering,2) + 1;
  699. all_A4_clustering(:, k_index) = test_clustering;
  700. all_A4_clustering_alg(k_index) = currAlg;
  701. end
  702. end
  703. if kmeanType == 2 || kmeanType == 3
  704. k_index = size(all_k3_clustering,2) + 1;
  705. all_k3_clustering(:, k_index) = test_clustering;
  706. all_k3_clustering_alg(k_index) = currAlg;
  707. end
  708. end
  709. end % compensate_for_unknown_placeholers == 1
  710. % calculate the purity for actual clustering
  711. fprintf('calculating purity\n');
  712. try
  713. %sigal - calulation done accoring to definition
  714. temp_purity = ClusteringPurity(true_clustering, test_clustering);
  715. catch ME1
  716. temp_purity = 99; %Sigal 12.8.12 - add invalid value incase of exception
  717. ddddd = 1;
  718. end
  719. clusters_out = sprintf('../output/OUTp_%d.mat', iter);
  720. save(clusters_out, 'true_clustering', 'test_clustering');
  721. % save results
  722. fprintf('saving results (withAttr %d, purity %.5f) \n',withAttrWeight,temp_purity);
  723. %oooo = sprintf('/Users/armin/Desktop/output/OUT_%d.mat', k);
  724. %save(oooo, 'withAttrWeight', 'temp_purity');
  725. curr_index = size(purity,2) + 1;
  726. purity(curr_index).score = temp_purity;
  727. purity(curr_index).score_sq = temp_purity^2;
  728. purity(curr_index).edit_distance = edit_distance;
  729. if compensate_for_unknown_placeholers == 1
  730. purity(curr_index).numLinksToAdd = numLinksToAdd;
  731. purity(curr_index).edit_distance_missing_links = edit_distance2;
  732. purity(curr_index).edit_distance_new_clustering = edit_distance3;
  733. fprintf('numLinksToAdd - %d\nedit_distance - %d\nedit_distance_missing_links - %d\nedit_distance_new_clustering - %d\n', numLinksToAdd, full(edit_distance), full(edit_distance2), full(edit_distance3));
  734. end
  735. purity(curr_index).withAttr = withAttrWeight; % sigal 15.10.13
  736. purity(curr_index).num_missing_nodes_idx = num_missing_nodes_idx;
  737. purity(curr_index).num_missing_nodes = num_missing_nodes_arr(num_missing_nodes_idx);
  738. purity(curr_index).affinity_calculation_type = affinity_calculation_type;
  739. purity(curr_index).addMissingAtt = addMissingAtt; %sigal 8.11.13
  740. purity(curr_index).cluster_only_missing_nodes = cluster_only_missing_nodes;
  741. purity(curr_index).num_clusters_known = num_clusters_known;
  742. purity(curr_index).num_clusters_estimated = k; % sigal 26.11.12
  743. purity(curr_index).num_placeholders = num_placeholders;
  744. purity(curr_index).num_placeholders_to_remove = num_placeholders_to_remove;
  745. purity(curr_index).num_attr_nodes = totalAttNum; % sigal 3.1.13
  746. purity(curr_index).unite_common_friends = unite_common_friends;
  747. purity(curr_index).iteration = 1;
  748. purity(curr_index).test_clustering = test_clustering;
  749. purity(curr_index).true_clustering = true_clustering;
  750. purity(curr_index).graph_size = graph_size;
  751. purity(curr_index).graph_edges = graph_edges; % sigal - number of edges
  752. purity(curr_index).graph_attr_edges = graph_attr_edges; % sigal - number of attributes edges
  753. purity(curr_index).inverse_purity = 99; % Sigal 12.8.12 - tmp ??? % CalculateInversePurity(true_clustering, test_clustering);
  754. purity(curr_index).NMI = 99; %CalcNormalizedMutualInformation(true_clustering, test_clustering);
  755. purity(curr_index).removed_nodes = removed_nodes;
  756. purity(curr_index).percent_known_placeholders = percent_known_placeholders;
  757. purity(curr_index).reduce_dimensions = reduce_dimensions;
  758. purity(curr_index).missing_nodes_mapping = missing_nodes_mapping;
  759. purity(curr_index).compensate_for_unknown_placeholers = compensate_for_unknown_placeholers;
  760. purity(curr_index).affinity_calc_time = affinity_calc_time;
  761. purity(curr_index).reduce_dim_time = reduce_dim_time;
  762. purity(curr_index).graph_predict_time = graph_predict_time;
  763. if withAttr == 1 %% save this time only for this variation
  764. purity(curr_index).att_affinity_calc_time = att_affinity_calc_time; %sigal 14.3.13
  765. purity(curr_index).affinity_calc_time = affinity_calc_time+att_affinity_merge_time; %sigal 14.3.13
  766. elseif withAttr == 2 || withAttr == 4 %% save this time only for this variation
  767. purity(curr_index).att_affinity_calc_time = att_combine_calc_time; %sigal 13.3.13
  768. elseif withAttr == 3 %% sigal 22.1.14
  769. purity(curr_index).att_affinity_calc_time = phs_att_affinity_calc_time;
  770. elseif withAttr == 5 %% sigal 22.1.14
  771. purity(curr_index).att_affinity_calc_time = phs_img_affinity_calc_time;
  772. elseif withAttr == 7 %% sigal 22.1.14
  773. purity(curr_index).att_affinity_calc_time = phs_att_affinity_calc_time+phs_img_affinity_calc_time;
  774. else
  775. purity(curr_index).att_affinity_calc_time = 0; %sigal 12.3.13
  776. end
  777. if compensate_for_unknown_placeholers == 0
  778. break
  779. end
  780. end %linksToAdd
  781. %
  782. % purity(unite_common_friends+1, num_missing_nodes_idx, affinity_calculation_type+1, cluster_only_missing_nodes+1) = ...
  783. % purity(unite_common_friends+1, num_missing_nodes_idx, affinity_calculation_type+1, cluster_only_missing_nodes+1) + temp_purity;
  784. %
  785. % purity_sq(unite_common_friends+1, num_missing_nodes_idx, affinity_calculation_type+1, cluster_only_missing_nodes+1) = ...
  786. % purity_sq(unite_common_friends+1, num_missing_nodes_idx, affinity_calculation_type+1, cluster_only_missing_nodes+1) + temp_purity^2;
  787. %
  788. LogMsg(sprintf('S8b: Size=%d,Miss=%d,PHs=%d,Affinity=%d,Att=%d,Purity=%.3f', ...
  789. graph_size,purity(curr_index).num_missing_nodes,num_placeholders,affinity_calculation_type,withAttrWeight,temp_purity));
  790. %fprintf('affinity_calculation_type = %d, unite_common_friends = %d\n', affinity_calculation_type, unite_common_friends);
  791. fprintf('Graph size: %d, Number of missing nodes: %d, Purity: %f \n' ,graph_size, num_missing_nodes, temp_purity);
  792. %fprintf('============================================\n\n\n');
  793. %clear U;
  794. clear eigValues;
  795. clear eigVectors;
  796. end %kmeanTypes (clustering types)
  797. end %num_clusters_known
  798. end %reduce_dimensions
  799. clear('affinity');
  800. clear('phsAffinity');
  801. end % run loop for attWeight
  802. end % run over - once as original without attributes and next with attriutes/images
  803. clear('netAffinity');
  804. clear('phsNetAffinity');
  805. end % loop over different affinity_types
  806. clear('attAffinity');
  807. clear('phsAttAffinity');
  808. clear('phsAttAffinity2');
  809. end %loop over percent_known_placeholders_vec
  810. end %loop over addMissingAtt
  811. end %loop over num_missing_nodes...
  812. end %main function
  813. % sigal - 29.10.13
  814. % calc only PHs affinity
  815. function [affinity] = CalcPHsAffinity( data, affType, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, addMissingAtt)
  816. global affinity_calculation_shortest_path;
  817. global affinity_calculation_euclid;
  818. global affinity_calculation_common_friends;
  819. global affinity_calculation_random_clustering;
  820. global affinity_calculation_adamic_adar;
  821. global affinity_calculation_katz_beta_0_5;
  822. global affinity_calculation_katz_beta_0_05;
  823. global affinity_calculation_katz_beta_0_005;
  824. global affinity_calculation_AA_RCN;
  825. global netAffNormFactor1;
  826. global netAffNormFactor2;
  827. firstPH = actual_graph_size-num_missing_nodes+1;
  828. normAttWeight = attWeight / netAffNormFactor2; % only for SAMI-N
  829. if affType == affinity_calculation_euclid
  830. LogMsg(sprintf('*** ERROR: MissingNodes_S8b:CalcPHsAffinity - affType %d not supported !!!',affType));
  831. return;
  832. elseif affType == affinity_calculation_shortest_path
  833. LogMsg(sprintf('*** ERROR: MissingNodes_S8b:CalcPHsAffinity - affType %d not supported !!!',affType));
  834. return;
  835. elseif affType == affinity_calculation_common_friends
  836. affinity = CalcPHsAffinityByRCN(data, actual_graph_size, num_missing_nodes, num_attr_nodes, normAttWeight, addMissingAtt);
  837. elseif affType == affinity_calculation_random_clustering
  838. affinity = data(firstPH:end, firstPH:end); %just a placeholder...
  839. elseif affType == affinity_calculation_adamic_adar
  840. affinity = CalcPHsAffinityByAA( data, actual_graph_size, num_missing_nodes, 1, num_attr_nodes, normAttWeight, addMissingAtt);
  841. elseif affType == affinity_calculation_katz_beta_0_5
  842. affinity = CalcPHsAffinityByKatzBeta( data, 0.5, 3, firstPH );
  843. elseif affType == affinity_calculation_katz_beta_0_05
  844. affinity = CalcPHsAffinityByKatzBeta( data, 0.05, 4, firstPH );
  845. elseif affType == affinity_calculation_katz_beta_0_005
  846. affinity = CalcPHsAffinityByKatzBeta( data, 0.005, 4, firstPH );
  847. elseif affType == affinity_calculation_AA_RCN
  848. affinity = CalcPHsAffinity( data, affinity_calculation_adamic_adar, actual_graph_size, num_missing_nodes, num_attr_nodes, normAttWeight, addMissingAtt);
  849. affinity2 = CalcPHsAffinity( data, affinity_calculation_common_friends, actual_graph_size, num_missing_nodes, num_attr_nodes, normAttWeight, addMissingAtt);
  850. affinity = [affinity2 affinity];
  851. end
  852. %sigal 14.11.13
  853. affinity = affinity * netAffNormFactor1;
  854. end %main function
  855. %sigal - adjust to withAttr flag TODO
  856. function [affinity] = CalcAffinity( data, affinity_calculation_type, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, addMissingAtt)
  857. global affinity_calculation_shortest_path;
  858. global affinity_calculation_euclid;
  859. global affinity_calculation_common_friends;
  860. global affinity_calculation_random_clustering;
  861. global affinity_calculation_adamic_adar;
  862. global affinity_calculation_katz_beta_0_5;
  863. global affinity_calculation_katz_beta_0_05;
  864. global affinity_calculation_katz_beta_0_005;
  865. global affinity_calculation_AA_RCN;
  866. global netAffNormFactor1;
  867. % sigal 11.2.14 - backward compitbility with ASONAM 13
  868. addMissingAtt = 0;
  869. if affinity_calculation_type == affinity_calculation_euclid
  870. sp_mat = graphallshortestpaths(data);
  871. %remove INF values
  872. max_value = max(sp_mat(sp_mat ~= Inf)) + 1;
  873. sp_mat_euclid = sp_mat;
  874. sp_mat_euclid(sp_mat == Inf) = max_value;
  875. affinity = CalculateAffinity(sp_mat_euclid);
  876. %affinity = exp(-(sp_mat.^2))/(2 * 0.3^2);
  877. elseif affinity_calculation_type == affinity_calculation_shortest_path
  878. % max_value = max(sp_mat(sp_mat ~= Inf)) + 1;
  879. % sp_mat_euclid = sp_mat;
  880. % sp_mat_euclid(sp_mat == Inf) = max_value;
  881. % affinity = (sp_mat_euclid + 1).^(-affinity_exp_factor);
  882. %affinity = spfun(affinityFunc, data);
  883. affinity = graphallshortestpaths(data);
  884. affinity = affinity .^ -2;
  885. affinity(affinity == Inf) = 1; %added on 05/11/11
  886. elseif affinity_calculation_type == affinity_calculation_common_friends
  887. affinity = CalcAffinityByCommonNeighbors_Sparse(data, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, addMissingAtt);
  888. %affinity = CalcAffinityByCommonNeighbors(data, actual_graph_size, num_missing_nodes);
  889. elseif affinity_calculation_type == affinity_calculation_random_clustering
  890. affinity = data; %just a placeholder...
  891. elseif affinity_calculation_type == affinity_calculation_adamic_adar
  892. affinity = CalculateAffinityByAdamicAdar_S3o( data, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, 1 , addMissingAtt);
  893. %%affinity2 = CalculateAffinityByAdamicAdar_S2( data, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, 1 , addMissingAtt);
  894. if nnz(affinity) < 5
  895. x = 8;
  896. end
  897. % diff = affinity2-affinity;
  898. % if nnz(diff) > 0
  899. % LogMsg(sprintf('*** WARNING: affinityAA - mismatch (nnz=%d)',nnz(diff)));
  900. % zz = 999;
  901. % end
  902. elseif affinity_calculation_type == affinity_calculation_katz_beta_0_5
  903. affinity = CalcAffinityByKatzBeta_Sparse( data, 0.5, 3, num_attr_nodes );
  904. elseif affinity_calculation_type == affinity_calculation_katz_beta_0_05
  905. affinity = CalcAffinityByKatzBeta_Sparse( data, 0.05, 4, num_attr_nodes );
  906. elseif affinity_calculation_type == affinity_calculation_katz_beta_0_005
  907. affinity = CalcAffinityByKatzBeta_Sparse( data, 0.005, 4, num_attr_nodes );
  908. elseif affinity_calculation_type == affinity_calculation_AA_RCN
  909. w2 = 0.5;
  910. affinity = CalcAffinity( data, affinity_calculation_adamic_adar, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, addMissingAtt);
  911. affinity2 = CalcAffinity( data, affinity_calculation_common_friends, actual_graph_size, num_missing_nodes, num_attr_nodes, attWeight, addMissingAtt);
  912. affinity = WeightedSum(affinity, affinity2, w2, size(affinity,1));
  913. end
  914. %sigal 22.11.13
  915. %affinity = affinity * 10; %%netAffNormFactor1;
  916. end % function CalcAffinity
  917. %sigal - review code and messages TODO
  918. function [test_clustering] = SpectralClustering(affinity, k, num_placeholders, affinityType, cluster_only_missing_nodes)
  919. fprintf('kmeans clustering type=0 (SP)\n');
  920. first_unk_node = size(affinity,1) - num_placeholders + 1;
  921. diagonal = sum(affinity, 2); %sum the rows
  922. D = sparse(diag(diagonal)); %D is the matrix whose diagonal is the sum of the rows of A
  923. clear('diagonal');
  924. fprintf('calculating NL\n');
  925. D = sqrt(D);
  926. NL1 = D * affinity * D;
  927. clear('D');
  928. fprintf('calculating U - eigs\n');
  929. fail = 0;
  930. try
  931. [nEigVec,eigValues] = eigs(NL1,k);
  932. catch ME1 % variable that get the exception
  933. opts.tol = 1e-1;
  934. try
  935. fprintf('calculating U - 2nd try\n');
  936. [nEigVec,eigValues] = eigs(NL1,k, 'LM', opts);
  937. catch ME2
  938. fail = 1;
  939. end
  940. end
  941. % select k largest eigen vectors
  942. if fail == 0
  943. U = [];
  944. % construct the normalized matrix U from the obtained eigen vectors
  945. fprintf('calculating U - construct\n');
  946. for i=1:size(nEigVec,1)
  947. n = sqrt(sum(nEigVec(i,:).^2));
  948. U(i,:) = nEigVec(i,:) ./ n;
  949. end
  950. num_samples = size(affinity,1) - first_unk_node + 1;
  951. if cluster_only_missing_nodes == 1
  952. U(1:first_unk_node - 1 ,:) = []; %cluster only the missing nodes
  953. end
  954. fprintf('SC: run kmeans clustering\n');
  955. % perform kmeans clustering on the matrix U
  956. test_clustering = calcKMean(U, k, num_samples, affinityType);
  957. else %fail == 0
  958. disp('Failed in finding eigenvectors - using random!');
  959. if cluster_only_missing_nodes == 0
  960. num_samples = size(affinity,1);
  961. else
  962. num_samples = num_placeholders;
  963. end
  964. test_clustering = randi(k, num_samples, 1);
  965. end
  966. end % function SpectralClustering
  967. % Sigal 29.7.13
  968. % add option for clustering with Kmean intead of SP
  969. % options: kmean_type 0=SP, 3=kmean on PH (mxm), 2=Kmean on PH+Nodes (m*(m+n))
  970. % 1=kmean on already cut affinity
  971. function [test_clustering] = KMeanClustering(affinity, k, num_placeholders, affinityType, kmean_type)
  972. first_unk_node = size(affinity,1) - num_placeholders + 1;
  973. num_samples = num_placeholders;
  974. if kmean_type == 1
  975. U = affinity;
  976. elseif kmean_type == 3 % previous kmean_type == 1
  977. U(1:num_placeholders,1:num_placeholders) = affinity(first_unk_node:end,first_unk_node:end);
  978. else
  979. U(1:num_placeholders,:) = affinity(first_unk_node:end,:);
  980. end
  981. fprintf('kmeans clustering type=%d\n',kmean_type);
  982. % perform kmeans clustering on the matrix U
  983. test_clustering = calcKMean(U, k, num_samples, affinityType);
  984. end % function SpectralClustering
  985. % Sigal 29.10.13
  986. % perform kmeans clustering on the matrix U
  987. % use same method for both KMeanClustering and SpectralClustering
  988. function [test_clustering] = calcKMean(U, num_clusters, num_samples, affinityType)
  989. global affinity_calculation_random_clustering;
  990. if num_clusters > 99
  991. numReplicates = 1;
  992. else
  993. numReplicates = 3;
  994. end
  995. fprintf('calcKMean\n');
  996. % perform kmeans clustering on the matrix U
  997. fail = 1;
  998. while fail > 0
  999. try
  1000. currK = num_clusters;
  1001. % OPT: 'EmptyAction','singleton' - in case of an empty cluster just drop it
  1002. % OPT: 'Replicates',3 - repeat run/start points
  1003. [IDX,C, SUMD, D] = kmeans(U,currK,'EmptyAction','singleton','Replicates',numReplicates);
  1004. fail = 0;
  1005. catch ME1
  1006. fail = fail + 1;
  1007. if fail < 100
  1008. %disp('error in kmeans clustering. trying again...');
  1009. else
  1010. %give up on clustering and select random clusters...
  1011. IDX = randi(currK, size(U));
  1012. fail = 0;
  1013. end
  1014. end
  1015. end
  1016. test_clustering = IDX(size(IDX,1) - num_samples + 1 : size(IDX,1));
  1017. %if it's random just replace everything...
  1018. if affinityType == affinity_calculation_random_clustering
  1019. test_clustering = randi(num_clusters, size(test_clustering,1), size(test_clustering,2));
  1020. end
  1021. end %function KMeanClustering
  1022. % sigal - adjust to withAttr flag TOCHECK - which data to use?
  1023. % Sigal 29.7.13
  1024. % add option for clustering with Kmean intead of SP
  1025. % original implementation with SP, i.e use kmean_type = 0
  1026. % k is the number of return clusters
  1027. function [newData, test_clustering] = PredictGraph(affinity, k, data, num_placeholders, affinity_calculation_type, cluster_only_missing_nodes, kmean_type)
  1028. % sigal - backwards compatibility
  1029. if nargin < 7
  1030. kmean_type = 0;
  1031. end
  1032. last_known_node = size(data,1) - num_placeholders;
  1033. %%first_unk_node = last_known_node + 1; % Sigal 15.10.13 remove unuse warning
  1034. if kmean_type == 0
  1035. [test_clustering] = SpectralClustering(affinity, k, num_placeholders, affinity_calculation_type, cluster_only_missing_nodes);
  1036. else
  1037. [test_clustering] = KMeanClustering(affinity, k, num_placeholders, affinity_calculation_type, kmean_type);
  1038. end
  1039. %sigal - what if #clusters diffrent than #missing ???
  1040. newNodes = CreateNewNodesFromClusters(data, test_clustering);
  1041. %sigal - ... means continue command at next line
  1042. newData = [data(1:last_known_node,1:last_known_node), newNodes(:, 1:last_known_node)';...
  1043. newNodes(:,1:last_known_node), zeros(size(newNodes,1))];
  1044. end % function PredictGraph
  1045. %sigal - estimation can be wrong ???
  1046. %sigal - adjust to withAttr flag TODO
  1047. function [k] = DetermineNumberOfClusters(num_clusters_known, data_untouched, actual_graph_size, num_missing_nodes, num_added_nodes)
  1048. %determine k - the number of clusters
  1049. if num_clusters_known == 1
  1050. k = num_missing_nodes;
  1051. else
  1052. numKnownNodes = actual_graph_size - num_missing_nodes;
  1053. sumKnownEdges = sum(sum(data_untouched(1 : numKnownNodes, 1 : numKnownNodes)));
  1054. meanKnownEdges = sumKnownEdges/numKnownNodes;
  1055. addedEdges = num_added_nodes*2; % undirect graph
  1056. fprintf('EstimatedK: numKnownN=%d, meanKnownE=%.3f, addedE=%d, missN=%d, meanMissE=%.3f\n', ...
  1057. numKnownNodes,full(meanKnownEdges),num_added_nodes,num_missing_nodes,addedEdges/num_missing_nodes);
  1058. if num_clusters_known == 0
  1059. %k = round(num_added_nodes / meanKnownEdges);
  1060. k = round(num_added_nodes / floor(meanKnownEdges));
  1061. %fprintf('EstimatedK: type=%d, actual=%d, rounding k to %d\n',num_clusters_known, num_missing_nodes, k);
  1062. elseif num_clusters_known == 2 %guessing upper limit
  1063. k = 2*round(num_added_nodes / meanKnownEdges);
  1064. %fprintf('EstimatedK: type=%d, actual=%d, guessing upper limit %d\n',num_clusters_known, num_missing_nodes, k);
  1065. elseif num_clusters_known == 3 % e=a*n
  1066. a = meanKnownEdges;
  1067. e = sumKnownEdges+num_added_nodes;
  1068. k = round(e/a-numKnownNodes);
  1069. %fprintf('EstimatedK: type=%d, actual=%d, rounding k to %d\n',num_clusters_known, num_missing_nodes, k);
  1070. elseif num_clusters_known == 4 % e=a*n^2
  1071. a = meanKnownEdges/numKnownNodes;
  1072. e = sumKnownEdges+addedEdges;
  1073. k = round(sqrt(e/a)-numKnownNodes);
  1074. %fprintf('EstimatedK: type=%d, actual=%d, rounding k to %d\n',num_clusters_known, num_missing_nodes, k);
  1075. elseif num_clusters_known == 5 % e=a*n^2
  1076. a = meanKnownEdges/numKnownNodes;
  1077. e = sumKnownEdges+addedEdges;
  1078. k = ceil(sqrt(e/a)-numKnownNodes);
  1079. %fprintf('EstimatedK: type=%d, actual=%d, rounding k to %d\n',num_clusters_known, num_missing_nodes, k);
  1080. elseif num_clusters_known == 6 % e=a*n
  1081. a = meanKnownEdges;
  1082. e = sumKnownEdges+num_added_nodes;
  1083. k = ceil(e/a-numKnownNodes);
  1084. elseif num_clusters_known == 7
  1085. k = ceil(num_added_nodes / meanKnownEdges);
  1086. elseif num_clusters_known == 8
  1087. k = round(num_added_nodes / meanKnownEdges);
  1088. end
  1089. LogMsg(sprintf('EstimatedK(size,PHs,type,actual,k):\t%d\t%d\t%d\t%d\t%d', ...
  1090. actual_graph_size,num_added_nodes,num_clusters_known, num_missing_nodes, k),'EstimateK_Log2.txt');
  1091. end
  1092. end % function DetermineNumberOfClusters
  1093. %find nodes with some affinity to one or more missing node
  1094. function [nodes_to_keep] = NodesToKeep(affinity, first_unk_node, includePHs)
  1095. affinity_sum = sum(affinity(first_unk_node:size(affinity,1),:)); %the sum of the affinity of placeholders to all other nodes
  1096. nodes_to_keep = (affinity_sum > 0); %keep only nodes which have some affinity to the placeholders
  1097. if includePHs == 1
  1098. nodes_to_keep(first_unk_node:size(affinity,1)) = 1; %keep all the placeholders even if for some reason they have a sum of zero...
  1099. end
  1100. end % function NodesToKeep
  1101. %keep only missing node rows and their friends
  1102. function [affinity, num_placeholders, first_unk_node] = ReduceDimensions(affinity, first_unk_node)
  1103. num_placeholders = size(affinity,1) - first_unk_node + 1;
  1104. %keep only nodes which have some affinity to the placeholders and all of the placeholders
  1105. nodes_to_keep = NodesToKeep(affinity, first_unk_node, 1);
  1106. affinity = affinity(nodes_to_keep, nodes_to_keep);
  1107. first_unk_node = size(affinity,1) - num_placeholders + 1;
  1108. end % function ReduceDimensions
  1109. %return the true clustering accoring to the savd missing_nodes_mapping
  1110. function [true_clustering] = BuildTrueClustering(missing_nodes_mapping, actual_graph_size, num_missing_nodes, percent_known_placeholders, placeholders_to_remove, last_known_node)
  1111. %sigal 25.11.12 - count nonzero cell (beside first raw) - i.e. number of placeholder
  1112. numMapping = 0;
  1113. %sigal 23.1.14 - start form thrid row (first row original id, second row images profile)
  1114. for i = 3 : size(missing_nodes_mapping, 1)
  1115. nz=find(missing_nodes_mapping(i,:));
  1116. numMapping = numMapping + size(nz,2);
  1117. end
  1118. true_clustering = zeros(numMapping,1);
  1119. %sigal 25.11.12
  1120. %true_clustering = []; %zeros(size(test_clustering, 1), 1);
  1121. for i = 3 : size(missing_nodes_mapping, 1)
  1122. for j = 1 : size(missing_nodes_mapping,2)
  1123. if missing_nodes_mapping(i,j) ~= 0
  1124. true_clustering(missing_nodes_mapping(i,j) - actual_graph_size + num_missing_nodes, 1) = j; % missing_nodes_mapping(1, j);
  1125. end
  1126. end
  1127. end
  1128. %sigal - adjust to withAttr flag TODO
  1129. if percent_known_placeholders < 1
  1130. true_clustering(placeholders_to_remove - last_known_node) = [];
  1131. end
  1132. end % function BuildTrueClustering
  1133. function saveSmallData(dumpSmallDataPath, dataFileName, iter, affinity_type, withAttr, missNodes, small_data, i)
  1134. Sigal 24.1.13 - TODO
  1135. outFile = sprintf('%s_%d_%d_%d_%d_small_data_%d', dataFileName, iter, missNodes, affinity_type, withAttr, i);
  1136. if affinity_type == 9 % save instead a dummy size (1) and the best_alg
  1137. SaveIntMatrixToFile(strcat(dumpSmallDataPath, outFile,'_edges.txt'), small_data, 1);
  1138. else
  1139. SaveAsciiGraph(dumpSmallDataPath, outFile, small_data, 1); %% also save graph size
  1140. end
  1141. end % function saveSmallData
  1142. function [best_clustering, best_alg] = ChooseBestResults(clusteringResults, clusteringAlg, type)
  1143. global affinity_boost;
  1144. global affinity_boost2;
  1145. if type == affinity_boost
  1146. best_clustering_inx = ChooseBestResults1(clusteringResults);
  1147. elseif type == affinity_boost2
  1148. best_clustering_inx = ChooseBestResults2(clusteringResults, clusteringAlg);
  1149. else
  1150. fprintf('*** ERROR: ChooseBestResults: invalid tye %d\n', type);
  1151. end
  1152. best_clustering = clusteringResults(:,best_clustering_inx);
  1153. best_alg = clusteringAlg(best_clustering_inx);
  1154. end % function ChooseBestResults
  1155. function [best_clustering_inx] = ChooseBestResults1(clusteringResults, indices)
  1156. numResults = size(clusteringResults,2);
  1157. if nargin < 2
  1158. indices = ones(1,numResults); % i.e. all
  1159. end
  1160. sumPurity = CalcSumPurity(clusteringResults, indices);
  1161. % return max entry
  1162. [val, inx] = max(sumPurity);
  1163. fprintf('ChooseBestResults: val %d, inx %d\n', val, inx);
  1164. best_clustering_inx = inx;
  1165. end % function ChooseBestResults
  1166. function [best_clustering_inx] = ChooseBestResults2(clusteringResults, clusteringAlg)
  1167. max_num_level_2 = 10;
  1168. last_level_2 = 1;
  1169. numResults = size(clusteringResults,2);
  1170. indices_level_1 = zeros(1,numResults);
  1171. indices_level_2 = zeros(max_num_level_2,numResults);
  1172. alg_level_2 = zeros(1,max_num_level_2);
  1173. for i=1:numResults
  1174. base_alg = floor(clusteringAlg(i)/10);
  1175. %base_att = base_alg-10*floor(base_alg/10);
  1176. var_alg = clusteringAlg(i)-base_alg*10;
  1177. if var_alg == 0 || var_alg == 0
  1178. indices_level_1(i) = 1;
  1179. else
  1180. found = 0;
  1181. for j=1:last_level_2-1
  1182. if alg_level_2(j)==base_alg
  1183. l2 = j;
  1184. found = 1;
  1185. break;
  1186. end
  1187. end
  1188. if found == 0
  1189. l2 = last_level_2;
  1190. alg_level_2(l2)=base_alg;
  1191. last_level_2 = l2+1;
  1192. end
  1193. indices_level_2(l2,i) = 1;
  1194. end
  1195. end
  1196. for j=1:last_level_2-1
  1197. best = ChooseBestResults1(clusteringResults, indices_level_2(j,:));
  1198. indices_level_1(best) = 1;
  1199. end
  1200. best_clustering_inx = ChooseBestResults1(clusteringResults, indices_level_1);
  1201. end % function ChooseBestResults
  1202. function [sumPurity] = CalcSumPurity(clusteringResults, indices)
  1203. numResults = size(clusteringResults,2);
  1204. crossPurity = zeros(numResults,numResults);
  1205. for i=1:numResults
  1206. for j=1:numResults
  1207. if i~=j && indices(i)==1 && indices(j)==1
  1208. crossPurity(i,j) = ClusteringPurity(clusteringResults(:,j), clusteringResults(:,i));
  1209. end
  1210. end
  1211. end
  1212. sumPurity = sum(crossPurity,2);
  1213. end % function CalcSumPurity