@@ -39,6 +39,87 @@ def _maybe_load(paths, file_format) -> meeteval.io.SegLST:
3939 raise TypeError (type (paths ), paths ) from e
4040
4141
42+ class _Normalizers :
43+ """
44+ A normalizer that is applied to the transcript.
45+ Choices:
46+ - None: Do nothing (default)
47+ - lower,rm(.?!,): Lowercase the transcript and remove punctuations (.,?!).
48+ - lower,rm([^a-z0-9 ]): Lowercase the transcript and remove all characters that are not a-z, 0-9, or space.
49+ - chime6: Normalize the transcript according to the CHiME-6 challenge.
50+ - chime7: Normalize the transcript according to the CHiME-7 challenge.
51+ In contrast to chime6, words like "hmm" are normalized,
52+ e.g. "hm", "hmm" and "hmmm" get "hmmm".
53+ - chime8: Normalize the transcript according to the CHiME-8 challenge.
54+ Removes words like "hmm", converts integers to words,
55+ and much more.
56+ """
57+ # Note: The text above is used as CLI help text.
58+ # So the None is not a real option for this class, but the default
59+ # value for the normalizer argument.
60+
61+ def keys (self ):
62+ return [
63+ 'lower,rm(.?!,)' ,
64+ 'lower,rm([^a-z0-9 ])' ,
65+ 'chime6' ,
66+ 'chime7' ,
67+ 'chime8' ,
68+ ]
69+
70+ def __getitem__ (self , normalizer ):
71+ """
72+ >>> def test(normalizer):
73+ ... seg = {'words': 'Hello, World! äèア😊 hm hmm hmmm [noise] [inaudible] wi-fi word-word 1.1 11 Mr. then,\" said'}
74+ ... return _Normalizers()[normalizer](seg)['words']
75+ >>> test('lower,rm(.?!,)')
76+ 'hello world äèア😊 hm hmm hmmm [noise] [inaudible] wi-fi word-word 11 11 mr then" said'
77+ >>> test('lower,rm([^a-z0-9 ])')
78+ 'hello world hm hmm hmmm noise inaudible wifi wordword 11 11 mr then said'
79+ >>> test('chime8')
80+ 'hello world aeア wifi word word 1.1 eleven mister then said'
81+ >>> test('chime7')
82+ 'hello world äèア😊 hmmm hmmm hmmm wi-fi word-word 11 11 mr then said'
83+ >>> test('chime6')
84+ 'hello world äèア😊 hm hmm hmmm wi-fi word-word 11 11 mr then said'
85+ """
86+ if normalizer == 'lower,rm(.?!,)' :
87+ def normalizer (seg ):
88+ seg ['words' ] = seg ['words' ].lower ().replace ('.' , '' ).replace ('?' , '' ).replace ('!' , '' ).replace (',' , '' )
89+ return seg
90+ elif normalizer == 'lower,rm([^a-z0-9 ])' :
91+ r = re .compile ('[^a-z0-9 ]' )
92+ r2 = re .compile (r'\s{2,}' )
93+ def normalizer (seg ):
94+ seg ['words' ] = r2 .sub (' ' , r .sub ('' , seg ['words' ].lower ()).strip ())
95+ return seg
96+ elif normalizer in ['chime8' , 'chime7' , 'chime6' ]:
97+ from chime_utils .text_norm import get_txt_norm # pip install git+https://github.com/chimechallenge/chime-utils
98+ chime_utils_normalizer = get_txt_norm (normalizer )
99+
100+ # Note:
101+ # chime6 and chime7 remove all words, when [redacted] is
102+ # present.
103+
104+ def normalizer (seg ):
105+ words = chime_utils_normalizer (seg ['words' ])
106+ if words != chime_utils_normalizer (seg ['words' ]):
107+ raise RuntimeError (
108+ f'You discovered an idempotence bug in the chime_utils normalizer: { normalizer !r} .\n '
109+ f'Original: { seg ["words" ]} \n '
110+ f'Normalized: { words } \n '
111+ f'Normalized again: { chime_utils_normalizer (words )} '
112+ )
113+ seg ['words' ] = words
114+ return seg
115+ else :
116+ raise ValueError (f'Unknown normalizer: { normalizer } . Available normalizers: { self .keys ()} ' )
117+ return normalizer
118+
119+
120+ normalizers = _Normalizers ()
121+
122+
42123def _load_texts (
43124 reference_paths : 'list[str]' ,
44125 hypothesis_paths : 'list[str]' ,
@@ -89,12 +170,7 @@ def filter(s):
89170 hypothesis = hypothesis .filter_by_uem (uem )
90171
91172 if normalizer is not None :
92- if normalizer == 'lower,rm(.?!,)' :
93- def normalizer (seg ):
94- seg ['words' ] = seg ['words' ].lower ().replace ('.' , '' ).replace ('?' , '' ).replace ('!' , '' ).replace (',' , '' )
95- return seg
96- else :
97- raise NotImplementedError (normalizer )
173+ normalizer = normalizers [normalizer ]
98174 reference = reference .map (normalizer )
99175 hypothesis = hypothesis .map (normalizer )
100176
0 commit comments