roc 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +25 -0
- data/lib/roc.rb +83 -0
- data/roc.gemspec +25 -0
- data/samples/a.rb +9 -0
- data/test/roc.rb +54 -0
- metadata +53 -0
data/README
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
NAME
|
2
|
+
|
3
|
+
roc
|
4
|
+
|
5
|
+
SYNOPSIS
|
6
|
+
|
7
|
+
Receiver operator characteristic
|
8
|
+
|
9
|
+
URI
|
10
|
+
|
11
|
+
http://rubyforge.org/projects/roc
|
12
|
+
http://github.com/fredrikj/roc
|
13
|
+
|
14
|
+
INSTALL
|
15
|
+
|
16
|
+
gem install roc
|
17
|
+
|
18
|
+
DESCRIPTION
|
19
|
+
|
20
|
+
Calculates a ROC curve as well as the area under the curve (AUC).
|
21
|
+
|
22
|
+
HISTORY
|
23
|
+
0.0.0
|
24
|
+
|
25
|
+
initial version
|
data/lib/roc.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
#----------
|
2
|
+
# ROCarray
|
3
|
+
#----------
|
4
|
+
# An Array consisting only
|
5
|
+
# of 'P' and 'N' (for true positive and negative).
|
6
|
+
# It is further assumed that self is an array of
|
7
|
+
# predictions ordered such that most positive predictions
|
8
|
+
# come first.
|
9
|
+
# Finally - if some elements have been ranked equally, they
|
10
|
+
# should appear together in the same element in the Array.
|
11
|
+
class ROCarray < Array
|
12
|
+
# Two ways to initialize:
|
13
|
+
#
|
14
|
+
# 1) arg1 is prediction values
|
15
|
+
# arg2 is indices of P elements in arg1
|
16
|
+
#
|
17
|
+
# 2) arg1 is an array of T and P:
|
18
|
+
# Example: %w(P PN P N N)
|
19
|
+
#
|
20
|
+
def initialize(arg1,arg2=nil)
|
21
|
+
a = if arg2
|
22
|
+
pn = Array.new(arg1.size,'N')
|
23
|
+
arg2.each{|arg2i| pn[arg2i]='P'}
|
24
|
+
tmp = arg1.zip(pn).sort_by{|i,j| -i}
|
25
|
+
i=1
|
26
|
+
while tmp[i]
|
27
|
+
if tmp[i][0]==tmp[i-1][0]
|
28
|
+
tmp[i-1][1] += tmp[i][1]
|
29
|
+
tmp.delete_at i
|
30
|
+
else
|
31
|
+
i+=1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
tmp.map{|i,j| j}
|
35
|
+
else
|
36
|
+
if arg1.find{|i| !i.is_a? String or i.upcase !~ /^[PN]+$/}
|
37
|
+
raise 'Incorrect Array for ROC'
|
38
|
+
end
|
39
|
+
arg1.dup
|
40
|
+
end
|
41
|
+
a.map!{|i| i.upcase}
|
42
|
+
super(a)
|
43
|
+
end
|
44
|
+
|
45
|
+
# --- roc ---
|
46
|
+
# Returns an array of x and y values up until fpmax.
|
47
|
+
# Returns nil if there are no P values
|
48
|
+
def roc(fpmax=1)
|
49
|
+
ptot = self.join.count('P')
|
50
|
+
return nil if ptot==0
|
51
|
+
ntot = self.join.count('N')
|
52
|
+
ystep = 1.0 / ptot
|
53
|
+
xstep = 1.0 / ntot
|
54
|
+
parr = self.inject([[0,0]]) do |points,rocpoint|
|
55
|
+
break points if points.last[0]>=fpmax
|
56
|
+
curpoint = points.last.dup
|
57
|
+
rocpoint.split('').each do |char|
|
58
|
+
case char
|
59
|
+
when 'N' : curpoint[0]+=xstep
|
60
|
+
when 'P' : curpoint[1]+=ystep
|
61
|
+
end
|
62
|
+
end
|
63
|
+
points << curpoint
|
64
|
+
end
|
65
|
+
# Remove what is greater than fpmax
|
66
|
+
if parr.last[0]>fpmax
|
67
|
+
k = (parr[-1][1]-parr[-2][1]) / (parr[-1][0]-parr[-2][0])
|
68
|
+
r = fpmax - parr[-2][0]
|
69
|
+
parr[-1] = [ fpmax, parr[-2][1] + k * r ]
|
70
|
+
end
|
71
|
+
parr
|
72
|
+
end
|
73
|
+
|
74
|
+
# --- auc ---
|
75
|
+
def auc(fpmax=1)
|
76
|
+
r = self.roc(fpmax)
|
77
|
+
return nil unless r
|
78
|
+
(1...r.size).inject(0) do |area,i|
|
79
|
+
length = [ r[i][0] - r[i-1][0], r[i][1] - r[i-1][1] ]
|
80
|
+
area += length[0] * ( r[i-1][1] + 0.5*length[1] )
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/roc.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
## roc.gemspec
|
2
|
+
#
|
3
|
+
|
4
|
+
Gem::Specification::new do |spec|
|
5
|
+
spec.name = "roc"
|
6
|
+
spec.description = 'Receiver operator characteristic (ROC)'
|
7
|
+
spec.version = "0.0.0"
|
8
|
+
spec.platform = Gem::Platform::RUBY
|
9
|
+
spec.summary = "roc"
|
10
|
+
|
11
|
+
spec.files = ["roc.gemspec", "lib", "lib/roc.rb", "README", "samples", "samples/a.rb", "test", "test/roc.rb"]
|
12
|
+
spec.executables = []
|
13
|
+
|
14
|
+
spec.require_path = "lib"
|
15
|
+
|
16
|
+
spec.has_rdoc = true
|
17
|
+
spec.test_files = "test/roc.rb"
|
18
|
+
|
19
|
+
spec.extensions.push(*[])
|
20
|
+
|
21
|
+
spec.rubyforge_project = "roc"
|
22
|
+
spec.author = "Fredrik Johansson"
|
23
|
+
spec.email = "fredjoha@gmail.com"
|
24
|
+
spec.homepage = "http://github.com/fredrikj/roc/tree/master"
|
25
|
+
end
|
data/samples/a.rb
ADDED
data/test/roc.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
$:.unshift('.')
|
2
|
+
$:.unshift('./lib')
|
3
|
+
$:.unshift('..')
|
4
|
+
$:.unshift('../lib')
|
5
|
+
|
6
|
+
require('test/unit')
|
7
|
+
require('forkoff')
|
8
|
+
|
9
|
+
|
10
|
+
class T < Test::Unit::TestCase
|
11
|
+
|
12
|
+
# simple usage
|
13
|
+
#
|
14
|
+
|
15
|
+
def test_0010
|
16
|
+
results = [0,1,2].forkoff!{|n| [n, Process.pid]}
|
17
|
+
assert_equal(results, results.uniq, 'all ran in a different process')
|
18
|
+
end
|
19
|
+
|
20
|
+
# it's faster
|
21
|
+
#
|
22
|
+
def test_0020
|
23
|
+
n = 4
|
24
|
+
strategies = :forkoff, :each
|
25
|
+
|
26
|
+
4.times do
|
27
|
+
result = {}
|
28
|
+
|
29
|
+
strategies.each do |strategy|
|
30
|
+
a = Time.now.to_f
|
31
|
+
(0..4).send(strategy){|i| sleep 0.2}
|
32
|
+
b = Time.now.to_f
|
33
|
+
elapsed = b - a
|
34
|
+
result[strategy] = elapsed
|
35
|
+
end
|
36
|
+
|
37
|
+
assert result[:forkoff] < result[:each], 'forkoff is faster than each for long running tasks'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# in case of different execution times for different processes
|
42
|
+
#
|
43
|
+
def test_0030
|
44
|
+
a = Time.now.to_f
|
45
|
+
(0...4).forkoff(2) do |i|
|
46
|
+
sleep i.modulo(2)
|
47
|
+
end
|
48
|
+
b = Time.now.to_f
|
49
|
+
elapsed = b - a
|
50
|
+
assert elapsed < 2
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: roc
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.0
|
7
|
+
date: 2009-10-21 00:00:00 +09:00
|
8
|
+
summary: roc
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: fredjoha@gmail.com
|
12
|
+
homepage: http://github.com/fredrikj/roc/tree/master
|
13
|
+
rubyforge_project: roc
|
14
|
+
description: Receiver operator characteristic (ROC)
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Fredrik Johansson
|
31
|
+
files:
|
32
|
+
- roc.gemspec
|
33
|
+
- lib
|
34
|
+
- lib/roc.rb
|
35
|
+
- README
|
36
|
+
- samples
|
37
|
+
- samples/a.rb
|
38
|
+
- test
|
39
|
+
- test/roc.rb
|
40
|
+
test_files:
|
41
|
+
- test/roc.rb
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
extra_rdoc_files: []
|
45
|
+
|
46
|
+
executables: []
|
47
|
+
|
48
|
+
extensions: []
|
49
|
+
|
50
|
+
requirements: []
|
51
|
+
|
52
|
+
dependencies: []
|
53
|
+
|