1 # import numpy # numpy provides Fast Arrays, for future optimization
4 # the following will only print when in this module:
5 if __name__ == "__main__":
6 print "DMV-module tests:"
7 a = io.CNF_Rule(3,1,3,0.1)
9 print "import io works"
11 class DMV_Grammar(io.Grammar):
14 We need to be able to access rules per mother node, sum every H, every
15 H_, ..., every H', every H'_, etc. for the IO-algorithm.
17 What other representations do we need? (P_STOP formula uses
18 deps_D(h,l/r) at least)'''
19 def rules(self, (bars, head)):
20 return [r for r in self.p_rules if r.head == head and r.bars == bars]
22 def headed_rule_probs(self):
23 '''Give all rules sorted by head, for use in DMV-specific
24 probabilities (need deps_D(h, l/r) and so on also)'''
27 def __init__(self, p_rules, p_terminals):
28 io.Grammar.__init__(self, p_rules, p_terminals)
31 class DMV_Rule(io.CNF_Rule):
32 '''A single CNF rule in the PCFG, of the form
34 with the added information of bars
40 if(self.bars == 2): # todo: print prettier?
42 return b + io.CNF_Rule.__str__(self)
44 def __init__(self, head, L, R, prob, bars):
45 io.CNF_Rule.__init__(self, head, L, R, prob)
49 raise ValueError("bars must be either 0, 1 or 2; was given: %s" % bars)
52 # the following will only print when in this module:
53 if __name__ == "__main__":
54 # these are not Real rules, just testing the classes. todo: make
55 # a rule-set to test inner() on.
56 a1 = DMV_Rule(3,1,3, 0.1, 1)
57 a2 = DMV_Rule(1,3,3, 0.4, 2)
58 a3 = DMV_Rule(1,1,3, 0.2, 2)
59 a4 = DMV_Rule(1,1,3, 0.2, 0)
65 g = DMV_Grammar([a1,a2,a3,a4], b)
67 for r in g.rules((2,1)):
69 print "should be 0.1:%.1f" % io.inner(0,0, 3, g, ['vbd'])
72 def all_inner_dmv(sent, g):
74 for bars in [0, 1, 2]:
75 for s in range(s, len(sent)): # summing over r = s to r = t-1
76 for t in range(s+1, len(sent)):
77 io.inner(s, t, (bars, h))
84 # '''Here it seems like they store bracketing information on a per-head
85 # (per direction) basis, in deps_D(h, dir) which gives us a list. '''
86 # P_D = array indexed on h`s from sentence
88 # for a from deps_D(h, dir):
90 # P_STOP (notSTOP | h, dir, adj) * \
91 # P_CHOOSE (a | h,dir) * \
93 # P_STOP (STOP | h, dir, adj)
96 # def P_STOP(STOP | h, dir, adj):
99 # for i<loc(h): # where h is in the sentence
101 # P_STOP_num += c(h-r : i, k)
106 # P_STOP_den += c(l-h-r : i, k)
107 # return P_STOP_num / P_STOP_den
111 ##################################################################
112 # just junk from here on down: #
113 ##################################################################
115 def initialize(taglist):
116 '''If H and A are non-equal tags, we want every rule
123 to have some initial probability. It's supposed to be harmonic,
124 which we get from an M-step of the IO-algorithm; do we need a full
125 rule count? -- Where we check the distance from H to A in each case,
126 and the probability is C/distance + C' ... but then what constants
127 do we need in order to sum to 1?
129 p.4 in Carroll & Charniak gives the number of DG rules for
130 sentences of length n as n*(2^{n-1}+1).
132 "harmonic" completion where all non-ROOT words took the same
133 number of arguments, and each took other words as arguments in
134 inverse proportion to (a constant plus) the distance between
135 them. The ROOT always had a single argument and took each word
136 with equal probability. (p.5 in DMV-article)
140 Given their model, we have these types of probabilities:
142 - P_STOP(-STOP | h, dir, adj)
143 - P_STOP(STOP | h, dir, adj)
144 - P_CHOOSE(a | h, dir)
146 and then each has to sum to 1 given certain values for h, dir, adj.
147 (so P_STOP(-STOP | VBD, L, non-adj)+P_STOP( STOP | VBD, L, non-adj)=1;
148 and summing P_CHOOSE(a | VBD, L), over all a, equals 1).
151 rules = [ ] # should be a simple array where indexes correspond to
152 # heads h, so if h->_a_ h_, then h == heads[i] iff
153 # rules[i] == (_a_, h_)
157 rules['ROOT'] = ('ROOT', h)
158 rules['_' + h + '_'] = ('STOP', h + '_') # _H_ -> STOP H_
159 rules[ h + '_'] = ('h' , 'STOP' ) # H_ -> H STOP
162 rules[h] = (h , '_' + a + '_') # H -> H _A_
163 rules[h + '_'] = ('_' + a + '_', h + '_') # H_ -> _A_ H_
165 # not sure what kind of rule-access we'll need
166 # (dictionary?).. also, rules should be stored somewhere "globally
169 # put the probabilities in a single array, indexed on rule-number,
170 # (anticipating the need for quick and simple access)
171 p_rules = numpy.zeros( (len(rules)) )
173 return (p_rules, rules)
177 p = tuple([(tag, 1) for tag in tags])
178 test = numpy.zeros((len(tags)+1, len(tags)+1))
181 #if __name__ == "__main__":
182 # pprint.pprint(initialize(['vbd', 'nn', 'jj', 'dt']))
183 # print bracket(("foo", "bar", "fie","foe"))