Class: SVMPrediction
Instance Method Summary collapse
-
#-(arg) ⇒ Object
— (minus) — Removes all predictions in arg that is found in self.
-
#[](expr) ⇒ Object
— [] — If indexing with a regular expression, a new SVMPrediction object is created containing all elements with matching keys.
-
#cc ⇒ Object
— cc — Correlation coefficient.
-
#difficultFeature(features) ⇒ Object
— difficultFeature —.
-
#f1(border = 0) ⇒ Object
— f1 — Precision Recall measure.
-
#genericplot(plotdata, file, title = 'Plot', xtitle = 'X', ytitle = 'Y') ⇒ Object
Each should be an array giving more than one plot.
-
#plot(legends = [], title = 'SVM Prediction', err = nil, file = '') ⇒ Object
— plot — Plots true value on the X axis vs.
-
#rmsd ⇒ Object
— rmsd — Root mean square deviation.
Methods inherited from Hash
Instance Method Details
#-(arg) ⇒ Object
— (minus) — Removes all predictions in arg that is found in self.
41 42 43 44 45 46 47 48 |
# File 'lib/svmprediction.rb', line 41 def -(arg) self.inject(SVMPrediction.new) do |subs, (k,v)| if !arg[k] subs[k] = v if !arg[k] end subs end end |
#[](expr) ⇒ Object
— [] — If indexing with a regular expression, a new SVMPrediction object is created containing all elements with matching keys.
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/svmprediction.rb', line 27 def [](expr) if expr.is_a? Regexp subs = SVMPrediction.new self.find_all { |(k,v)| k =~ expr }.each do |i| subs[i[0]] = i[1] end subs else super(expr) end end |
#cc ⇒ Object
— cc — Correlation coefficient
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/svmprediction.rb', line 140 def cc a = [] # Don't initialize in one line : x=y=[] b = [] # If doing that, they will both refer to the same array self.each { |example,val| a.push(val['truth'].to_f) b.push(val['pred'].to_f) } amean = a.inject(0) {|sum,i| sum + i} / a.size.to_f bmean = b.inject(0) {|sum,i| sum + i} / b.size.to_f ssa = a.inject(0.0) {|ss,i| ss + (i-amean)**2} ssb = b.inject(0) {|ss,i| ss + (i-bmean)**2} ssab = a.zip(b).inject(0) {|ss,(ai,bi)| ss + (ai-amean) * (bi-bmean)} if ssab > 0 Math::sqrt(ssab**2 / (ssa * ssb)) else 0 end end |
#difficultFeature(features) ⇒ Object
— difficultFeature —
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/svmprediction.rb', line 6 def difficultFeature(features) if !features.is_a? SVMFeature raise "Please give a SVMFeature object as argument." end keys = self.keys names = (1...features.dim).map do |i| features.featname(i) end maxlen = names.map{|n| n.size}.max correlations = (1...features.dim).map do |i| predmiss = keys.map { |k| (self[k]['truth'] - self[k]['pred']).abs } feat = keys.map { |k| features[k][i] } "#{names[i-1].rjust(maxlen)} %.2f"%correlation(predmiss, feat) end correlations.sort_by{|line| line.split.last.to_f.abs}.reverse end |
#f1(border = 0) ⇒ Object
— f1 — Precision Recall measure
161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/svmprediction.rb', line 161 def f1( border = 0) tp = self.select { |k,v| v['truth'] >= border and v['pred'] >= border}.size.to_f fp = self.select { |k,v| v['truth'] < border and v['pred'] >= border}.size.to_f fn = self.select { |k,v| v['truth'] >= border and v['pred'] < border}.size.to_f precision = if (denom=tp+fp) > 0 then tp / denom else 0 end recall = if (denom=tp+fn) > 0 then tp / denom else 0 end if (denom = precision + recall) > 0 2 * precision * recall / denom else 0 end end |
#genericplot(plotdata, file, title = 'Plot', xtitle = 'X', ytitle = 'Y') ⇒ Object
Each should be an array giving more than one plot
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/svmprediction.rb', line 51 def genericplot(plotdata, file, title='Plot', xtitle='X', ytitle='Y') Gnuplot.open do |gp| # This could be either a file or the gnuplot process that we pipe to Gnuplot::Plot.new( gp ) do |plot| plot.title title plot.xlabel xtitle plot.ylabel ytitle plot.set "grid" if file =~ /(png)|(ps)$/ plot.terminal "png size 1024,800 font '/usr/share/fonts/truetype/ttf-bitstream-vera/VeraBd.ttf' 20" if file =~ /png$/ plot.terminal "postscript eps color" if file =~ /ps$/ plot.output file end plot.data = plotdata end end nil end |
#plot(legends = [], title = 'SVM Prediction', err = nil, file = '') ⇒ Object
— plot — Plots true value on the X axis vs. predicted value on the Y axis.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/svmprediction.rb', line 71 def plot(legends = [], title = 'SVM Prediction', err = nil, file = '') # For historical reasons predarr = [ self ] # Set up dataarr dataarr = predarr.map do |predictions| x, y = predictions.inject([[],[]]) { |data,(example,val)| data[0].push(val['truth']) data[1].push(val['pred']) data } end from = dataarr.inject(dataarr[0][0][0]) { |m,a| [m, a[0].min, a[1].min].min }.floor to = dataarr.inject(dataarr[0][0][0]) { |m,a| [m, a[0].max, a[1].max].max }.ceil sampleindex = 0 # Fiddling with legends legends = dataarr.map{|d| "Sample #{sampleindex+=1}"} if legends.size==0 err = ['rmsd','cc'] if !err # Default behaviour err = [err] if err.is_a? String if err legends = legends.map { |legend| legend + ' (' + err.map { |e| begin args = if e.split(/,/).size==1 then nil else '(' + (e.split(/,/)[1..-1]).join(',') + ')' end "#{e} = ".upcase + "%.2f"%eval("self.#{e.split(/,/).first.downcase}#{args}") rescue $! end }.join(', ') + ')' } end # Setting plotdata plotdata = [ Gnuplot::DataSet.new( [[from,to], [from,to]] ) { |ds| ds.using = '1:2' ds.with = "lines" ds.title = "Correct diagonal" ds.linewidth = 1 ds.matrix = nil } ] + dataarr.zip(legends).inject([]) { |arr,((x,y),legend)| arr.push(Gnuplot::DataSet.new( [x,y] ) { |ds| ds.using = '1:2' ds.with = "points" ds.title = legend ds.linewidth = 2 ds.matrix = nil }) } genericplot(plotdata, file, title, 'Experimental value', 'Predicted value') end |
#rmsd ⇒ Object
— rmsd — Root mean square deviation
124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/svmprediction.rb', line 124 def rmsd a = [] # Don't initialize in one line : x=y=[] b = [] # If doing that, they will both refer to the same array self.each { |example,val| a.push(val['truth'].to_f) b.push(val['pred'].to_f) } if (x = a.zip(b).inject(0) {|sd, (d, q)| sd + (d - q)**2 }.to_f / a.length) > 0 Math.sqrt(x) else 0 end end |