ParallelRearrangeNBest.java
3.11 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
package decoder;
import is2.data.DataF;
import is2.data.Edges;
import is2.data.Parse;
import is2.data.ParseNBest;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import extractors.Extractor;
/**
* @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;}
}
// list of parent child combinations
private static ArrayList<PA> parents = new ArrayList<PA>();
// 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(int l=0;l<labels.length;l++) {
types[ch]=labels[l];
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(int l=0;l<labels.length;l++) {
types[ch]=labels[l];
float p_new = (float) 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;
}
}