diff --git a/itn/chinese/data/number/special_dash.tsv b/itn/chinese/data/number/special_dash.tsv index d06b033..d13d65d 100644 --- a/itn/chinese/data/number/special_dash.tsv +++ b/itn/chinese/data/number/special_dash.tsv @@ -38,3 +38,82 @@ 六七千 6000-7000 七八千 7000-8000 八九千 8000-9000 +十一二 11、12 +十二三 12、13 +十三四 13、14 +十四五 14、15 +十五六 15、16 +十六七 16、17 +十七八 17、18 +十八九 18、19 +十一二三 11、12、13 +十二三四 12、13、14 +十三四五 13、14、15 +十四五六 14、15、16 +十五六七 15、16、17 +十六七八 16、17、18 +十七八九 17、18、19 +二一二二 21、22 +二二三三 22、23 +二三四四 23、24 +二四五五 24、25 +二五六六 25、26 +二六七七 26、27 +二七八八 27、28 +二八九九 28、29 +三一三二 31、32 +三二三三 32、33 +三三四四 33、34 +三四五五 34、35 +三五六六 35、36 +三六七七 36、37 +三七八八 37、38 +三八九九 38、39 +四一四二 41、42 +四二四三 42、43 +四三四四 43、44 +四五四五 44、45 +四六四六 45、46 +四七四七 46、47 +四八四八 47、48 +四九四九 48、49 +五一五二 51、52 +五二五三 52、53 +五三五四 53、54 +五四五五 54、55 +五五六五 55、56 +五七五七 56、57 +五八五八 57、58 +五九五九 58、59 +六一六二 61、62 +六二六三 62、63 +六三六四 63、64 +六四六五 64、65 +六五六六 65、66 +六六六七 66、67 +六七六八 67、68 +六八六九 68、69 +七一七二 71、72 +七二七三 72、73 +七三七四 73、74 +七四七五 74、75 +七五七六 75、76 +七六七七 76、77 +七七七八 77、78 +七八七九 78、79 +八一八二 81、82 +八二八三 82、83 +八三八四 83、84 +八四八五 84、85 +八五八六 85、86 +八六八七 86、87 +八七八八 87、88 +八八八九 88、89 +九一九二 91、92 +九二九三 92、93 +九三九四 93、94 +九四九五 94、95 +九五九六 95、96 +九六九七 96、97 +九七九八 97、98 +九八九九 98、99 \ No newline at end of file diff --git a/itn/chinese/data/number/special_tilde.tsv b/itn/chinese/data/number/special_tilde.tsv index e6323c0..bdebdd3 100644 --- a/itn/chinese/data/number/special_tilde.tsv +++ b/itn/chinese/data/number/special_tilde.tsv @@ -38,3 +38,82 @@ 六七千 6000~7000 七八千 7000~8000 八九千 8000~9000 +十一二 11、12 +十二三 12、13 +十三四 13、14 +十四五 14、15 +十五六 15、16 +十六七 16、17 +十七八 17、18 +十八九 18、19 +十一二三 11、12、13 +十二三四 12、13、14 +十三四五 13、14、15 +十四五六 14、15、16 +十五六七 15、16、17 +十六七八 16、17、18 +十七八九 17、18、19 +二一二二 21、22 +二二三三 22、23 +二三四四 23、24 +二四五五 24、25 +二五六六 25、26 +二六七七 26、27 +二七八八 27、28 +二八九九 28、29 +三一三二 31、32 +三二三三 32、33 +三三四四 33、34 +三四五五 34、35 +三五六六 35、36 +三六七七 36、37 +三七八八 37、38 +三八九九 38、39 +四一四二 41、42 +四二四三 42、43 +四三四四 43、44 +四五四五 44、45 +四六四六 45、46 +四七四七 46、47 +四八四八 47、48 +四九四九 48、49 +五一五二 51、52 +五二五三 52、53 +五三五四 53、54 +五四五五 54、55 +五五六五 55、56 +五七五七 56、57 +五八五八 57、58 +五九五九 58、59 +六一六二 61、62 +六二六三 62、63 +六三六四 63、64 +六四六五 64、65 +六五六六 65、66 +六六六七 66、67 +六七六八 67、68 +六八六九 68、69 +七一七二 71、72 +七二七三 72、73 +七三七四 73、74 +七四七五 74、75 +七五七六 75、76 +七六七七 76、77 +七七七八 77、78 +七八七九 78、79 +八一八二 81、82 +八二八三 82、83 +八三八四 83、84 +八四八五 84、85 +八五八六 85、86 +八六八七 86、87 +八七八八 87、88 +八八八九 88、89 +九一九二 91、92 +九二九三 92、93 +九三九四 93、94 +九四九五 94、95 +九五九六 95、96 +九六九七 96、97 +九七九八 97、98 +九八九九 98、99 diff --git a/itn/chinese/rules/cardinal.py b/itn/chinese/rules/cardinal.py index 4893cfa..915c4cb 100644 --- a/itn/chinese/rules/cardinal.py +++ b/itn/chinese/rules/cardinal.py @@ -101,7 +101,7 @@ def build_tagger(self): ) ) ten_thousand |= ( - (thousand | hundred) + (thousand | hundred | tens | teen | digits) + accep("万") + delete("零").ques + (thousand | hundred | tens | teen | digits).ques @@ -167,5 +167,31 @@ def build_tagger(self): cardinal |= add_weight(number, 0.1) else: cardinal |= add_weight(number_exclude_0_to_9, 0.1) - tagger = insert('value: "') + cardinal + (insert(" ") + cardinal).star + insert('"') + + + # 5. 添加"中文数字+英文字母"的规则,如"四a" -> "4a" + # 匹配一个或多个英文字母(大小写) + from pynini import union + english_letters = union(*[accep(c) for c in "abcdqABCD"]) + # 数字+字母的组合,如"四a" -> "4a" + number_with_letter = number.plus + english_letters.plus + cardinal |= add_weight(number_with_letter, 0.05) # 使用较高优先级 + + # 6. 添加两个连续完整数字的范围规则(如"二十一二十二" -> "21-22") + # 定义完整数字(不包括单个数字0-9,避免误匹配) + complete_number = teen | tens | hundred | thousand | ten_thousand + complete_number = ( + (complete_number + accep("兆") + delete("零").ques).ques + + (complete_number + accep("亿") + delete("零").ques).ques + + complete_number + ) + complete_number = sign.ques + complete_number + (dot + digits.plus).ques + + # 两个连续完整数字的范围模式(优先级高于单独的数字) + # 如:二十一二十二 -> 21-22, 三十一三十二 -> 31-32 + number_range = complete_number + insert("~") + complete_number + # 将这个规则添加到 cardinal,使用较高优先级(负权重) + cardinal |= add_weight(number_range, -0.05) + + tagger = insert('value: "') + cardinal + (insert("、") + cardinal).star + insert('"') self.tagger = self.add_tokens(tagger) diff --git a/itn/chinese/rules/date.py b/itn/chinese/rules/date.py index 74a52e2..655e7e4 100644 --- a/itn/chinese/rules/date.py +++ b/itn/chinese/rules/date.py @@ -37,7 +37,7 @@ def build_tagger(self): dd = string_file(get_abs_path("../itn/chinese/data/date/dd.tsv")) year = insert('year: "') + (yyyy | yyy | yy) + delete("年") + insert('" ') - year_only = insert('year: "') + (yyyy | yyy | yy) + accep("年") + insert('"') + year_only = insert('year: "') + (yyyy | yyy | yy) + (accep("年") | accep("财年")) + insert('"') month = insert('month: "') + mm + insert('"') day = insert(' day: "') + dd + insert('"') diff --git a/itn/chinese/rules/measure.py b/itn/chinese/rules/measure.py index 23ff24f..eca0cd6 100644 --- a/itn/chinese/rules/measure.py +++ b/itn/chinese/rules/measure.py @@ -56,9 +56,38 @@ def build_tagger(self): + insert("%") ) - # 十千米每小时 => 10km/h, 十一到一百千米每小时 => 11~100km/h - measure = number + (to + number).ques + units + # 定义"到百分点"的转换 + to_percent_point = cross("到", "~") + + # 二十二个百分点, 零点六个百分点, 负二十二个百分点 + # 十一到十二个百分点 => 11~12% + # 注意:需要确保范围匹配时,第二个数字不会误匹配后续的"个"+"百分"+"点" + percent_point_single = ( + (sign + delete("的").ques).ques + + Cardinal().number + + delete("个") + + delete("百分") + + (delete("点") | delete("比")) + + insert("%") + ) + + percent_point_range = ( + (sign + delete("的").ques).ques + + Cardinal().number + + to_percent_point + + Cardinal().number + + delete("个") + + delete("百分") + + (delete("点") | delete("比")) + + insert("%") + ) + + percent_point = percent_point_range | percent_point_single + + # 十千米每小时 => 10km/h, 十一到一百千米每小时 => 11~100km/h + # measure = number + (to + number).ques + units + measure = number + (insert("、") + number).star + (to + number).ques + units # XXX: 特殊case处理, ignore enable_standalone_number # digit + union("百", "千", "万") + digit + unit unit_sp_case1 = [ @@ -96,7 +125,7 @@ def build_tagger(self): -0.5, ) - tagger = insert('value: "') + (measure | measure_sp | percent) + insert('"') + tagger = insert('value: "') + (add_weight(percent_point_range, -0.5) | add_weight(percent_point_single, -0.3) | measure | measure_sp | percent) + insert('"') # 每小时十千米 => 10km/h, 每小时三十到三百一十一千米 => 30~311km/h tagger |= insert('denominator: "') + delete("每") + units + insert('" numerator: "') + measure + insert('"') diff --git a/itn/zh_itn_tagger.fst b/itn/zh_itn_tagger.fst new file mode 100644 index 0000000..0f5928d Binary files /dev/null and b/itn/zh_itn_tagger.fst differ diff --git a/itn/zh_itn_verbalizer.fst b/itn/zh_itn_verbalizer.fst new file mode 100644 index 0000000..e752c80 Binary files /dev/null and b/itn/zh_itn_verbalizer.fst differ