Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(itn): 支持配置百万及以上数字的转换格式 #172

Merged
merged 1 commit into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions itn/chinese/inverse_normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@ class InverseNormalizer(Processor):

def __init__(self, cache_dir=None, overwrite_cache=False,
enable_standalone_number=True,
enable_0_to_9=False):
enable_0_to_9=False,
enable_million=False):
super().__init__(name='inverse_normalizer', ordertype='itn')
self.convert_number = enable_standalone_number
self.enable_0_to_9 = enable_0_to_9
self.enable_million = enable_million
if cache_dir is None:
cache_dir = files("itn")
self.build_fst('zh_itn', cache_dir, overwrite_cache)
Expand All @@ -48,7 +50,7 @@ def build_tagger(self):
| add_weight(Measure(enable_0_to_9=self.enable_0_to_9).tagger, 1.05) # noqa
| add_weight(Money(enable_0_to_9=self.enable_0_to_9).tagger, 1.04) # noqa
| add_weight(Time().tagger, 1.05)
| add_weight(Cardinal(self.convert_number, self.enable_0_to_9).tagger, 1.06) # noqa
| add_weight(Cardinal(self.convert_number, self.enable_0_to_9, self.enable_million).tagger, 1.06) # noqa
| add_weight(Math().tagger, 1.10)
| add_weight(LicensePlate().tagger, 1.0)
| add_weight(Char().tagger, 100)).optimize()
Expand All @@ -58,7 +60,7 @@ def build_tagger(self):
self.tagger = tagger @ self.build_rule(delete(' '), '', '[EOS]')

def build_verbalizer(self):
verbalizer = (Cardinal(self.convert_number, self.enable_0_to_9).verbalizer # noqa
verbalizer = (Cardinal(self.convert_number, self.enable_0_to_9, self.enable_million).verbalizer # noqa
| Char().verbalizer
| Date().verbalizer
| Fraction().verbalizer
Expand Down
36 changes: 25 additions & 11 deletions itn/chinese/rules/cardinal.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@

class Cardinal(Processor):

def __init__(self, enable_standalone_number=True, enable_0_to_9=True):
def __init__(self, enable_standalone_number=True, enable_0_to_9=True,
enable_million=False):
super().__init__('cardinal')
self.number = None
self.number_exclude_0_to_9 = None
self.enable_standalone_number = enable_standalone_number
self.enable_0_to_9 = enable_0_to_9
self.enable_million = enable_million
self.build_tagger()
self.build_verbalizer()

Expand Down Expand Up @@ -57,14 +59,26 @@ def build_tagger(self):
| add_weight(digit + addzero**2, 0.8)
| add_weight(addzero**3, 1.0)))
# 10001111, 1001111, 101111, 11111, 10111, 10011, 10001, 10000
ten_thousand = ((thousand | hundred | teen | tens | digits)
+ delete('万')
+ (thousand
| add_weight(zero + hundred, 0.1)
| add_weight(addzero + zero + (tens | teen), 0.5)
| add_weight(addzero + addzero + zero + digit, 0.5)
| add_weight(digit + addzero**3, 0.8)
| add_weight(addzero**4, 1.0)))
if self.enable_million:
ten_thousand = ((thousand | hundred | teen | tens | digits)
+ delete('万')
+ (thousand
| add_weight(zero + hundred, 0.1)
| add_weight(addzero + zero + (tens | teen), 0.5)
| add_weight(addzero + addzero + zero + digit, 0.5)
| add_weight(digit + addzero**3, 0.8)
| add_weight(addzero**4, 1.0)))
else:
ten_thousand = ((teen | tens | digits)
+ delete('万')
+ (thousand
| add_weight(zero + hundred, 0.1)
| add_weight(addzero + zero + (tens | teen), 0.5)
| add_weight(addzero + addzero + zero + digit, 0.5)
| add_weight(digit + addzero**3, 0.8)
| add_weight(addzero**4, 1.0)))
ten_thousand |= (thousand | hundred) + accep("万") + delete("零").ques + (
thousand | hundred | tens | teen | digits).ques
# 个/十/百/千/万
number = digits | teen | tens | hundred | thousand | ten_thousand
# 兆/亿
Expand Down Expand Up @@ -94,8 +108,8 @@ def build_tagger(self):
number_exclude_0_to_9 = teen | tens | hundred | thousand | ten_thousand
# 兆/亿
number_exclude_0_to_9 = (
(number_exclude_0_to_9 + accep('兆') + delete('零').ques).ques +
(number_exclude_0_to_9 + accep('亿') + delete('零').ques).ques +
((number_exclude_0_to_9 | digits) + accep('兆') + delete('零').ques).ques +
((number_exclude_0_to_9 | digits) + accep('亿') + delete('零').ques).ques +
number_exclude_0_to_9
)
# 负的xxx 1.11, 1.01
Expand Down
7 changes: 5 additions & 2 deletions itn/chinese/rules/measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ def build_tagger(self):
sign = string_file('itn/chinese/data/number/sign.tsv') # + -
to = cross('到', '~') | cross('到百分之', '~')

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

number = Cardinal().number if self.enable_0_to_9 else \
Cardinal().number_exclude_0_to_9
Expand Down
8 changes: 4 additions & 4 deletions itn/chinese/test/data/measure.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
一亿两千三百人 => 1亿2300人
一亿零两千三百人 => 1亿2300人
一亿七万两千三百人 => 1亿72300人
一兆零三百万两千三百人 => 1兆3002300人
一兆零三百二十万五千人 => 1兆3205000人
一兆零三百万两千三百人 => 1兆300万2300人
一兆零三百二十万五千人 => 1兆320万5000人
两千万人 => 2000万人
九千九百九十一人 => 9991人
一共有一兆零三百二十万五千人 => 一共有1兆3205000人
一共有一兆零三百二十万五千人 => 一共有1兆320万5000人
明天有百分之六十二的概率降雨所以你有百分之二点五一的可能性赢得比赛但是有负百分之十三的人认为你有负的百分之二十的胜利可能性 => 明天有62%的概率降雨所以你有2.51%的可能性赢得比赛但是有-13%的人认为你有-20%的胜利可能性
这块黄金重达三百二十四点七五克,我再随便来几个价格三十四点五二一元,二十点一万 => 这块黄金重达324.75g,我再随便来几个价格¥34.521,20.1万
一共有一人二人三人四人五人六人七人八人九人十人十一人十二人十三人十四人十五人十六人十七人十八人十九人二十人二十一人二十二人二十三人二十四人二十五人二十六人二十七人二十八人二十九人三十人三十一人三十二人三十三人三十四人三十五人三十六人三十七人三十八人三十九人四十人四十一人四十二人四十三人四十四人四十五人四十六人四十七人四十八人四十九人五十人五十一人五十二人五十三人五十四人五十五人五十六人五十七人五十八人五十九人六十人六十一人六十二人六十三人六十四人六十五人六十六人六十七人六十八人六十九人七十人七十一人七十二人七十三人七十四人七十五人七十六人七十七人七十八人七十九人八十人八十一人八十二人八十三人八十四人八十五人八十六人八十七人八十八人八十九人九十人九十一人九十二人九十三人九十四人九十五人九十六人九十七人九十八人九十九人一百人一百零一人一百一人一百一十一人一百一十二人两百二人二百二十三人三百三人三百三十四人四百四人四百四十五人一千零一人一千零五十人一千零五十一人一千三百人一千五百五人两千五百五十六人三千六百六人四千六百六十七人五千七百七人六千七百七十八人七千八百八人八千八百八十九人九千九百九人九千九百九十一人 => 一共有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人
Expand All @@ -36,7 +36,7 @@
五六十摩尔 => 50~60mol
三五百公里 => 300~500km
三四万吨 => 3~4万吨
三四万伏特 => 30000~40000v
三四万伏特 => 3~4Wv
十五六千瓦时 => 15~16kwh
四十五六度 => 45-6°
七百三四秒 => 730-40s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
一百块钱 => 100块钱
十二块五毛 => 12块五毛
一万零三百人 => 10300人
一亿两千三百人 => 一亿2300人
一亿零两千三百人 => 一亿零2300人
一亿七万两千三百人 => 一亿72300人
一兆零三百万两千三百人 => 一兆零3002300人
一兆零三百二十万五千人 => 一兆零3205000人
十五兆零三百二十万五千人 => 15兆3205000人
一亿两千三百人 => 1亿2300人
一亿零两千三百人 => 1亿2300人
一亿七万两千三百人 => 1亿72300人
一兆零三百万两千三百人 => 1兆300万2300人
一兆零三百二十万五千人 => 1兆320万5000人
十五兆零三百二十万五千人 => 15兆320万5000人
两千万人 => 2000万人
九千九百九十一人 => 9991人
一共有一兆零三百二十万五千人 => 一共有一兆零3205000人
一共有一兆零三百二十万五千人 => 一共有1兆320万5000人
明天有百分之六十二的概率降雨所以你有百分之二点五一的可能性赢得比赛但是有负百分之十三的人认为你有负的百分之二十的胜利可能性 => 明天有62%的概率降雨所以你有2.51%的可能性赢得比赛但是有-13%的人认为你有-20%的胜利可能性
这块黄金重达三百二十四点七五克,我再随便来几个价格三十四点五二一元,二十点一万 => 这块黄金重达324.75g,我再随便来几个价格¥34.521,20.1万
一共有一人二人三人四人五人六人七人八人九人十人十一人十二人十三人十四人十五人十六人十七人十八人十九人二十人二十一人二十二人二十三人二十四人二十五人二十六人二十七人二十八人二十九人三十人三十一人三十二人三十三人三十四人三十五人三十六人三十七人三十八人三十九人四十人四十一人四十二人四十三人四十四人四十五人四十六人四十七人四十八人四十九人五十人五十一人五十二人五十三人五十四人五十五人五十六人五十七人五十八人五十九人六十人六十一人六十二人六十三人六十四人六十五人六十六人六十七人六十八人六十九人七十人七十一人七十二人七十三人七十四人七十五人七十六人七十七人七十八人七十九人八十人八十一人八十二人八十三人八十四人八十五人八十六人八十七人八十八人八十九人九十人九十一人九十二人九十三人九十四人九十五人九十六人九十七人九十八人九十九人一百人一百零一人一百一人一百一十一人一百一十二人两百二人二百二十三人三百三人三百三十四人四百四人四百四十五人一千零一人一千零五十人一千零五十一人一千三百人一千五百五人两千五百五十六人三千六百六人四千六百六十七人五千七百七人六千七百七十八人七千八百八人八千八百八十九人九千九百九人九千九百九十一人 => 一共有一人二人三人四人五人六人七人八人九人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人
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
一百块钱 => 100块钱
十二块五毛 => 12块五毛
一万零三百人 => 10300人
一亿两千三百人 => 一亿2300人
一亿零两千三百人 => 一亿零2300人
一亿七万两千三百人 => 一亿72300人
一兆零三百万两千三百人 => 一兆零3002300人
一兆零三百二十万五千人 => 一兆零3205000人
十五兆零三百二十万五千人 => 15兆3205000人
一亿两千三百人 => 1亿2300人
一亿零两千三百人 => 1亿2300人
一亿七万两千三百人 => 1亿72300人
一兆零三百万两千三百人 => 1兆300万2300人
一兆零三百二十万五千人 => 1兆320万5000人
十五兆零三百二十万五千人 => 15兆320万5000人
两千万人 => 2000万人
九千九百九十一人 => 9991人
一共有一兆零三百二十万五千人 => 一共有一兆零3205000人
一共有一兆零三百二十万五千人 => 一共有1兆320万5000人
明天有百分之六十二的概率降雨所以你有百分之二点五一的可能性赢得比赛但是有负百分之十三的人认为你有负的百分之二十的胜利可能性 => 明天有62%的概率降雨所以你有2.51%的可能性赢得比赛但是有-13%的人认为你有-20%的胜利可能性
这块黄金重达三百二十四点七五克,我再随便来几个价格三十四点五二一元,二十点一万 => 这块黄金重达324.75g,我再随便来几个价格¥34.521,20.1万
一共有一人二人三人四人五人六人七人八人九人十人十一人十二人十三人十四人十五人十六人十七人十八人十九人二十人二十一人二十二人二十三人二十四人二十五人二十六人二十七人二十八人二十九人三十人三十一人三十二人三十三人三十四人三十五人三十六人三十七人三十八人三十九人四十人四十一人四十二人四十三人四十四人四十五人四十六人四十七人四十八人四十九人五十人五十一人五十二人五十三人五十四人五十五人五十六人五十七人五十八人五十九人六十人六十一人六十二人六十三人六十四人六十五人六十六人六十七人六十八人六十九人七十人七十一人七十二人七十三人七十四人七十五人七十六人七十七人七十八人七十九人八十人八十一人八十二人八十三人八十四人八十五人八十六人八十七人八十八人八十九人九十人九十一人九十二人九十三人九十四人九十五人九十六人九十七人九十八人九十九人一百人一百零一人一百一人一百一十一人一百一十二人两百二人二百二十三人三百三人三百三十四人四百四人四百四十五人一千零一人一千零五十人一千零五十一人一千三百人一千五百五人两千五百五十六人三千六百六人四千六百六十七人五千七百七人六千七百七十八人七千八百八人八千八百八十九人九千九百九人九千九百九十一人 => 一共有一人二人三人四人五人六人七人八人九人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人
4 changes: 2 additions & 2 deletions itn/chinese/test/data/number.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
一万一千一百一十一 => 11111
两万 => 20000
十万一千一百一十一 => 101111
一百万一千一百一十一 => 1001111
一千万一千一百一十一 => 10001111
一百万一千一百一十一 => 100万1111
一千万一千一百一十一 => 1000万1111
一点一一 => 1.11
三点一四一五九二六 => 3.1415926
负三点一四一五九二六 => -3.1415926
Expand Down
12 changes: 8 additions & 4 deletions itn/chinese/test/normalizer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class TestNormalizer:
normalizer = InverseNormalizer(
overwrite_cache=True,
enable_standalone_number=True,
enable_0_to_9=True)
enable_0_to_9=True,
enable_million=False)

normalizer_cases = chain(
parse_test_case('data/cardinal.txt'),
Expand All @@ -51,7 +52,8 @@ class TestNormalizerDisablestandalonenumberEnable0to9:
normalizer = InverseNormalizer(
overwrite_cache=True,
enable_standalone_number=False,
enable_0_to_9=True)
enable_0_to_9=True,
enable_million=False)

normalizer_cases = chain(
parse_test_case('data/char.txt'),
Expand All @@ -75,7 +77,8 @@ class TestNormalizerEnablestandalonenumberDisable0to9:
normalizer = InverseNormalizer(
overwrite_cache=True,
enable_standalone_number=True,
enable_0_to_9=False)
enable_0_to_9=False,
enable_million=False)

normalizer_cases = chain(
parse_test_case('data/char.txt'),
Expand All @@ -98,7 +101,8 @@ class TestNormalizerDisablestandalonenumberDisable0to9:
normalizer = InverseNormalizer(
overwrite_cache=True,
enable_standalone_number=False,
enable_0_to_9=False)
enable_0_to_9=False,
enable_million=False)

normalizer_cases = chain(
parse_test_case('data/char.txt'),
Expand Down
6 changes: 5 additions & 1 deletion itn/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,16 @@ def main():
parser.add_argument('--enable_0_to_9', type=str,
default='False',
help='enable convert number 0 to 9')
parser.add_argument('--enable_million', type=str,
default='False',
help='六百万 = 6000000 if True else 600万')
args = parser.parse_args()

normalizer = InverseNormalizer(
cache_dir=args.cache_dir, overwrite_cache=args.overwrite_cache,
enable_standalone_number=str2bool(args.enable_standalone_number),
enable_0_to_9=str2bool(args.enable_0_to_9))
enable_0_to_9=str2bool(args.enable_0_to_9),
enable_million=str2bool(args.enable_million))

if args.text:
print(normalizer.tag(args.text))
Expand Down