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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 412854b58d2f6a2dbb1844cb943a90c9b96f7fd6
4
- data.tar.gz: df275072cb0d1bb9b9d15099b089897471566eb8
3
+ metadata.gz: c09e22b1a1867c0ab7c8f8a07214d05d68b3411f
4
+ data.tar.gz: 3343dd6ae5b60ba7916089118e8e7079db022b2b
5
5
  SHA512:
6
- metadata.gz: a6d3be799d9def07f7addef75dfad5a8d1c6b9d14c684d3dcb227b6be68ef22912ab069beb2e439d07a08b7dc2a6d7d0f38e873a1303a099c3c110c9cf6b075b
7
- data.tar.gz: 561ad012584a397023897047b0e401a96246d39a67082f0c7cfd3ee6dc3cb8075d77d08bb75ae34a8174cbc13e5a8439f0348175f38133162f54ef9e6b55c07c
6
+ metadata.gz: e2d887cb3d500aa68f45f880f5e25405e186f7658f851c7a9c1a3124ea79263b905671fa244dfbaf6c0c5e8dd13c084af7762493e2b9b02ecb1be08b6ef0b01e
7
+ data.tar.gz: 23958924d092afdfe317a8ba87b6ea4578e74794ce311ef4549cd0a74e88f8dbe0dd60fcf8dc9179ac591652c9254f615f46965ae1c5b98ba5f00e67761b3773
@@ -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@uma.es"]
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
@@ -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
- File.open(options[:input_file]).each("\n") do |line|
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
@@ -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
- attr_reader :association_values
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(layers).length
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(layers).length
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
- nA = associatedIDs_node1.length
250
- nB = associatedIDs_node2.length
251
- #Using index from A layer proyected to B
252
- (intersection_lengths..minLength).each do |i|
253
- binom_product = binom(nA, i) * binom(ny - nA, nB - i)
254
- sum += binom_product.fdiv(binom(ny, nB))
255
- # binom_product_float = binom_product.to_f
256
- # to_f = false
257
- # if binom_product_float.infinite? # Handle bignum coercition to bigdecimal to avoid infinity values on float class.
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, key, key2, value)
276
- query = hash[key]
289
+ def add_record(hash, node1, node2)
290
+ query = hash[node1]
277
291
  if query.nil?
278
- hash[key]={key2 => value}
292
+ hash[node1] = [node2]
279
293
  else
280
- query[key2] = value
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
- indexed_pcc_relations = {}
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
- if assoc_index > 0
289
- add_record(indexed_pcc_relations, node1, node2, assoc_index)
290
- add_record(indexed_pcc_relations, node2, node1, assoc_index)
291
- end
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
- ny = get_nodes_layer(layers).length
294
- relations = get_associations(layers, base_layer) do |associatedIDs_node1, associatedIDs_node2, intersectedIDs, node1, node2|
295
- query = indexed_pcc_relations[node1]
296
- if query.nil?
297
- valid_A_nodes = []
298
- pccAB = -0.05
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
- query2 = indexed_pcc_relations[node2]
309
- if query2.nil?
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
- valid_connections = valid_A_nodes | valid_B_nodes
315
- csiValue = 1 - valid_connections.length.to_f/ny
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).to_f/n_cuts
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
@@ -1,3 +1,3 @@
1
1
  module NetAnalyzer
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe NetAnalyzer do
4
+ it 'has a version number' do
5
+ expect(NetAnalyzer::VERSION).not_to be nil
6
+ end
7
+
8
+ it 'does something useful' do
9
+ expect(false).to eq(true)
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'NetAnalyzer'
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.2
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: 2017-02-14 00:00:00.000000000 Z
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@uma.es
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.4.8
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.