ParallelRearrangeNBest.java
3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package decoder;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import extractors.Extractor;
import is2.data.DataF;
import is2.data.Edges;
import is2.data.Parse;
import is2.data.ParseNBest;
/**
* @author Dr. Bernd Bohnet, 30.08.2009
*
* This class implements a parallel edge rearrangement for
* non-projective parsing; The linear method was first suggest by Rayn
* McDonald et. al. 2005.
*/
final public class ParallelRearrangeNBest implements Callable<Object> {
// new parent child combination to explore
final static class PA {
final float p;
final short ch, pa;
float best;
public PA(float p2, short ch2, short pa2) {
p = p2;
ch = ch2;
pa = pa2;
}
}
// some data from the dependency tree
private short[] pos;
private DataF x;
private boolean[][] isChild;
public short[] heads, types;
private float lastNBest;
private float best; // best so far
private float threshold;
private Extractor extractor;
/**
* Initialize the parallel rearrange thread
*
* @param isChild2
* is a child
* @param edgesC
* the part-of-speech edge mapping
* @param pos
* the part-of-speech
* @param x
* the data
* @param lastNBest
* @param s
* the heads
* @param ts
* the types
*/
public ParallelRearrangeNBest(short[] pos, DataF x, Parse p, float lastNBest, Extractor extractor, float best,
float threshold) {
heads = p.heads;
types = p.labels;
isChild = new boolean[heads.length][heads.length];
for (int i = 1, l1 = 1; i < heads.length; i++, l1 = i)
while ((l1 = heads[l1]) != -1)
isChild[l1][i] = true;
this.lastNBest = lastNBest;
this.pos = pos;
this.x = x;
this.extractor = extractor;
this.best = best;
this.threshold = threshold;
}
public ArrayList<ParseNBest> parses = new ArrayList<ParseNBest>();
@Override
public Object call() {
// check the list of new possible parents and children for a better
// combination
for (int ch = 1; ch < heads.length; ch++) {
for (short pa = 0; pa < heads.length; pa++) {
if (ch == pa || pa == heads[ch] || isChild[ch][pa])
continue;
short oldP = heads[ch], oldT = types[ch];
heads[ch] = pa;
short[] labels = Edges.get(pos[pa], pos[ch], ch < pa);
for (short label : labels) {
types[ch] = label;
float p_new = extractor.encode3(pos, heads, types, x);
if (p_new < lastNBest || ((best + this.threshold) > p_new))
continue;
ParseNBest p = new ParseNBest();
p.signature(heads, types);
p.f1 = p_new;
parses.add(p);
}
// change back
heads[ch] = oldP;
types[ch] = oldT;
// consider changes to labels only
labels = Edges.get(pos[oldP], pos[ch], ch < oldP);
for (short label : labels) {
types[ch] = label;
float p_new = extractor.encode3(pos, heads, types, x);
// optimization: add only if larger than smallest of n-best
if (p_new < lastNBest || ((best + this.threshold) > p_new))
continue;
ParseNBest p = new ParseNBest();
p.signature(heads, types);
p.f1 = p_new;
parses.add(p);
}
heads[ch] = oldP;
types[ch] = oldT;
}
}
return parses;
}
}