ankusa 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +6 -4
- data/Rakefile +2 -2
- data/docs/classes/Ankusa.html +8 -8
- data/docs/classes/Ankusa/Classifier.html +82 -271
- data/docs/classes/Ankusa/HBaseStorage.html +537 -0
- data/docs/classes/Ankusa/MemoryStorage.html +439 -0
- data/docs/classes/Ankusa/TextHash.html +84 -29
- data/docs/classes/String.html +172 -0
- data/docs/created.rid +1 -1
- data/docs/files/README_rdoc.html +6 -4
- data/docs/files/lib/ankusa/classifier_rb.html +1 -1
- data/docs/files/lib/ankusa/extensions_rb.html +108 -0
- data/docs/files/lib/ankusa/hasher_rb.html +1 -1
- data/docs/files/lib/ankusa/hbase_storage_rb.html +108 -0
- data/docs/files/lib/ankusa/{nbclass_rb.html → memory_storage_rb.html} +4 -4
- data/docs/files/lib/ankusa_rb.html +4 -2
- data/docs/fr_class_index.html +3 -1
- data/docs/fr_file_index.html +3 -1
- data/docs/fr_method_index.html +41 -17
- data/lib/ankusa.rb +3 -1
- data/lib/ankusa/classifier.rb +37 -86
- data/lib/ankusa/extensions.rb +13 -0
- data/lib/ankusa/hasher.rb +24 -10
- data/lib/ankusa/hbase_storage.rb +109 -0
- data/lib/ankusa/memory_storage.rb +61 -0
- metadata +13 -7
- data/docs/classes/Ankusa/NBClass.html +0 -168
- data/lib/ankusa/nbclass.rb +0 -15
@@ -56,7 +56,7 @@
|
|
56
56
|
</tr>
|
57
57
|
<tr class="top-aligned-row">
|
58
58
|
<td><strong>Last Update:</strong></td>
|
59
|
-
<td>
|
59
|
+
<td>Thu Dec 02 07:40:55 -0500 2010</td>
|
60
60
|
</tr>
|
61
61
|
</table>
|
62
62
|
</div>
|
@@ -73,9 +73,11 @@
|
|
73
73
|
<h3 class="section-bar">Required files</h3>
|
74
74
|
|
75
75
|
<div class="name-list">
|
76
|
+
ankusa/extensions
|
76
77
|
ankusa/classifier
|
77
78
|
ankusa/hasher
|
78
|
-
ankusa/
|
79
|
+
ankusa/memory_storage
|
80
|
+
ankusa/hbase_storage
|
79
81
|
</div>
|
80
82
|
</div>
|
81
83
|
|
data/docs/fr_class_index.html
CHANGED
@@ -22,8 +22,10 @@
|
|
22
22
|
<div id="index-entries">
|
23
23
|
<a href="classes/Ankusa.html">Ankusa</a><br />
|
24
24
|
<a href="classes/Ankusa/Classifier.html">Ankusa::Classifier</a><br />
|
25
|
-
<a href="classes/Ankusa/
|
25
|
+
<a href="classes/Ankusa/HBaseStorage.html">Ankusa::HBaseStorage</a><br />
|
26
|
+
<a href="classes/Ankusa/MemoryStorage.html">Ankusa::MemoryStorage</a><br />
|
26
27
|
<a href="classes/Ankusa/TextHash.html">Ankusa::TextHash</a><br />
|
28
|
+
<a href="classes/String.html">String</a><br />
|
27
29
|
</div>
|
28
30
|
</div>
|
29
31
|
</body>
|
data/docs/fr_file_index.html
CHANGED
@@ -23,8 +23,10 @@
|
|
23
23
|
<a href="files/README_rdoc.html">README.rdoc</a><br />
|
24
24
|
<a href="files/lib/ankusa_rb.html">lib/ankusa.rb</a><br />
|
25
25
|
<a href="files/lib/ankusa/classifier_rb.html">lib/ankusa/classifier.rb</a><br />
|
26
|
+
<a href="files/lib/ankusa/extensions_rb.html">lib/ankusa/extensions.rb</a><br />
|
26
27
|
<a href="files/lib/ankusa/hasher_rb.html">lib/ankusa/hasher.rb</a><br />
|
27
|
-
<a href="files/lib/ankusa/
|
28
|
+
<a href="files/lib/ankusa/hbase_storage_rb.html">lib/ankusa/hbase_storage.rb</a><br />
|
29
|
+
<a href="files/lib/ankusa/memory_storage_rb.html">lib/ankusa/memory_storage.rb</a><br />
|
28
30
|
<a href="files/lib/ankusa/stopwords_rb.html">lib/ankusa/stopwords.rb</a><br />
|
29
31
|
</div>
|
30
32
|
</div>
|
data/docs/fr_method_index.html
CHANGED
@@ -20,23 +20,47 @@
|
|
20
20
|
<div id="index">
|
21
21
|
<h1 class="section-bar">Methods</h1>
|
22
22
|
<div id="index-entries">
|
23
|
-
<a href="classes/Ankusa/TextHash.html#
|
24
|
-
<a href="classes/Ankusa/TextHash.html#
|
25
|
-
<a href="classes/Ankusa/
|
26
|
-
<a href="classes/Ankusa/Classifier.html#
|
27
|
-
<a href="classes/Ankusa/Classifier.html#
|
28
|
-
<a href="classes/Ankusa/
|
29
|
-
<a href="classes/Ankusa/
|
30
|
-
<a href="classes/Ankusa/
|
31
|
-
<a href="classes/Ankusa/
|
32
|
-
<a href="classes/Ankusa/
|
33
|
-
<a href="classes/Ankusa/
|
34
|
-
<a href="classes/Ankusa/
|
35
|
-
<a href="classes/Ankusa/
|
36
|
-
<a href="classes/Ankusa/
|
37
|
-
<a href="classes/Ankusa/
|
38
|
-
<a href="classes/Ankusa/
|
39
|
-
<a href="classes/Ankusa/
|
23
|
+
<a href="classes/Ankusa/TextHash.html#M000038">add_text (Ankusa::TextHash)</a><br />
|
24
|
+
<a href="classes/Ankusa/TextHash.html#M000039">add_word (Ankusa::TextHash)</a><br />
|
25
|
+
<a href="classes/Ankusa/TextHash.html#M000040">atomize (Ankusa::TextHash)</a><br />
|
26
|
+
<a href="classes/Ankusa/Classifier.html#M000007">classifications (Ankusa::Classifier)</a><br />
|
27
|
+
<a href="classes/Ankusa/Classifier.html#M000006">classify (Ankusa::Classifier)</a><br />
|
28
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000023">classnames (Ankusa::HBaseStorage)</a><br />
|
29
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000010">classnames (Ankusa::MemoryStorage)</a><br />
|
30
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000034">close (Ankusa::HBaseStorage)</a><br />
|
31
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000021">close (Ankusa::MemoryStorage)</a><br />
|
32
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000020">doc_count_total (Ankusa::MemoryStorage)</a><br />
|
33
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000033">doc_count_total (Ankusa::HBaseStorage)</a><br />
|
34
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000012">drop_tables (Ankusa::MemoryStorage)</a><br />
|
35
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000025">drop_tables (Ankusa::HBaseStorage)</a><br />
|
36
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000036">freq_table (Ankusa::HBaseStorage)</a><br />
|
37
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000016">get_doc_count (Ankusa::MemoryStorage)</a><br />
|
38
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000029">get_doc_count (Ankusa::HBaseStorage)</a><br />
|
39
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000028">get_total_word_count (Ankusa::HBaseStorage)</a><br />
|
40
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000015">get_total_word_count (Ankusa::MemoryStorage)</a><br />
|
41
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000014">get_word_counts (Ankusa::MemoryStorage)</a><br />
|
42
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000027">get_word_counts (Ankusa::HBaseStorage)</a><br />
|
43
|
+
<a href="classes/Ankusa/Classifier.html#M000008">get_word_probs (Ankusa::Classifier)</a><br />
|
44
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000019">incr_doc_count (Ankusa::MemoryStorage)</a><br />
|
45
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000032">incr_doc_count (Ankusa::HBaseStorage)</a><br />
|
46
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000031">incr_total_word_count (Ankusa::HBaseStorage)</a><br />
|
47
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000018">incr_total_word_count (Ankusa::MemoryStorage)</a><br />
|
48
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000030">incr_word_count (Ankusa::HBaseStorage)</a><br />
|
49
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000017">incr_word_count (Ankusa::MemoryStorage)</a><br />
|
50
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000026">init_tables (Ankusa::HBaseStorage)</a><br />
|
51
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000013">init_tables (Ankusa::MemoryStorage)</a><br />
|
52
|
+
<a href="classes/Ankusa/TextHash.html#M000037">new (Ankusa::TextHash)</a><br />
|
53
|
+
<a href="classes/Ankusa/Classifier.html#M000003">new (Ankusa::Classifier)</a><br />
|
54
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000009">new (Ankusa::MemoryStorage)</a><br />
|
55
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000022">new (Ankusa::HBaseStorage)</a><br />
|
56
|
+
<a href="classes/String.html#M000001">numeric? (String)</a><br />
|
57
|
+
<a href="classes/Ankusa/MemoryStorage.html#M000011">reset (Ankusa::MemoryStorage)</a><br />
|
58
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000024">reset (Ankusa::HBaseStorage)</a><br />
|
59
|
+
<a href="classes/Ankusa/HBaseStorage.html#M000035">summary_table (Ankusa::HBaseStorage)</a><br />
|
60
|
+
<a href="classes/String.html#M000002">to_ascii (String)</a><br />
|
61
|
+
<a href="classes/Ankusa/Classifier.html#M000004">train (Ankusa::Classifier)</a><br />
|
62
|
+
<a href="classes/Ankusa/Classifier.html#M000005">untrain (Ankusa::Classifier)</a><br />
|
63
|
+
<a href="classes/Ankusa/TextHash.html#M000041">valid_word? (Ankusa::TextHash)</a><br />
|
40
64
|
</div>
|
41
65
|
</div>
|
42
66
|
</body>
|
data/lib/ankusa.rb
CHANGED
data/lib/ankusa/classifier.rb
CHANGED
@@ -1,125 +1,76 @@
|
|
1
1
|
module Ankusa
|
2
|
-
SMALL_PROB = 0.0001
|
3
2
|
|
4
3
|
class Classifier
|
5
4
|
attr_reader :classnames
|
6
5
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@
|
11
|
-
init_tables
|
12
|
-
@classnames = refresh_classnames
|
6
|
+
def initialize(storage)
|
7
|
+
@storage = storage
|
8
|
+
@storage.init_tables
|
9
|
+
@classnames = @storage.classnames
|
13
10
|
end
|
14
|
-
|
11
|
+
|
12
|
+
# text can be either an array of strings or a string
|
13
|
+
# klass is a symbol
|
15
14
|
def train(klass, text)
|
16
15
|
th = TextHash.new(text)
|
17
16
|
th.each { |word, count|
|
18
|
-
|
17
|
+
@storage.incr_word_count klass, word, count
|
18
|
+
yield word, count if block_given?
|
19
19
|
}
|
20
|
-
|
21
|
-
|
20
|
+
@storage.incr_total_word_count klass, th.word_count
|
21
|
+
doccount = (text.kind_of? Array) ? text.length : 1
|
22
|
+
@storage.incr_doc_count klass, doccount
|
22
23
|
@classnames << klass if not @classnames.include? klass
|
23
24
|
end
|
24
25
|
|
26
|
+
# text can be either an array of strings or a string
|
27
|
+
# klass is a symbol
|
25
28
|
def untrain(klass, text)
|
26
29
|
th = TextHash.new(text)
|
27
30
|
th.each { |word, count|
|
28
|
-
|
31
|
+
@storage.incr_word_count klass, word, -count
|
32
|
+
yield word, count if block_given?
|
29
33
|
}
|
30
|
-
|
31
|
-
|
34
|
+
@storage.incr_total_word_count klass, -th.word_count
|
35
|
+
doccount = (text.kind_of? Array) ? text.length : 1
|
36
|
+
@storage.incr_doc_count klass, -doccount
|
32
37
|
end
|
33
38
|
|
34
39
|
def classify(text)
|
35
40
|
# return the most probable class
|
36
|
-
classifications(text).
|
41
|
+
classifications(text).sort_by { |c| -c[1] }.first.first
|
37
42
|
end
|
38
43
|
|
39
44
|
def classifications(text)
|
40
|
-
|
41
|
-
result = {}
|
42
|
-
@classnames.each { |k|
|
43
|
-
classes[k] = NBClass.new k, summary_table, freq_table
|
44
|
-
result[k] = 0
|
45
|
-
}
|
45
|
+
result = Hash.new 0
|
46
46
|
|
47
|
-
TextHash.new(text).each { |word,count|
|
48
|
-
probs = get_word_probs(word
|
49
|
-
@classnames.each { |k| result[k] += Math.log(probs[k]) }
|
47
|
+
TextHash.new(text).each { |word, count|
|
48
|
+
probs = get_word_probs(word)
|
49
|
+
@classnames.each { |k| result[k] += (Math.log(probs[k]) * count) }
|
50
50
|
}
|
51
|
-
|
52
|
-
@classnames.each { |k| result[k] += Math.log(classes[k].doc_count / doc_count_total) }
|
53
51
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
result[
|
52
|
+
# add the prior and exponentiate
|
53
|
+
@classnames.each { |k|
|
54
|
+
result[k] += Math.log(@storage.get_doc_count(k).to_f / @storage.doc_count_total.to_f)
|
55
|
+
result[k] = Math.exp(result[k])
|
58
56
|
}
|
59
|
-
|
57
|
+
|
58
|
+
# normalize to get probs
|
59
|
+
sum = result.values.inject { |x,y| x+y }
|
60
|
+
@classnames.each { |k| result[k] = result[k] / sum }
|
60
61
|
result
|
61
62
|
end
|
62
63
|
|
63
|
-
# get all classes
|
64
|
-
def refresh_classnames
|
65
|
-
cs = []
|
66
|
-
summary_table.create_scanner("", "totals") { |row|
|
67
|
-
cs << row.row.intern
|
68
|
-
}
|
69
|
-
cs
|
70
|
-
end
|
71
|
-
|
72
|
-
def drop_tables
|
73
|
-
freq_table.delete
|
74
|
-
summary_table.delete
|
75
|
-
@stable = nil
|
76
|
-
@ftable = nil
|
77
|
-
end
|
78
|
-
|
79
|
-
def reset
|
80
|
-
drop_tables
|
81
|
-
init_tables
|
82
|
-
end
|
83
|
-
|
84
|
-
def doc_count_total
|
85
|
-
total = 0
|
86
|
-
summary_table.create_scanner("", "totals:doccount") { |row|
|
87
|
-
total += row.columns["totals:doccount"].to_i64
|
88
|
-
}
|
89
|
-
total
|
90
|
-
end
|
91
|
-
|
92
64
|
protected
|
93
|
-
def get_word_probs(word
|
94
|
-
probs =
|
95
|
-
@classnames.each { |cn|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
row.first.columns.each { |colname, cell|
|
100
|
-
classname = colname.split(':')[1].intern
|
101
|
-
probs[classname] = cell.to_i64.to_f / classes[classname].word_count
|
65
|
+
def get_word_probs(word)
|
66
|
+
probs = @storage.get_word_counts(word)
|
67
|
+
@classnames.each { |cn|
|
68
|
+
# use a laplacian smoother
|
69
|
+
probs[cn] = (probs[cn] + 1).to_f / (@storage.get_total_word_count(cn) + 1).to_f
|
102
70
|
}
|
103
71
|
probs
|
104
72
|
end
|
105
73
|
|
106
|
-
def init_tables
|
107
|
-
if not @hbase.has_table? @ftablename
|
108
|
-
@hbase.create_table @ftablename, "classes", "total"
|
109
|
-
end
|
110
|
-
|
111
|
-
if not @hbase.has_table? @stablename
|
112
|
-
@hbase.create_table @stablename, "totals"
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def summary_table
|
117
|
-
@stable ||= @hbase.get_table @stablename
|
118
|
-
end
|
119
|
-
|
120
|
-
def freq_table
|
121
|
-
@ftable ||= @hbase.get_table @ftablename
|
122
|
-
end
|
123
74
|
end
|
124
75
|
|
125
76
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'iconv'
|
2
|
+
|
3
|
+
class String
|
4
|
+
def numeric?
|
5
|
+
true if Float(self) rescue false
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_ascii
|
9
|
+
# from http://www.jroller.com/obie/tags/unicode
|
10
|
+
converter = Iconv.new('ASCII//IGNORE//TRANSLIT', 'UTF-8')
|
11
|
+
converter.iconv(self).unpack('U*').select { |cp| cp < 127 }.pack('U*')
|
12
|
+
end
|
13
|
+
end
|
data/lib/ankusa/hasher.rb
CHANGED
@@ -13,21 +13,35 @@ module Ankusa
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def add_text(text)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
if text.kind_of? Array
|
17
|
+
text.each { |t| add_text t }
|
18
|
+
else
|
19
|
+
# replace dashes with spaces, then get rid of non-word/non-space characters,
|
20
|
+
# then split by space to get words
|
21
|
+
words = TextHash.atomize text
|
22
|
+
words.each { |word| add_word(word) if TextHash.valid_word?(word) }
|
23
|
+
end
|
20
24
|
self
|
21
25
|
end
|
22
26
|
|
23
27
|
def add_word(word)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
@word_count += 1
|
29
|
+
key = word.stem.intern
|
30
|
+
store key, fetch(key, 0)+1
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.atomize(text)
|
34
|
+
text.to_ascii.tr('-', ' ').gsub(/[^\w\s]/," ").split.map { |w| w.downcase }
|
30
35
|
end
|
36
|
+
|
37
|
+
# word should be only alphanum chars at this point
|
38
|
+
def self.valid_word?(word)
|
39
|
+
return false if Ankusa::STOPWORDS.include? word
|
40
|
+
return false if word.length < 3
|
41
|
+
return false if word.numeric?
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
31
45
|
end
|
32
46
|
|
33
47
|
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'hbaserb'
|
2
|
+
|
3
|
+
module Ankusa
|
4
|
+
|
5
|
+
class HBaseStorage
|
6
|
+
attr_reader :hbase
|
7
|
+
|
8
|
+
def initialize(host='localhost', port=9090, frequency_tablename="ankusa_word_frequencies", summary_tablename="ankusa_summary")
|
9
|
+
@hbase = HBaseRb::Client.new host, port
|
10
|
+
@ftablename = frequency_tablename
|
11
|
+
@stablename = summary_tablename
|
12
|
+
@klass_word_counts = {}
|
13
|
+
@klass_doc_counts = {}
|
14
|
+
init_tables
|
15
|
+
end
|
16
|
+
|
17
|
+
def classnames
|
18
|
+
cs = []
|
19
|
+
summary_table.create_scanner("", "totals") { |row|
|
20
|
+
cs << row.row.intern
|
21
|
+
}
|
22
|
+
cs
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset
|
26
|
+
drop_tables
|
27
|
+
init_tables
|
28
|
+
end
|
29
|
+
|
30
|
+
def drop_tables
|
31
|
+
freq_table.delete
|
32
|
+
summary_table.delete
|
33
|
+
@stable = nil
|
34
|
+
@ftable = nil
|
35
|
+
@klass_word_counts = {}
|
36
|
+
@klass_doc_counts = {}
|
37
|
+
end
|
38
|
+
|
39
|
+
def init_tables
|
40
|
+
if not @hbase.has_table? @ftablename
|
41
|
+
@hbase.create_table @ftablename, "classes", "total"
|
42
|
+
end
|
43
|
+
|
44
|
+
if not @hbase.has_table? @stablename
|
45
|
+
@hbase.create_table @stablename, "totals"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_word_counts(word)
|
50
|
+
counts = Hash.new(0)
|
51
|
+
row = freq_table.get_row(word)
|
52
|
+
return counts if row.length == 0
|
53
|
+
|
54
|
+
row.first.columns.each { |colname, cell|
|
55
|
+
classname = colname.split(':')[1].intern
|
56
|
+
counts[classname] = cell.to_i64.to_f
|
57
|
+
}
|
58
|
+
|
59
|
+
counts
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_total_word_count(klass)
|
63
|
+
@klass_word_counts.fetch(klass) {
|
64
|
+
@klass_word_counts[klass] = summary_table.get(klass, "totals:wordcount").first.to_i64.to_f
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_doc_count(klass)
|
69
|
+
@klass_doc_counts.fetch(klass) {
|
70
|
+
@klass_doc_counts[klass] = summary_table.get(klass, "totals:doccount").first.to_i64.to_f
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
def incr_word_count(klass, word, count)
|
75
|
+
freq_table.atomic_increment word, "classes:#{klass.to_s}", count
|
76
|
+
end
|
77
|
+
|
78
|
+
def incr_total_word_count(klass, count)
|
79
|
+
@klass_word_counts[klass] = summary_table.atomic_increment klass, "totals:wordcount", count
|
80
|
+
end
|
81
|
+
|
82
|
+
def incr_doc_count(klass, count)
|
83
|
+
@klass_doc_counts[klass] = summary_table.atomic_increment klass, "totals:doccount", count
|
84
|
+
end
|
85
|
+
|
86
|
+
def doc_count_total
|
87
|
+
total = 0
|
88
|
+
summary_table.create_scanner("", "totals:doccount") { |row|
|
89
|
+
total += row.columns["totals:doccount"].to_i64
|
90
|
+
}
|
91
|
+
total
|
92
|
+
end
|
93
|
+
|
94
|
+
def close
|
95
|
+
@hbase.close
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
def summary_table
|
100
|
+
@stable ||= @hbase.get_table @stablename
|
101
|
+
end
|
102
|
+
|
103
|
+
def freq_table
|
104
|
+
@ftable ||= @hbase.get_table @ftablename
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|