NetAnalyzer 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/NetAnalyzer.gemspec +2 -1
- data/Rakefile +10 -3
- data/bin/NetAnalyzer.rb +5 -30
- data/lib/NetAnalyzer/network.rb +86 -53
- data/lib/NetAnalyzer/version.rb +1 -1
- data/old_spec/NetAnalyzer_spec.rb +11 -0
- data/old_spec/spec_helper.rb +2 -0
- metadata +20 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c09e22b1a1867c0ab7c8f8a07214d05d68b3411f
|
4
|
+
data.tar.gz: 3343dd6ae5b60ba7916089118e8e7079db022b2b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2d887cb3d500aa68f45f880f5e25405e186f7658f851c7a9c1a3124ea79263b905671fa244dfbaf6c0c5e8dd13c084af7762493e2b9b02ecb1be08b6ef0b01e
|
7
|
+
data.tar.gz: 23958924d092afdfe317a8ba87b6ea4578e74794ce311ef4549cd0a74e88f8dbe0dd60fcf8dc9179ac591652c9254f615f46965ae1c5b98ba5f00e67761b3773
|
data/NetAnalyzer.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "NetAnalyzer"
|
8
8
|
spec.version = NetAnalyzer::VERSION
|
9
9
|
spec.authors = ["Elena Rojano, Pedro Seoane"]
|
10
|
-
spec.email = ["elenarojano@uma.es, seoanezonjic@
|
10
|
+
spec.email = ["elenarojano@uma.es, seoanezonjic@hotmail.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{Network analysis tool that calculate and validate different association indices.}
|
13
13
|
spec.description = %q{NetAnalyzer is a useful network analysis tool developed in Ruby that can 1) analyse any type of unweighted network, regardless of the number of layers, 2) calculate the relationship between different layers, using various association indices (Jaccard, Simpson, PCC, geometric, cosine and hypergeometric) and 3) validate the results}
|
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "rspec", "~> 3.0"
|
25
25
|
spec.add_dependency "nmatrix"
|
26
26
|
spec.add_dependency "bigdecimal"
|
27
|
+
spec.add_dependency "benchmark"
|
27
28
|
end
|
data/Rakefile
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
-
require "rspec/core/rake_task"
|
2
|
+
#require "rspec/core/rake_task"
|
3
3
|
|
4
|
-
RSpec::Core::RakeTask.new(:spec)
|
4
|
+
#RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
|
-
task :default => :spec
|
6
|
+
#task :default => :spec
|
7
|
+
|
8
|
+
require 'rake/testtask'
|
9
|
+
|
10
|
+
Rake::TestTask.new do |t|
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = "test/*_test.rb"
|
13
|
+
end
|
data/bin/NetAnalyzer.rb
CHANGED
@@ -2,29 +2,11 @@
|
|
2
2
|
|
3
3
|
ROOT_PATH = File.dirname(__FILE__)
|
4
4
|
$: << File.expand_path(File.join(ROOT_PATH, '..', 'lib', 'NetAnalyzer'))
|
5
|
+
$: << File.expand_path(File.join(ROOT_PATH, '..', 'lib', 'NetAnalyzer', 'methods'))
|
5
6
|
|
6
7
|
require 'network'
|
7
8
|
require 'optparse'
|
8
9
|
|
9
|
-
##############################
|
10
|
-
# MAIN METHODS
|
11
|
-
##############################
|
12
|
-
|
13
|
-
def set_layer(layer_definitions, node_name)
|
14
|
-
layer = nil
|
15
|
-
if layer_definitions.length > 1
|
16
|
-
layer_definitions.each do |layer_name, regexp|
|
17
|
-
if node_name =~ regexp
|
18
|
-
layer = layer_name
|
19
|
-
break
|
20
|
-
end
|
21
|
-
end
|
22
|
-
else
|
23
|
-
layer = layer_definitions.first.first
|
24
|
-
end
|
25
|
-
return layer
|
26
|
-
end
|
27
|
-
|
28
10
|
##############################
|
29
11
|
#OPTPARSE
|
30
12
|
##############################
|
@@ -97,18 +79,11 @@ end.parse!
|
|
97
79
|
##########################
|
98
80
|
|
99
81
|
fullNet = Network.new(options[:layers].map{|layer| layer.first})
|
82
|
+
#puts options[:layers].map{|layer| layer.first}.inspect
|
100
83
|
puts "Loading network data"
|
101
|
-
|
102
|
-
line.chomp!
|
103
|
-
pair = line.split(options[:splitChar])
|
104
|
-
node1 = pair[0]
|
105
|
-
node2 = pair[1]
|
106
|
-
fullNet.add_node(node1, set_layer(options[:layers], node1))
|
107
|
-
fullNet.add_node(node2, set_layer(options[:layers], node2))
|
108
|
-
fullNet.add_edge(node1, node2)
|
109
|
-
end
|
110
|
-
#fullNet.plot(options[:output_file], options[:output_style])
|
84
|
+
fullNet.load_network_by_pairs(options[:input_file], options[:layers], options[:splitChar])
|
111
85
|
|
86
|
+
#fullNet.plot(options[:output_file], options[:output_style])
|
112
87
|
|
113
88
|
if !options[:meth].nil?
|
114
89
|
puts "Performing association method #{options[:meth]} on network"
|
@@ -121,7 +96,7 @@ if !options[:meth].nil?
|
|
121
96
|
:transference)
|
122
97
|
else
|
123
98
|
fullNet.get_association_values(
|
124
|
-
options[:use_layers][0],
|
99
|
+
options[:use_layers][0],
|
125
100
|
options[:use_layers][1].first,
|
126
101
|
options[:meth])
|
127
102
|
end
|
data/lib/NetAnalyzer/network.rb
CHANGED
@@ -2,9 +2,11 @@ require 'nodes'
|
|
2
2
|
require 'nmatrix'
|
3
3
|
require 'pp'
|
4
4
|
require 'bigdecimal'
|
5
|
+
require 'benchmark'
|
5
6
|
|
6
7
|
class Network
|
7
|
-
|
8
|
+
|
9
|
+
attr_accessor :association_values, :control_connections
|
8
10
|
|
9
11
|
## BASIC METHODS
|
10
12
|
############################################################
|
@@ -16,7 +18,7 @@ class Network
|
|
16
18
|
@association_values = {}
|
17
19
|
@control_connections = {}
|
18
20
|
end
|
19
|
-
|
21
|
+
|
20
22
|
def add_node(nodeID, nodeType = 0)
|
21
23
|
@nodes[nodeID] = Node.new(nodeID, nodeType)
|
22
24
|
end
|
@@ -35,6 +37,23 @@ class Network
|
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
40
|
+
def load_network_by_pairs(file, layers, split_character="\t")
|
41
|
+
File.open(file).each("\n") do |line|
|
42
|
+
line.chomp!
|
43
|
+
pair = line.split(split_character)
|
44
|
+
node1 = pair[0]
|
45
|
+
node2 = pair[1]
|
46
|
+
add_node(node1, set_layer(layers, node1))
|
47
|
+
add_node(node2, set_layer(layers, node2))
|
48
|
+
add_edge(node1, node2)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_edge_number
|
53
|
+
node_connections = @edges.values.map{|connections| connections.length}.inject(0){|sum, n| sum + n}
|
54
|
+
return node_connections/2
|
55
|
+
end
|
56
|
+
|
38
57
|
def plot(output_filename, layout="dot")
|
39
58
|
roboWrite = File.open(output_filename, 'w')
|
40
59
|
roboWrite.puts "digraph g {"
|
@@ -227,7 +246,7 @@ class Network
|
|
227
246
|
|
228
247
|
def get_pcc_associations(layers, base_layer)
|
229
248
|
#for Ny calcule use get_nodes_layer
|
230
|
-
ny = get_nodes_layer(
|
249
|
+
ny = get_nodes_layer([base_layer]).length
|
231
250
|
relations = get_associations(layers, base_layer) do |associatedIDs_node1, associatedIDs_node2, intersectedIDs, node1, node2|
|
232
251
|
intersProd = intersectedIDs.length * ny
|
233
252
|
nodesProd = associatedIDs_node1.length * associatedIDs_node2.length
|
@@ -241,25 +260,20 @@ class Network
|
|
241
260
|
end
|
242
261
|
|
243
262
|
def get_hypergeometric_associations(layers, base_layer)
|
244
|
-
ny = get_nodes_layer(
|
263
|
+
ny = get_nodes_layer([base_layer]).length
|
245
264
|
relations = get_associations(layers, base_layer) do |associatedIDs_node1, associatedIDs_node2, intersectedIDs, node1, node2|
|
246
265
|
minLength = [associatedIDs_node1.length, associatedIDs_node2.length].min
|
247
266
|
intersection_lengths = intersectedIDs.length
|
248
267
|
sum = 0
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
# binom_product_float = BigDecimal.new(binom_product)
|
259
|
-
# to_f = true
|
260
|
-
# end
|
261
|
-
# sum += binom_product_float / binom(ny, nB)
|
262
|
-
# sum = sum.to_f if to_f # once the operation has finished, sum is corced from bigdecimal to float
|
268
|
+
if intersection_lengths > 0
|
269
|
+
nA = associatedIDs_node1.length
|
270
|
+
nB = associatedIDs_node2.length
|
271
|
+
#Using index from A layer proyected to B
|
272
|
+
hyper_denom = binom(ny, nB)
|
273
|
+
(intersection_lengths..minLength).each do |i|
|
274
|
+
binom_product = binom(nA, i) * binom(ny - nA, nB - i)
|
275
|
+
sum += binom_product.fdiv(hyper_denom)
|
276
|
+
end
|
263
277
|
end
|
264
278
|
if sum == 0
|
265
279
|
hypergeometricValue = 0
|
@@ -272,52 +286,56 @@ class Network
|
|
272
286
|
return relations
|
273
287
|
end
|
274
288
|
|
275
|
-
def add_record(hash,
|
276
|
-
query = hash[
|
289
|
+
def add_record(hash, node1, node2)
|
290
|
+
query = hash[node1]
|
277
291
|
if query.nil?
|
278
|
-
hash[
|
292
|
+
hash[node1] = [node2]
|
279
293
|
else
|
280
|
-
query
|
294
|
+
query << node2
|
281
295
|
end
|
282
296
|
end
|
283
297
|
|
298
|
+
def add_nested_record(hash, node1, node2, val)
|
299
|
+
query_node1 = hash[node1]
|
300
|
+
if query_node1.nil?
|
301
|
+
hash[node1] = {node2 => val}
|
302
|
+
else
|
303
|
+
query_node1[node2] = val
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
|
284
308
|
def get_csi_associations(layers, base_layer)
|
285
309
|
pcc_relations = get_pcc_associations(layers, base_layer)
|
286
|
-
|
310
|
+
clean_autorelations_on_association_values if layers.length > 1
|
311
|
+
nx = get_nodes_layer(layers).length
|
312
|
+
pcc_vals = {}
|
313
|
+
node_rels = {}
|
287
314
|
pcc_relations.each do |node1, node2, assoc_index|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
315
|
+
add_nested_record(pcc_vals, node1, node2, assoc_index.abs)
|
316
|
+
add_nested_record(pcc_vals, node2, node1, assoc_index.abs)
|
317
|
+
add_record(node_rels, node1, node2)
|
318
|
+
add_record(node_rels, node2, node1)
|
292
319
|
end
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
else
|
300
|
-
nested_query = query[node2]
|
301
|
-
if nested_query.nil?
|
302
|
-
pccAB = -0.05
|
303
|
-
else
|
304
|
-
pccAB = nested_query - 0.05
|
305
|
-
end
|
306
|
-
valid_A_nodes = query.select{|node_id, pcc| pcc>= pccAB}.keys
|
320
|
+
relations = []
|
321
|
+
pcc_relations.each do |node1, node2 ,assoc_index|
|
322
|
+
pccAB = assoc_index - 0.05
|
323
|
+
valid_nodes = 0
|
324
|
+
node_rels[node1].each do |node|
|
325
|
+
valid_nodes += 1 if pcc_vals[node1][node] >= pccAB
|
307
326
|
end
|
308
|
-
|
309
|
-
|
310
|
-
valid_B_nodes = []
|
311
|
-
else
|
312
|
-
valid_B_nodes = query2.select{|node_id, pcc| pcc>= pccAB}.keys
|
327
|
+
node_rels[node2].each do |node|
|
328
|
+
valid_nodes += 1 if pcc_vals[node2][node] >= pccAB
|
313
329
|
end
|
314
|
-
|
315
|
-
|
330
|
+
csiValue = 1 - (valid_nodes-1).fdiv(nx)
|
331
|
+
# valid_nodes-1 is done due to the connection node1-node2 is counted twice (one for each loop)
|
332
|
+
relations << [node1, node2, csiValue]
|
316
333
|
end
|
317
334
|
@association_values[:csi] = relations
|
318
335
|
return relations
|
319
336
|
end
|
320
337
|
|
338
|
+
|
321
339
|
## PERFORMANCE METHODS
|
322
340
|
############################################################
|
323
341
|
def load_control(ref_array)
|
@@ -381,11 +399,11 @@ class Network
|
|
381
399
|
if !pred_info.nil?
|
382
400
|
labels, scores = pred_info
|
383
401
|
reliable_labels = get_reliable_labels(labels, scores, cut, top)
|
384
|
-
|
385
402
|
predicted_labels += reliable_labels.length #m
|
386
403
|
common_labels += (c_labels & reliable_labels).length #k
|
387
404
|
end
|
388
405
|
end
|
406
|
+
#puts "cut: #{cut} trueL: #{true_labels} predL: #{predicted_labels} commL: #{common_labels}"
|
389
407
|
prec = common_labels.to_f/predicted_labels
|
390
408
|
rec = common_labels.to_f/true_labels
|
391
409
|
prec = 0.0 if prec.nan?
|
@@ -399,13 +417,28 @@ class Network
|
|
399
417
|
#######################################################################################
|
400
418
|
private
|
401
419
|
|
420
|
+
def set_layer(layer_definitions, node_name)
|
421
|
+
layer = nil
|
422
|
+
if layer_definitions.length > 1
|
423
|
+
layer_definitions.each do |layer_name, regexp|
|
424
|
+
if node_name =~ regexp
|
425
|
+
layer = layer_name
|
426
|
+
break
|
427
|
+
end
|
428
|
+
end
|
429
|
+
else
|
430
|
+
layer = layer_definitions.first.first
|
431
|
+
end
|
432
|
+
return layer
|
433
|
+
end
|
434
|
+
|
402
435
|
def get_cuts(limits, n_cuts)
|
403
436
|
cuts = []
|
404
|
-
range = (limits.last - limits.first).
|
437
|
+
range = (limits.last - limits.first).abs.fdiv(n_cuts)
|
438
|
+
range = BigDecimal(range, 10)
|
405
439
|
cut = limits.first
|
406
|
-
n_cuts.times do
|
407
|
-
cuts << cut
|
408
|
-
cut += range
|
440
|
+
(n_cuts + 1).times do |n|
|
441
|
+
cuts << (cut + n * range).to_f
|
409
442
|
end
|
410
443
|
return cuts
|
411
444
|
end
|
data/lib/NetAnalyzer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: NetAnalyzer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elena Rojano, Pedro Seoane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,13 +80,27 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: benchmark
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: NetAnalyzer is a useful network analysis tool developed in Ruby that
|
84
98
|
can 1) analyse any type of unweighted network, regardless of the number of layers,
|
85
99
|
2) calculate the relationship between different layers, using various association
|
86
100
|
indices (Jaccard, Simpson, PCC, geometric, cosine and hypergeometric) and 3) validate
|
87
101
|
the results
|
88
102
|
email:
|
89
|
-
- elenarojano@uma.es, seoanezonjic@
|
103
|
+
- elenarojano@uma.es, seoanezonjic@hotmail.com
|
90
104
|
executables:
|
91
105
|
- NetAnalyzer.rb
|
92
106
|
- console
|
@@ -109,6 +123,8 @@ files:
|
|
109
123
|
- lib/NetAnalyzer/network.rb
|
110
124
|
- lib/NetAnalyzer/nodes.rb
|
111
125
|
- lib/NetAnalyzer/version.rb
|
126
|
+
- old_spec/NetAnalyzer_spec.rb
|
127
|
+
- old_spec/spec_helper.rb
|
112
128
|
homepage: https://github.com/ElenaRojano/NetAnalyzer
|
113
129
|
licenses:
|
114
130
|
- MIT
|
@@ -129,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
145
|
version: '0'
|
130
146
|
requirements: []
|
131
147
|
rubyforge_project:
|
132
|
-
rubygems_version: 2.
|
148
|
+
rubygems_version: 2.6.14
|
133
149
|
signing_key:
|
134
150
|
specification_version: 4
|
135
151
|
summary: Network analysis tool that calculate and validate different association indices.
|