Skip to content

Commit b49a2ca

Browse files
committed
use local copy of ensegment.py for notebook
1 parent dd97830 commit b49a2ca

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

assets/notebooks/ensegment.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import re, string, random, glob, operator, heapq, codecs, sys, optparse, os, logging, math
2+
from functools import reduce
3+
from collections import defaultdict
4+
from math import log10
5+
6+
#### Code from P. Norvig's book chapter in "Beautiful Data"
7+
8+
def memo(f):
9+
"Memoize function f."
10+
table = {}
11+
def fmemo(*args):
12+
if args not in table:
13+
table[args] = f(*args)
14+
return table[args]
15+
fmemo.memo = table
16+
return fmemo
17+
18+
#### Word Segmentation (p. 223)
19+
20+
class Segment:
21+
22+
def __init__(self, Pw):
23+
self.Pw = Pw
24+
25+
@memo
26+
def segment(self, text):
27+
"Return a list of words that is the best segmentation of text."
28+
if not text: return []
29+
candidates = ([first]+self.segment(rem) for first,rem in self.splits(text))
30+
return max(candidates, key=self.Pwords)
31+
32+
def splits(self, text, L=20):
33+
"Return a list of all possible (first, rem) pairs, len(first)<=L."
34+
return [(text[:i+1], text[i+1:])
35+
for i in range(min(len(text), L))]
36+
37+
def Pwords(self, words):
38+
"The Naive Bayes probability of a sequence of words."
39+
return product(self.Pw(w) for w in words)
40+
41+
#### Support functions (p. 224)
42+
43+
def product(nums):
44+
"Return the product of a sequence of numbers."
45+
return reduce(operator.mul, nums, 1)
46+
47+
class Pdist(dict):
48+
"A probability distribution estimated from counts in datafile."
49+
def __init__(self, data=[], N=None, missingfn=None):
50+
for key,count in data:
51+
self[key] = self.get(key, 0) + int(count)
52+
self.N = float(N or sum(self.values()))
53+
self.missingfn = missingfn or (lambda k, N: 1./N)
54+
def __call__(self, key):
55+
if key in self: return self[key]/self.N
56+
else: return self.missingfn(key, self.N)
57+
58+
def datafile(name, sep='\t'):
59+
"Read key,value pairs from file."
60+
with open(name) as fh:
61+
for line in fh:
62+
(key, value) = line.split(sep)
63+
yield (key, value)
64+
65+
if __name__ == '__main__':
66+
optparser = optparse.OptionParser()
67+
optparser.add_option("-c", "--unigramcounts", dest='counts1w', default=os.path.join('data', 'count_1w.txt'), help="unigram counts")
68+
optparser.add_option("-i", "--inputfile", dest="input", default=os.path.join('data', 'input', 'dev.txt'), help="file to segment")
69+
optparser.add_option("-l", "--logfile", dest="logfile", default=None, help="log file for debugging")
70+
(opts, _) = optparser.parse_args()
71+
72+
if opts.logfile is not None:
73+
logging.basicConfig(filename=opts.logfile, filemode='w', level=logging.DEBUG)
74+
75+
sys.setrecursionlimit(10**6)
76+
77+
Pw = Pdist(data=datafile(opts.counts1w))
78+
segmenter = Segment(Pw)
79+
with open(opts.input) as f:
80+
for line in f:
81+
print(" ".join(segmenter.segment(line.strip())))

0 commit comments

Comments
 (0)