Skip to content

Commit b1e1332

Browse files
authored
feat(itn): 支持配置百万及以上数字的转换格式 (#172)
1 parent 0c8daec commit b1e1332

9 files changed

Lines changed: 68 additions & 41 deletions

itn/chinese/inverse_normalizer.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ class InverseNormalizer(Processor):
3333

3434
def __init__(self, cache_dir=None, overwrite_cache=False,
3535
enable_standalone_number=True,
36-
enable_0_to_9=False):
36+
enable_0_to_9=False,
37+
enable_million=False):
3738
super().__init__(name='inverse_normalizer', ordertype='itn')
3839
self.convert_number = enable_standalone_number
3940
self.enable_0_to_9 = enable_0_to_9
41+
self.enable_million = enable_million
4042
if cache_dir is None:
4143
cache_dir = files("itn")
4244
self.build_fst('zh_itn', cache_dir, overwrite_cache)
@@ -48,7 +50,7 @@ def build_tagger(self):
4850
| add_weight(Measure(enable_0_to_9=self.enable_0_to_9).tagger, 1.05) # noqa
4951
| add_weight(Money(enable_0_to_9=self.enable_0_to_9).tagger, 1.04) # noqa
5052
| add_weight(Time().tagger, 1.05)
51-
| add_weight(Cardinal(self.convert_number, self.enable_0_to_9).tagger, 1.06) # noqa
53+
| add_weight(Cardinal(self.convert_number, self.enable_0_to_9, self.enable_million).tagger, 1.06) # noqa
5254
| add_weight(Math().tagger, 1.10)
5355
| add_weight(LicensePlate().tagger, 1.0)
5456
| add_weight(Char().tagger, 100)).optimize()
@@ -58,7 +60,7 @@ def build_tagger(self):
5860
self.tagger = tagger @ self.build_rule(delete(' '), '', '[EOS]')
5961

6062
def build_verbalizer(self):
61-
verbalizer = (Cardinal(self.convert_number, self.enable_0_to_9).verbalizer # noqa
63+
verbalizer = (Cardinal(self.convert_number, self.enable_0_to_9, self.enable_million).verbalizer # noqa
6264
| Char().verbalizer
6365
| Date().verbalizer
6466
| Fraction().verbalizer

itn/chinese/rules/cardinal.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020

2121
class Cardinal(Processor):
2222

23-
def __init__(self, enable_standalone_number=True, enable_0_to_9=True):
23+
def __init__(self, enable_standalone_number=True, enable_0_to_9=True,
24+
enable_million=False):
2425
super().__init__('cardinal')
2526
self.number = None
2627
self.number_exclude_0_to_9 = None
2728
self.enable_standalone_number = enable_standalone_number
2829
self.enable_0_to_9 = enable_0_to_9
30+
self.enable_million = enable_million
2931
self.build_tagger()
3032
self.build_verbalizer()
3133

@@ -57,14 +59,26 @@ def build_tagger(self):
5759
| add_weight(digit + addzero**2, 0.8)
5860
| add_weight(addzero**3, 1.0)))
5961
# 10001111, 1001111, 101111, 11111, 10111, 10011, 10001, 10000
60-
ten_thousand = ((thousand | hundred | teen | tens | digits)
61-
+ delete('万')
62-
+ (thousand
63-
| add_weight(zero + hundred, 0.1)
64-
| add_weight(addzero + zero + (tens | teen), 0.5)
65-
| add_weight(addzero + addzero + zero + digit, 0.5)
66-
| add_weight(digit + addzero**3, 0.8)
67-
| add_weight(addzero**4, 1.0)))
62+
if self.enable_million:
63+
ten_thousand = ((thousand | hundred | teen | tens | digits)
64+
+ delete('万')
65+
+ (thousand
66+
| add_weight(zero + hundred, 0.1)
67+
| add_weight(addzero + zero + (tens | teen), 0.5)
68+
| add_weight(addzero + addzero + zero + digit, 0.5)
69+
| add_weight(digit + addzero**3, 0.8)
70+
| add_weight(addzero**4, 1.0)))
71+
else:
72+
ten_thousand = ((teen | tens | digits)
73+
+ delete('万')
74+
+ (thousand
75+
| add_weight(zero + hundred, 0.1)
76+
| add_weight(addzero + zero + (tens | teen), 0.5)
77+
| add_weight(addzero + addzero + zero + digit, 0.5)
78+
| add_weight(digit + addzero**3, 0.8)
79+
| add_weight(addzero**4, 1.0)))
80+
ten_thousand |= (thousand | hundred) + accep("万") + delete("零").ques + (
81+
thousand | hundred | tens | teen | digits).ques
6882
# 个/十/百/千/万
6983
number = digits | teen | tens | hundred | thousand | ten_thousand
7084
# 兆/亿
@@ -94,8 +108,8 @@ def build_tagger(self):
94108
number_exclude_0_to_9 = teen | tens | hundred | thousand | ten_thousand
95109
# 兆/亿
96110
number_exclude_0_to_9 = (
97-
(number_exclude_0_to_9 + accep('兆') + delete('零').ques).ques +
98-
(number_exclude_0_to_9 + accep('亿') + delete('零').ques).ques +
111+
((number_exclude_0_to_9 | digits) + accep('兆') + delete('零').ques).ques +
112+
((number_exclude_0_to_9 | digits) + accep('亿') + delete('零').ques).ques +
99113
number_exclude_0_to_9
100114
)
101115
# 负的xxx 1.11, 1.01

itn/chinese/rules/measure.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ def build_tagger(self):
3535
sign = string_file('itn/chinese/data/number/sign.tsv') # + -
3636
to = cross('到', '~') | cross('到百分之', '~')
3737

38-
units = add_weight(units_en, -1.0) | \
39-
add_weight((accep('亿') | accep('兆') | accep('万')), -0.5).ques + units_zh
38+
units = add_weight((accep('亿') | accep('兆') | accep('万')), -0.5).ques + units_zh
39+
units |= add_weight((cross('亿', '00M') | cross('兆', 'T') |
40+
cross('万', 'W')), -0.5).ques + (
41+
add_weight(units_en, -1.0)
42+
)
4043

4144
number = Cardinal().number if self.enable_0_to_9 else \
4245
Cardinal().number_exclude_0_to_9

itn/chinese/test/data/measure.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
一亿两千三百人 => 1亿2300人
2121
一亿零两千三百人 => 1亿2300人
2222
一亿七万两千三百人 => 1亿72300人
23-
一兆零三百万两千三百人 => 1兆3002300人
24-
一兆零三百二十万五千人 => 1兆3205000人
23+
一兆零三百万两千三百人 => 1兆300万2300人
24+
一兆零三百二十万五千人 => 1兆320万5000人
2525
两千万人 => 2000万人
2626
九千九百九十一人 => 9991人
27-
一共有一兆零三百二十万五千人 => 一共有1兆3205000人
27+
一共有一兆零三百二十万五千人 => 一共有1兆320万5000人
2828
明天有百分之六十二的概率降雨所以你有百分之二点五一的可能性赢得比赛但是有负百分之十三的人认为你有负的百分之二十的胜利可能性 => 明天有62%的概率降雨所以你有2.51%的可能性赢得比赛但是有-13%的人认为你有-20%的胜利可能性
2929
这块黄金重达三百二十四点七五克,我再随便来几个价格三十四点五二一元,二十点一万 => 这块黄金重达324.75g,我再随便来几个价格¥34.521,20.1万
3030
一共有一人二人三人四人五人六人七人八人九人十人十一人十二人十三人十四人十五人十六人十七人十八人十九人二十人二十一人二十二人二十三人二十四人二十五人二十六人二十七人二十八人二十九人三十人三十一人三十二人三十三人三十四人三十五人三十六人三十七人三十八人三十九人四十人四十一人四十二人四十三人四十四人四十五人四十六人四十七人四十八人四十九人五十人五十一人五十二人五十三人五十四人五十五人五十六人五十七人五十八人五十九人六十人六十一人六十二人六十三人六十四人六十五人六十六人六十七人六十八人六十九人七十人七十一人七十二人七十三人七十四人七十五人七十六人七十七人七十八人七十九人八十人八十一人八十二人八十三人八十四人八十五人八十六人八十七人八十八人八十九人九十人九十一人九十二人九十三人九十四人九十五人九十六人九十七人九十八人九十九人一百人一百零一人一百一人一百一十一人一百一十二人两百二人二百二十三人三百三人三百三十四人四百四人四百四十五人一千零一人一千零五十人一千零五十一人一千三百人一千五百五人两千五百五十六人三千六百六人四千六百六十七人五千七百七人六千七百七十八人七千八百八人八千八百八十九人九千九百九人九千九百九十一人 => 一共有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人110人111人112人220人223人330人334人440人445人1001人1050人1051人1300人1550人2556人3660人4667人5770人6778人7880人8889人9990人9991人
@@ -36,7 +36,7 @@
3636
五六十摩尔 => 50~60mol
3737
三五百公里 => 300~500km
3838
三四万吨 => 3~4万吨
39-
三四万伏特 => 30000~40000v
39+
三四万伏特 => 3~4Wv
4040
十五六千瓦时 => 15~16kwh
4141
四十五六度 => 45-6°
4242
七百三四秒 => 730-40s

itn/chinese/test/data/normalizer_disable_standalone_number_disable_0_to_9.txt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
一百块钱 => 100块钱
1919
十二块五毛 => 12块五毛
2020
一万零三百人 => 10300人
21-
一亿两千三百人 => 一亿2300人
22-
一亿零两千三百人 => 一亿零2300人
23-
一亿七万两千三百人 => 一亿72300人
24-
一兆零三百万两千三百人 => 一兆零3002300人
25-
一兆零三百二十万五千人 => 一兆零3205000人
26-
十五兆零三百二十万五千人 => 15兆3205000人
21+
一亿两千三百人 => 1亿2300人
22+
一亿零两千三百人 => 1亿2300人
23+
一亿七万两千三百人 => 1亿72300人
24+
一兆零三百万两千三百人 => 1兆300万2300人
25+
一兆零三百二十万五千人 => 1兆320万5000人
26+
十五兆零三百二十万五千人 => 15兆320万5000人
2727
两千万人 => 2000万人
2828
九千九百九十一人 => 9991人
29-
一共有一兆零三百二十万五千人 => 一共有一兆零3205000人
29+
一共有一兆零三百二十万五千人 => 一共有1兆320万5000人
3030
明天有百分之六十二的概率降雨所以你有百分之二点五一的可能性赢得比赛但是有负百分之十三的人认为你有负的百分之二十的胜利可能性 => 明天有62%的概率降雨所以你有2.51%的可能性赢得比赛但是有-13%的人认为你有-20%的胜利可能性
3131
这块黄金重达三百二十四点七五克,我再随便来几个价格三十四点五二一元,二十点一万 => 这块黄金重达324.75g,我再随便来几个价格¥34.521,20.1万
3232
一共有一人二人三人四人五人六人七人八人九人十人十一人十二人十三人十四人十五人十六人十七人十八人十九人二十人二十一人二十二人二十三人二十四人二十五人二十六人二十七人二十八人二十九人三十人三十一人三十二人三十三人三十四人三十五人三十六人三十七人三十八人三十九人四十人四十一人四十二人四十三人四十四人四十五人四十六人四十七人四十八人四十九人五十人五十一人五十二人五十三人五十四人五十五人五十六人五十七人五十八人五十九人六十人六十一人六十二人六十三人六十四人六十五人六十六人六十七人六十八人六十九人七十人七十一人七十二人七十三人七十四人七十五人七十六人七十七人七十八人七十九人八十人八十一人八十二人八十三人八十四人八十五人八十六人八十七人八十八人八十九人九十人九十一人九十二人九十三人九十四人九十五人九十六人九十七人九十八人九十九人一百人一百零一人一百一人一百一十一人一百一十二人两百二人二百二十三人三百三人三百三十四人四百四人四百四十五人一千零一人一千零五十人一千零五十一人一千三百人一千五百五人两千五百五十六人三千六百六人四千六百六十七人五千七百七人六千七百七十八人七千八百八人八千八百八十九人九千九百九人九千九百九十一人 => 一共有一人二人三人四人五人六人七人八人九人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人110人111人112人220人223人330人334人440人445人1001人1050人1051人1300人1550人2556人3660人4667人5770人6778人7880人8889人9990人9991人

itn/chinese/test/data/normalizer_enable_standalone_number_disable_0_to_9.txt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
一百块钱 => 100块钱
1919
十二块五毛 => 12块五毛
2020
一万零三百人 => 10300人
21-
一亿两千三百人 => 一亿2300人
22-
一亿零两千三百人 => 一亿零2300人
23-
一亿七万两千三百人 => 一亿72300人
24-
一兆零三百万两千三百人 => 一兆零3002300人
25-
一兆零三百二十万五千人 => 一兆零3205000人
26-
十五兆零三百二十万五千人 => 15兆3205000人
21+
一亿两千三百人 => 1亿2300人
22+
一亿零两千三百人 => 1亿2300人
23+
一亿七万两千三百人 => 1亿72300人
24+
一兆零三百万两千三百人 => 1兆300万2300人
25+
一兆零三百二十万五千人 => 1兆320万5000人
26+
十五兆零三百二十万五千人 => 15兆320万5000人
2727
两千万人 => 2000万人
2828
九千九百九十一人 => 9991人
29-
一共有一兆零三百二十万五千人 => 一共有一兆零3205000人
29+
一共有一兆零三百二十万五千人 => 一共有1兆320万5000人
3030
明天有百分之六十二的概率降雨所以你有百分之二点五一的可能性赢得比赛但是有负百分之十三的人认为你有负的百分之二十的胜利可能性 => 明天有62%的概率降雨所以你有2.51%的可能性赢得比赛但是有-13%的人认为你有-20%的胜利可能性
3131
这块黄金重达三百二十四点七五克,我再随便来几个价格三十四点五二一元,二十点一万 => 这块黄金重达324.75g,我再随便来几个价格¥34.521,20.1万
3232
一共有一人二人三人四人五人六人七人八人九人十人十一人十二人十三人十四人十五人十六人十七人十八人十九人二十人二十一人二十二人二十三人二十四人二十五人二十六人二十七人二十八人二十九人三十人三十一人三十二人三十三人三十四人三十五人三十六人三十七人三十八人三十九人四十人四十一人四十二人四十三人四十四人四十五人四十六人四十七人四十八人四十九人五十人五十一人五十二人五十三人五十四人五十五人五十六人五十七人五十八人五十九人六十人六十一人六十二人六十三人六十四人六十五人六十六人六十七人六十八人六十九人七十人七十一人七十二人七十三人七十四人七十五人七十六人七十七人七十八人七十九人八十人八十一人八十二人八十三人八十四人八十五人八十六人八十七人八十八人八十九人九十人九十一人九十二人九十三人九十四人九十五人九十六人九十七人九十八人九十九人一百人一百零一人一百一人一百一十一人一百一十二人两百二人二百二十三人三百三人三百三十四人四百四人四百四十五人一千零一人一千零五十人一千零五十一人一千三百人一千五百五人两千五百五十六人三千六百六人四千六百六十七人五千七百七人六千七百七十八人七千八百八人八千八百八十九人九千九百九人九千九百九十一人 => 一共有一人二人三人四人五人六人七人八人九人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人110人111人112人220人223人330人334人440人445人1001人1050人1051人1300人1550人2556人3660人4667人5770人6778人7880人8889人9990人9991人

itn/chinese/test/data/number.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
一万一千一百一十一 => 11111
2727
两万 => 20000
2828
十万一千一百一十一 => 101111
29-
一百万一千一百一十一 => 1001111
30-
一千万一千一百一十一 => 10001111
29+
一百万一千一百一十一 => 100万1111
30+
一千万一千一百一十一 => 1000万1111
3131
一点一一 => 1.11
3232
三点一四一五九二六 => 3.1415926
3333
负三点一四一五九二六 => -3.1415926

itn/chinese/test/normalizer_test.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ class TestNormalizer:
2525
normalizer = InverseNormalizer(
2626
overwrite_cache=True,
2727
enable_standalone_number=True,
28-
enable_0_to_9=True)
28+
enable_0_to_9=True,
29+
enable_million=False)
2930

3031
normalizer_cases = chain(
3132
parse_test_case('data/cardinal.txt'),
@@ -51,7 +52,8 @@ class TestNormalizerDisablestandalonenumberEnable0to9:
5152
normalizer = InverseNormalizer(
5253
overwrite_cache=True,
5354
enable_standalone_number=False,
54-
enable_0_to_9=True)
55+
enable_0_to_9=True,
56+
enable_million=False)
5557

5658
normalizer_cases = chain(
5759
parse_test_case('data/char.txt'),
@@ -75,7 +77,8 @@ class TestNormalizerEnablestandalonenumberDisable0to9:
7577
normalizer = InverseNormalizer(
7678
overwrite_cache=True,
7779
enable_standalone_number=True,
78-
enable_0_to_9=False)
80+
enable_0_to_9=False,
81+
enable_million=False)
7982

8083
normalizer_cases = chain(
8184
parse_test_case('data/char.txt'),
@@ -98,7 +101,8 @@ class TestNormalizerDisablestandalonenumberDisable0to9:
98101
normalizer = InverseNormalizer(
99102
overwrite_cache=True,
100103
enable_standalone_number=False,
101-
enable_0_to_9=False)
104+
enable_0_to_9=False,
105+
enable_million=False)
102106

103107
normalizer_cases = chain(
104108
parse_test_case('data/char.txt'),

itn/main.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,16 @@ def main():
4141
parser.add_argument('--enable_0_to_9', type=str,
4242
default='False',
4343
help='enable convert number 0 to 9')
44+
parser.add_argument('--enable_million', type=str,
45+
default='False',
46+
help='六百万 = 6000000 if True else 600万')
4447
args = parser.parse_args()
4548

4649
normalizer = InverseNormalizer(
4750
cache_dir=args.cache_dir, overwrite_cache=args.overwrite_cache,
4851
enable_standalone_number=str2bool(args.enable_standalone_number),
49-
enable_0_to_9=str2bool(args.enable_0_to_9))
52+
enable_0_to_9=str2bool(args.enable_0_to_9),
53+
enable_million=str2bool(args.enable_million))
5054

5155
if args.text:
5256
print(normalizer.tag(args.text))

0 commit comments

Comments
 (0)