|
11 | 11 | 'DICPErrorRate', |
12 | 12 | 'greedy_di_cp_word_error_rate', |
13 | 13 | 'greedy_di_cp_word_error_rate_multifile', |
| 14 | + 'greedy_di_tcp_word_error_rate', |
| 15 | + 'greedy_di_tcp_word_error_rate_multifile', |
14 | 16 | 'apply_dicp_assignment', |
15 | 17 | ] |
16 | 18 |
|
@@ -111,6 +113,86 @@ def greedy_di_cp_word_error_rate_multifile( |
111 | 113 | ) |
112 | 114 |
|
113 | 115 |
|
| 116 | +def greedy_di_tcp_word_error_rate( |
| 117 | + reference, |
| 118 | + hypothesis, |
| 119 | + reference_pseudo_word_level_timing='character_based', |
| 120 | + hypothesis_pseudo_word_level_timing='character_based_points', |
| 121 | + collar: int = 0, |
| 122 | + reference_sort='segment', |
| 123 | + hypothesis_sort='segment', |
| 124 | +): |
| 125 | + """ |
| 126 | + Computes the DI-tcpWER (time-constrained DI-cpWER) with a greedy algorithm |
| 127 | +
|
| 128 | + >>> reference = SegLST([ |
| 129 | + ... {'segment_index': 0, 'speaker': 'A', 'words': 'a', 'start_time': 0.0, 'end_time': 1.0}, |
| 130 | + ... {'segment_index': 1, 'speaker': 'A', 'words': 'b', 'start_time': 1.0, 'end_time': 2.0}, |
| 131 | + ... {'segment_index': 2, 'speaker': 'B', 'words': 'c', 'start_time': 2.0, 'end_time': 3.0}, |
| 132 | + ... {'segment_index': 3, 'speaker': 'B', 'words': 'd', 'start_time': 3.0, 'end_time': 4.0}, |
| 133 | + ... ]) |
| 134 | + >>> greedy_di_tcp_word_error_rate(reference, reference) |
| 135 | + DICPErrorRate(error_rate=0.0, errors=0, length=4, insertions=0, deletions=0, substitutions=0, reference_self_overlap=SelfOverlap(overlap_rate=0.0, overlap_time=0, total_time=6.0), hypothesis_self_overlap=SelfOverlap(overlap_rate=0.0, overlap_time=0, total_time=6.0), assignment=('A', 'A', 'B', 'B')) |
| 136 | + >>> hypothesis = SegLST([ |
| 137 | + ... {'segment_index': 0, 'speaker': 'A', 'words': 'a b', 'start_time': 0.0, 'end_time': 2.0}, |
| 138 | + ... {'segment_index': 2, 'speaker': 'A', 'words': 'b c d', 'start_time': 1.0, 'end_time': 4.0}, |
| 139 | + ... ]) |
| 140 | + >>> greedy_di_tcp_word_error_rate(reference, hypothesis) |
| 141 | + DICPErrorRate(error_rate=0.25, errors=1, length=4, insertions=1, deletions=0, substitutions=0, reference_self_overlap=SelfOverlap(overlap_rate=0.0, overlap_time=0, total_time=6.0), hypothesis_self_overlap=SelfOverlap(overlap_rate=0.25, overlap_time=1.0, total_time=4.0), assignment=('A', 'B')) |
| 142 | + """ |
| 143 | + |
| 144 | + # The assignment of the DI-tcpWER is equal to the assignment of the tcORC-WER |
| 145 | + # with swapped arguments (reference <-> hypothesis) |
| 146 | + er = meeteval.wer.wer.time_constrained_orc.greedy_time_constrained_orc_wer( |
| 147 | + hypothesis, reference, |
| 148 | + hypothesis_pseudo_word_level_timing, reference_pseudo_word_level_timing, |
| 149 | + collar, |
| 150 | + hypothesis_sort, reference_sort |
| 151 | + ) |
| 152 | + |
| 153 | + # The error rate object can be constructed just from the ORC-WER error rate |
| 154 | + # object. Insertions and deletions are swapped, the length is different. |
| 155 | + return DICPErrorRate( |
| 156 | + er.errors, sum([len(s['words'].split()) for s in reference]), |
| 157 | + insertions=er.deletions, |
| 158 | + deletions=er.insertions, |
| 159 | + substitutions=er.substitutions, |
| 160 | + assignment=er.assignment, |
| 161 | + reference_self_overlap=er.hypothesis_self_overlap, |
| 162 | + hypothesis_self_overlap=er.reference_self_overlap, |
| 163 | + ) |
| 164 | + |
| 165 | + |
| 166 | +def greedy_di_tcp_word_error_rate_multifile( |
| 167 | + reference, |
| 168 | + hypothesis, |
| 169 | + partial=False, |
| 170 | + reference_pseudo_word_level_timing='character_based', |
| 171 | + hypothesis_pseudo_word_level_timing='character_based_points', |
| 172 | + collar: int = 0, |
| 173 | + reference_sort='segment', |
| 174 | + hypothesis_sort='segment', |
| 175 | +) -> 'dict[str, DICPErrorRate]': |
| 176 | + """ |
| 177 | + Computes the (Greedy) DI-tcpWER for each example in the reference and hypothesis files. |
| 178 | +
|
| 179 | + To compute the overall WER, use |
| 180 | + `sum(greedy_di_tcp_word_error_rate_multifile(r, h).values())`. |
| 181 | + """ |
| 182 | + from meeteval.io.seglst import apply_multi_file |
| 183 | + return apply_multi_file( |
| 184 | + functools.partial( |
| 185 | + greedy_di_tcp_word_error_rate, |
| 186 | + reference_pseudo_word_level_timing=reference_pseudo_word_level_timing, |
| 187 | + hypothesis_pseudo_word_level_timing=hypothesis_pseudo_word_level_timing, |
| 188 | + collar=collar, |
| 189 | + reference_sort=reference_sort, |
| 190 | + hypothesis_sort=hypothesis_sort, |
| 191 | + ), reference, hypothesis, |
| 192 | + partial=partial |
| 193 | + ) |
| 194 | + |
| 195 | + |
114 | 196 | def apply_dicp_assignment( |
115 | 197 | assignment: 'list[int | str] | tuple[int | str]', |
116 | 198 | reference: 'list[list[str]] | dict[str, list[str]] | SegLST', |
|
0 commit comments