From 1763dc81cba5e1577c6b63e8d935327de95e5993 Mon Sep 17 00:00:00 2001 From: LoganLiu66 <2319277867@qq.com> Date: Thu, 17 Oct 2024 14:12:11 +0800 Subject: [PATCH 1/9] [tn] support Japanese TN --- tn/japanese/__init__.py | 0 tn/japanese/data/char/common_chinese_char.tsv | 2502 +++++++++++++++++ .../data/char/fullwidth_to_halfwidth.tsv | 95 + .../data/char/hiragana_and_katakana.tsv | 160 ++ tn/japanese/data/char/oov_tags.tsv | 1 + tn/japanese/data/char/punctuations_ja.tsv | 72 + tn/japanese/data/date/d.tsv | 31 + tn/japanese/data/date/date.tsv | 7 + tn/japanese/data/date/dd.tsv | 9 + tn/japanese/data/date/m.tsv | 12 + tn/japanese/data/date/mm.tsv | 9 + tn/japanese/data/default/blacklist.tsv | 0 tn/japanese/data/default/whitelist.tsv | 14 + tn/japanese/data/math/operator.tsv | 7 + tn/japanese/data/measure/units_en.tsv | 100 + tn/japanese/data/measure/units_ja.tsv | 45 + tn/japanese/data/money/code.tsv | 24 + tn/japanese/data/money/symbol.tsv | 11 + tn/japanese/data/number/digit.tsv | 18 + tn/japanese/data/number/dot.tsv | 1 + tn/japanese/data/number/en_digit.tsv | 18 + tn/japanese/data/number/sign.tsv | 3 + tn/japanese/data/number/teen.tsv | 18 + tn/japanese/data/number/zero.tsv | 2 + tn/japanese/data/sport/club.tsv | 31 + tn/japanese/data/sport/country.tsv | 185 ++ tn/japanese/data/time/hour.tsv | 34 + tn/japanese/data/time/minute.tsv | 60 + tn/japanese/data/time/noon.tsv | 10 + tn/japanese/data/time/second.tsv | 60 + tn/japanese/normalizer.py | 86 + tn/japanese/rules/cardinal.py | 90 + tn/japanese/rules/char.py | 29 + tn/japanese/rules/date.py | 81 + tn/japanese/rules/fraction.py | 41 + tn/japanese/rules/math.py | 48 + tn/japanese/rules/measure.py | 50 + tn/japanese/rules/money.py | 43 + tn/japanese/rules/postprocessor.py | 54 + tn/japanese/rules/preprocessor.py | 32 + tn/japanese/rules/sport.py | 47 + tn/japanese/rules/time.py | 52 + tn/japanese/rules/whitelist.py | 37 + tn/japanese/test/__init__.py | 0 tn/japanese/test/data/cardinal.txt | 18 + tn/japanese/test/data/char.txt | 2 + tn/japanese/test/data/date.txt | 15 + tn/japanese/test/data/fraction.txt | 3 + tn/japanese/test/data/math.txt | 26 + tn/japanese/test/data/measure.txt | 10 + tn/japanese/test/data/money.txt | 7 + tn/japanese/test/data/normalizer.txt | 110 + tn/japanese/test/data/sport.txt | 5 + tn/japanese/test/data/time.txt | 8 + tn/japanese/test/data/whitelist.txt | 4 + tn/japanese/test/normalizer_test.py | 40 + tn/japanese/test/utils.py | 1 + tn/main.py | 9 +- 58 files changed, 4486 insertions(+), 1 deletion(-) create mode 100644 tn/japanese/__init__.py create mode 100644 tn/japanese/data/char/common_chinese_char.tsv create mode 100644 tn/japanese/data/char/fullwidth_to_halfwidth.tsv create mode 100644 tn/japanese/data/char/hiragana_and_katakana.tsv create mode 100644 tn/japanese/data/char/oov_tags.tsv create mode 100644 tn/japanese/data/char/punctuations_ja.tsv create mode 100644 tn/japanese/data/date/d.tsv create mode 100644 tn/japanese/data/date/date.tsv create mode 100644 tn/japanese/data/date/dd.tsv create mode 100644 tn/japanese/data/date/m.tsv create mode 100644 tn/japanese/data/date/mm.tsv create mode 100644 tn/japanese/data/default/blacklist.tsv create mode 100644 tn/japanese/data/default/whitelist.tsv create mode 100644 tn/japanese/data/math/operator.tsv create mode 100644 tn/japanese/data/measure/units_en.tsv create mode 100644 tn/japanese/data/measure/units_ja.tsv create mode 100644 tn/japanese/data/money/code.tsv create mode 100644 tn/japanese/data/money/symbol.tsv create mode 100644 tn/japanese/data/number/digit.tsv create mode 100644 tn/japanese/data/number/dot.tsv create mode 100644 tn/japanese/data/number/en_digit.tsv create mode 100644 tn/japanese/data/number/sign.tsv create mode 100644 tn/japanese/data/number/teen.tsv create mode 100644 tn/japanese/data/number/zero.tsv create mode 100644 tn/japanese/data/sport/club.tsv create mode 100644 tn/japanese/data/sport/country.tsv create mode 100644 tn/japanese/data/time/hour.tsv create mode 100644 tn/japanese/data/time/minute.tsv create mode 100644 tn/japanese/data/time/noon.tsv create mode 100644 tn/japanese/data/time/second.tsv create mode 100644 tn/japanese/normalizer.py create mode 100644 tn/japanese/rules/cardinal.py create mode 100644 tn/japanese/rules/char.py create mode 100644 tn/japanese/rules/date.py create mode 100644 tn/japanese/rules/fraction.py create mode 100644 tn/japanese/rules/math.py create mode 100644 tn/japanese/rules/measure.py create mode 100644 tn/japanese/rules/money.py create mode 100644 tn/japanese/rules/postprocessor.py create mode 100644 tn/japanese/rules/preprocessor.py create mode 100644 tn/japanese/rules/sport.py create mode 100644 tn/japanese/rules/time.py create mode 100644 tn/japanese/rules/whitelist.py create mode 100644 tn/japanese/test/__init__.py create mode 100644 tn/japanese/test/data/cardinal.txt create mode 100644 tn/japanese/test/data/char.txt create mode 100644 tn/japanese/test/data/date.txt create mode 100644 tn/japanese/test/data/fraction.txt create mode 100644 tn/japanese/test/data/math.txt create mode 100644 tn/japanese/test/data/measure.txt create mode 100644 tn/japanese/test/data/money.txt create mode 100644 tn/japanese/test/data/normalizer.txt create mode 100644 tn/japanese/test/data/sport.txt create mode 100644 tn/japanese/test/data/time.txt create mode 100644 tn/japanese/test/data/whitelist.txt create mode 100644 tn/japanese/test/normalizer_test.py create mode 120000 tn/japanese/test/utils.py diff --git a/tn/japanese/__init__.py b/tn/japanese/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tn/japanese/data/char/common_chinese_char.tsv b/tn/japanese/data/char/common_chinese_char.tsv new file mode 100644 index 0000000..f047193 --- /dev/null +++ b/tn/japanese/data/char/common_chinese_char.tsv @@ -0,0 +1,2502 @@ +尽 +愼 +霸 +伯 +健 +市 +盤 +萬 +致 +奈 +眺 +衞 +声 +徹 +衣 +比 +巡 +革 +謡 +険 +玄 +獸 +沈 +商 +住 +艦 +傳 +祈 +彰 +渓 +酸 +刹 +苗 +齢 +詠 +號 +盛 +薰 +昨 +敢 +背 +陛 +貌 +等 +怖 +大 +丘 +到 +緖 +門 +瀨 +然 +貢 +録 +裕 +咲 +耕 +勅 +梨 +三 +授 +謹 +斥 +田 +視 +貸 +緩 +降 +杉 +濯 +童 +竊 +薦 +靴 +既 +胴 +沸 +渡 +卑 +方 +爲 +罪 +図 +命 +俵 +蛍 +彙 +甚 +腕 +圍 +会 +損 +腸 +俸 +沃 +寺 +諦 +峠 +朕 +鯨 +泣 +枢 +確 +蔵 +熊 +邪 +遺 +給 +遲 +辣 +莊 +發 +陽 +雑 +把 +昔 +和 +騎 +種 +卷 +誰 +乙 +紅 +零 +汚 +詰 +蓄 +剛 +拉 +遅 +餌 +渋 +合 +統 +映 +踊 +漁 +腰 +瓦 +王 +存 +孤 +擇 +旨 +併 +渴 +還 +知 +餘 +井 +渦 +戀 +凶 +餓 +逸 +亡 +犯 +舗 +刻 +今 +嫌 +形 +売 +詣 +諸 +廃 +貧 +忠 +后 +架 +祥 +雲 +葉 +加 +化 +心 +錄 +継 +搾 +般 +蜂 +捜 +負 +尾 +空 +洗 +回 +行 +沖 +太 +偉 +坊 +刈 +虎 +恭 +朴 +暑 +君 +悠 +尚 +思 +增 +汰 +虛 +響 +輪 +漂 +乘 +書 +打 +捗 +現 +弐 +邊 +軍 +植 +鼻 +頻 +迭 +蟲 +擁 +汽 +官 +干 +抵 +慣 +傾 +非 +迫 +微 +是 +拓 +純 +出 +排 +勤 +薫 +福 +社 +醜 +諾 +峽 +浴 +若 +舟 +契 +聞 +詮 +庫 +妊 +帯 +丙 +以 +塀 +柵 +詔 +錮 +瀧 +塩 +元 +遡 +煮 +殉 +脂 +陶 +去 +癡 +候 +稲 +慢 +眠 +穩 +討 +巾 +訟 +貳 +勝 +支 +深 +蚕 +探 +党 +堂 +乗 +龍 +象 +數 +澄 +人 +峰 +魚 +粹 +喚 +丹 +輩 +奮 +墜 +廉 +懸 +退 +譽 +概 +裝 +糾 +械 +喝 +寛 +丁 +者 +置 +洋 +九 +繊 +瞳 +斤 +夜 +瘍 +隆 +爆 +赦 +御 +哀 +雌 +提 +姉 +賓 +歌 +諧 +芽 +挨 +仕 +音 +府 +買 +依 +錦 +祉 +待 +催 +浮 +塀 +泥 +櫻 +払 +麓 +崖 +切 +物 +織 +西 +縄 +妙 +賂 +緻 +郡 +眞 +悟 +憲 +製 +郞 +静 +俊 +県 +團 +基 +車 +叔 +界 +驅 +陪 +班 +繁 +苛 +博 +伏 +二 +稚 +絵 +月 +賢 +乳 +滿 +具 +坂 +兼 +労 +聲 +讀 +仰 +隱 +材 +顯 +英 +免 +沙 +枠 +弁 +拙 +組 +砲 +固 +髄 +歡 +天 +凍 +副 +肘 +柱 +款 +崇 +由 +鍊 +瀬 +麵 +軌 +妹 +林 +徑 +舷 +匂 +祉 +拠 +係 +着 +旧 +盡 +北 +挙 +赤 +宝 +阻 +諮 +疑 +淡 +毛 +夕 +将 +近 +斷 +擴 +鉛 +惠 +弟 +極 +妻 +誉 +珍 +突 +畳 +放 +券 +圈 +賓 +妄 +海 +猫 +嫡 +紫 +薄 +褐 +刷 +壯 +送 +堕 +挟 +毆 +憬 +綻 +獲 +粧 +晴 +中 +幣 +柿 +旅 +飢 +飛 +本 +症 +紛 +服 +営 +滞 +但 +罐 +済 +審 +家 +須 +程 +票 +自 +爽 +米 +寡 +詳 +角 +泡 +倒 +稿 +戦 +災 +距 +捕 +族 +璧 +坪 +毎 +阪 +路 +得 +品 +尻 +蛇 +樂 +淑 +茶 +聴 +学 +施 +運 +海 +策 +弥 +憾 +莖 +削 +膳 +隻 +積 +浜 +濫 +尋 +臨 +灣 +詞 +許 +列 +伎 +豪 +斉 +婦 +斗 +芸 +療 +俳 +評 +幼 +他 +励 +希 +築 +南 +麻 +寒 +町 +必 +典 +一 +儀 +匠 +紹 +呂 +歷 +艶 +廣 +煎 +奔 +頑 +摯 +剖 +茨 +怨 +私 +寶 +減 +陷 +管 +盜 +條 +留 +込 +玩 +德 +永 +答 +薬 +軽 +国 +頭 +頒 +仏 +罰 +口 +齡 +龜 +署 +謙 +麦 +科 +白 +驗 +岡 +互 +愛 +囲 +氷 +卸 +周 +勉 +翌 +嚇 +浅 +案 +直 +姿 +座 +五 +藝 +索 +獨 +塞 +所 +礁 +菌 +呪 +撃 +拜 +冒 +伐 +胆 +没 +濕 +仙 +佳 +隣 +栄 +曆 +楷 +笛 +吟 +怠 +寄 +腹 +弱 +驛 +灰 +俗 +那 +改 +器 +亜 +兒 +凝 +輕 +連 +操 +取 +駄 +態 +絲 +訂 +梅 +昼 +測 +禍 +糸 +母 +衰 +春 +拳 +暑 +漫 +瑠 +卓 +押 +儒 +嵐 +猛 +麗 +逸 +奨 +感 +制 +線 +軟 +圖 +病 +舌 +懲 +謁 +硬 +垂 +肢 +懷 +江 +鈍 +葬 +正 +望 +吉 +踐 +翻 +末 +脅 +且 +袋 +電 +芋 +隅 +却 +碁 +作 +妃 +貫 +量 +同 +笑 +栓 +稱 +遭 +拒 +敏 +朽 +試 +競 +長 +筆 +兵 +召 +皿 +兩 +禁 +看 +妖 +揭 +憂 +壊 +濟 +涉 +牧 +卵 +問 +徒 +畔 +蓋 +膽 +土 +己 +叫 +禮 +建 +頻 +載 +略 +恒 +暖 +混 +内 +岐 +財 +箱 +窓 +硏 +劍 +奥 +止 +擧 +応 +苦 +鮮 +遍 +傍 +申 +繁 +抹 +徵 +濱 +顧 +結 +上 +否 +采 +藍 +倍 +幹 +殘 +歓 +睦 +犬 +肖 +逓 +胸 +塁 +謎 +成 +鳴 +錬 +添 +惧 +雪 +墓 +特 +波 +百 +寸 +璃 +債 +詩 +企 +剤 +木 +喩 +庭 +広 +避 +新 +葛 +系 +防 +娘 +卑 +曇 +星 +冗 +墨 +吐 +欠 +彫 +敕 +賀 +鑛 +戚 +鷄 +頼 +才 +穗 +猶 +集 +僚 +壌 +暮 +段 +蔑 +騒 +醸 +懐 +衝 +従 +偏 +唾 +侮 +報 +員 +潛 +粗 +刃 +利 +畜 +犧 +戻 +恵 +繩 +術 +習 +攝 +腎 +脳 +遞 +配 +氣 +國 +劇 +釣 +應 +劾 +埼 +鉢 +媒 +稼 +級 +勸 +節 +棋 +穴 +憶 +四 +選 +封 +妥 +唆 +網 +複 +酬 +飯 +據 +尼 +堤 +泰 +甁 +至 +縱 +責 +鹿 +因 +味 +下 +度 +肝 +場 +序 +鋳 +村 +尊 +埋 +底 +瓣 +写 +抄 +推 +耐 +断 +崩 +判 +項 +駆 +既 +擬 +含 +督 +艷 +嫉 +努 +杯 +痩 +辭 +潮 +蜜 +業 +続 +育 +演 +謹 +頃 +椅 +從 +更 +踏 +屯 +央 +養 +優 +岳 +舊 +悦 +赴 +駅 +凡 +疊 +晩 +訓 +經 +楽 +面 +陰 +違 +險 +源 +簿 +汎 +矯 +骸 +錠 +棄 +湿 +砂 +寫 +調 +幻 +穀 +争 +劑 +睡 +脊 +剰 +整 +搬 +戾 +賦 +括 +郎 +邸 +慎 +專 +晝 +昧 +伺 +章 +教 +阜 +吏 +週 +換 +臆 +炊 +満 +勤 +陣 +腐 +甲 +餅 +某 +窟 +勃 +樓 +臟 +蛮 +酷 +賄 +狙 +恆 +嘱 +嬢 +曖 +宰 +貝 +患 +遂 +厄 +桑 +卽 +總 +蚊 +攻 +暇 +較 +漢 +黃 +壁 +猿 +昇 +川 +室 +慮 +前 +団 +越 +敷 +未 +廳 +注 +億 +画 +失 +慰 +妬 +姫 +講 +験 +殴 +示 +拭 +曉 +銘 +涼 +発 +情 +石 +勧 +旬 +傷 +膜 +靜 +故 +茂 +澁 +乾 +髪 +岸 +詐 +粛 +仁 +騷 +豆 +根 +慕 +績 +剝 +誤 +秋 +役 +悼 +悪 +滝 +休 +挑 +披 +床 +地 +魂 +史 +馬 +持 +修 +騰 +夏 +橋 +氾 +領 +涙 +忌 +液 +辯 +滑 +堪 +幕 +類 +朱 +千 +経 +殖 +著 +遵 +識 +圏 +札 +釀 +丸 +粘 +禅 +榮 +握 +歐 +鏡 +穏 +導 +話 +虞 +両 +震 +飲 +的 +骨 +観 +局 +侯 +寮 +拡 +採 +汗 +肉 +桟 +護 +厚 +矛 +芯 +安 +藤 +価 +腦 +廢 +顎 +缺 +検 +殊 +欺 +水 +型 +膨 +薪 +畑 +規 +菜 +裁 +參 +姓 +鎌 +碑 +醫 +嚴 +耗 +諭 +痛 +祖 +潰 +鬱 +分 +別 +購 +寿 +步 +終 +蹴 +拍 +囑 +真 +霊 +浦 +蠻 +宇 +對 +里 +侮 +爪 +麥 +燃 +廷 +異 +狭 +淚 +欧 +河 +狂 +燥 +縦 +強 +孝 +則 +兆 +無 +良 +舞 +糖 +彈 +湯 +氏 +實 +秀 +点 +鬼 +紋 +戒 +言 +點 +雨 +槪 +興 +威 +續 +浄 +脈 +富 +肯 +慶 +援 +桜 +芝 +多 +題 +奉 +在 +閉 +循 +理 +単 +籠 +随 +盆 +窮 +轄 +総 +衷 +後 +便 +銃 +帶 +訪 +敬 +荘 +酒 +影 +砕 +生 +離 +京 +釋 +帳 +煮 +怪 +陸 +殺 +超 +転 +閥 +透 +嘲 +弦 +属 +鍋 +繼 +付 +並 +惱 +殺 +壘 +吸 +淫 +洞 +質 +磨 +迎 +稻 +甘 +跡 +效 +塚 +効 +恣 +双 +議 +伴 +殻 +皇 +署 +庶 +弄 +況 +譲 +響 +潟 +扇 +公 +想 +締 +犠 +陵 +停 +晶 +証 +宵 +遷 +搜 +雄 +毀 +賛 +令 +受 +層 +環 +朗 +円 +孔 +拷 +覆 +監 +酌 +瞭 +旺 +羨 +掛 +剩 +琴 +男 +牙 +鋼 +景 +衡 +勳 +鎮 +専 +虹 +巨 +残 +獣 +俺 +驚 +潔 +善 +社 +躍 +紡 +辱 +仮 +柔 +困 +黄 +実 +娠 +算 +挾 +常 +墮 +投 +傲 +脇 +遜 +表 +弧 +該 +叙 +都 +届 +手 +雜 +事 +准 +廊 +任 +児 +飽 +賊 +拶 +尉 +抜 +遇 +暴 +差 +勉 +読 +芳 +帝 +塊 +張 +漬 +靈 +字 +刑 +郭 +頰 +曹 +寢 +途 +縮 +与 +消 +韻 +唐 +記 +願 +歳 +惨 +涯 +慌 +賣 +節 +及 +死 +境 +獵 +牛 +子 +忙 +熟 +七 +敏 +携 +対 +履 +縫 +漏 +日 +租 +保 +際 +台 +塗 +轉 +駐 +翼 +暫 +奧 +鎖 +婆 +雰 +折 +値 +悩 +計 +篤 +毒 +均 +箋 +婿 +破 +房 +編 +繕 +鬭 +覇 +宅 +反 +誌 +青 +恐 +冷 +謝 +森 +鍵 +慨 +八 +立 +壇 +第 +焦 +衆 +鄕 +繭 +竜 +募 +課 +贈 +緯 +初 +域 +肺 +侶 +勞 +収 +沼 +齊 +早 +花 +霧 +暗 +密 +膝 +帽 +帥 +慄 +脱 +害 +老 +勾 +要 +動 +菊 +恩 +懇 +沢 +客 +遮 +相 +約 +舶 +全 +讓 +果 +玉 +飼 +滅 +秘 +疲 +往 +宣 +贈 +燒 +承 +臺 +視 +松 +鐵 +彌 +主 +傘 +僧 +穂 +奬 +旦 +端 +鉱 +來 +細 +盗 +乱 +期 +標 +堆 +樣 +警 +裂 +霜 +魔 +宛 +慘 +政 +店 +万 +察 +鼓 +漠 +湧 +径 +觸 +蠶 +恋 +隊 +季 +塚 +隔 +屬 +捨 +閲 +佐 +秩 +麺 +通 +校 +孃 +紙 +幾 +體 +武 +割 +箇 +賞 +褐 +忍 +僕 +宜 +奇 +逐 +状 +挿 +擔 +荷 +逝 +克 +流 +盟 +隆 +機 +圧 +覧 +桁 +供 +疎 +盾 +每 +布 +屋 +穀 +移 +句 +煩 +竹 +乞 +釈 +澤 +凄 +巢 +礼 +檢 +平 +貞 +尺 +酢 +撮 +務 +泳 +宙 +朝 +僅 +匿 +査 +淨 +賜 +処 +橫 +盲 +壽 +棧 +岬 +曲 +筒 +喝 +漆 +鶏 +顕 +裾 +枕 +法 +錯 +針 +絡 +溫 +意 +高 +束 +儉 +偶 +勢 +納 +勘 +唱 +栽 +順 +敍 +冊 +津 +介 +酎 +摘 +墾 +韓 +娯 +黑 +辺 +臭 +陥 +僞 +變 +光 +酵 +弊 +了 +賭 +棚 +時 +暦 +抱 +熱 +墨 +溶 +練 +祭 +鶴 +位 +鹽 +撲 +寝 +危 +惰 +邦 +胞 +研 +都 +開 +色 +魅 +隙 +舎 +粋 +風 +呉 +佛 +狀 +腺 +被 +浸 +喜 +癒 +午 +憤 +縛 +宗 +追 +撤 +謄 +露 +治 +文 +僧 +指 +血 +硫 +濃 +貨 +迅 +秒 +幸 +能 +] +彩 +畝 +兄 +格 +獻 +側 +碎 +賴 +擦 +昭 +易 +語 +彼 +歸 +雇 +精 +爵 +圓 +屈 +漸 +明 +拐 +穫 +年 +当 +駒 +摂 +速 +憧 +康 +挫 +倉 +名 +辨 +亂 +右 +重 +街 +据 +屆 +抑 +個 +淺 +臣 +棒 +難 +容 +功 +侵 +羊 +刊 +漢 +足 +槽 +壓 +析 +椎 +間 +次 +嗅 +緑 +器 +緒 +居 +扉 +触 +油 +歴 +矢 +装 +気 +信 +進 +草 +絶 +齋 +範 +鑑 +[ +礎 +顔 +肪 +綱 +道 +始 +勲 +輝 +培 +鉄 +貪 +譯 +牲 +温 +友 +士 +免 +志 +皆 +眼 +迷 +臼 +登 +絞 +糧 +創 +箸 +食 +又 +璽 +辞 +原 +潜 +余 +谷 +蒸 +證 +額 +枯 +設 +郊 +説 +短 +夢 +池 +嫁 +拂 +髓 +遠 +践 +虫 +不 +冬 +襃 +席 +独 +使 +裏 +船 +達 +享 +掘 +件 +禍 +農 +祕 +群 +觀 +助 +粒 +十 +拾 +灯 +炉 +鍛 +変 +為 +資 +歯 +遣 +緣 +欄 +嶽 +拝 +瘦 +補 +者 +剣 +冥 +黙 +維 +廊 +完 +繰 +敵 +惜 +突 +来 +紺 +揮 +罵 +悲 +摩 +溪 +税 +趣 +豐 +潤 +卒 +執 +髮 +凹 +神 +義 +性 +古 +金 +冶 +輸 +入 +融 +求 +首 +普 +島 +館 +素 +譜 +收 +雅 +階 +獄 +批 +欄 +爐 +用 +復 +酔 +塑 +愁 +奪 +祖 +會 +著 +墳 +權 +働 +醒 +堀 +華 +適 +造 +緊 +喪 +串 +跳 +衛 +謀 +低 +覽 +似 +肅 +起 +共 +称 +描 +煙 +餠 +快 +愚 +交 +荒 +豫 +酪 +身 +坑 +羞 +岩 +銀 +航 +神 +戰 +掃 +弾 +民 +述 +模 +訴 +省 +闘 +予 +層 +慈 +唯 +泊 +升 +射 +眉 +猟 +侍 +單 +胃 +硝 +益 +誇 +艇 +美 +何 +桃 +飜 +見 +竝 +山 +皮 +揚 +學 +預 +照 +厘 +綿 +敗 +守 +亭 +晚 +炭 +献 +謁 +劣 +尿 +野 +借 +珠 +償 +院 +障 +縣 +黒 +錢 +偵 +旋 +誠 +銭 +惡 +訃 +外 +託 +力 +峡 +増 +戴 +當 +軒 +最 +式 +腫 +女 +畏 +談 +搭 +如 +沿 +逆 +枚 +律 +世 +陳 +勵 +好 +憩 +爭 +走 +委 +促 +宮 +虚 +掌 +費 +裸 +畫 +隨 +扶 +捉 +厳 +滯 +囚 +踪 +丈 +亀 +嘆 +征 +清 +覚 +痕 +搖 +例 +措 +壹 +伸 +醉 +郵 +歩 +惑 +鳥 +豚 +狹 +呈 +鋭 +渉 +激 +左 +占 +体 +恨 +區 +捻 +湖 +痘 +累 +番 +控 +殿 +戸 +可 +有 +先 +勇 +難 +偽 +與 +過 +鈴 +診 +壮 +愉 +園 +貴 +泌 +倂 +禪 +誓 +藏 +罷 +翁 +關 +粉 +巧 +姻 +率 +臭 +悔 +区 +雙 +贊 +再 +我 +藻 +默 +倹 +準 +技 +孫 +担 +返 +啓 +賃 +鎭 +巣 +溝 +択 +横 +洪 +活 +寂 +解 +丼 +婚 +念 +謠 +宴 +港 +喫 +練 +濁 +久 +決 +引 +刺 +將 +香 +職 +凸 +畿 +祈 +逮 +請 +吹 +烈 +類 +昆 +籍 +宿 +幽 +様 +派 +倫 +曽 +臓 +父 +楼 +参 +羽 +頂 +巻 +憎 +褒 +急 +諸 +机 +梅 +遊 +息 +条 +誘 +聖 +旗 +菓 +唇 +各 +定 +梗 +向 +癖 +縁 +窃 +嘆 +像 +貯 +延 +肌 +産 +少 +充 +片 +汁 +胎 +城 +半 +湾 +庁 +咽 +郷 +筋 +滴 +柄 +祝 +関 +祥 +振 +乏 +肥 +忘 +磁 +散 +塔 +塾 +包 +窒 +祝 +襲 +襟 +符 +樞 +懲 +扱 +豊 +究 +斬 +東 +肩 +耳 +痴 +棺 +柳 +虜 +渇 +擊 +染 +溺 +羅 +壤 +怒 +假 +附 +絹 +協 +痢 +逃 +鑄 +股 +寧 +喉 +就 +徐 +奴 +代 +泉 +帆 +核 +除 +棟 +噴 +認 +夫 +救 +價 +仲 +辛 +工 +誕 +告 +伝 +替 +紀 +浪 +即 +弓 +号 +亞 +堅 +板 +庸 +部 +雷 +斎 +炎 +司 +目 +匹 +螢 +鐘 +販 +斑 +閣 +拔 +樹 +窯 +聽 +傑 +呼 +州 +招 +缶 +暁 +壱 +齒 +碑 +嗣 +数 +哺 +揺 +營 +寬 +帰 +抽 +展 +脚 +斜 +媛 +飾 +医 +唄 +料 +需 +藩 +弔 +貿 +曾 +妨 +瓶 +拘 +権 +萎 +虜 +稽 +論 +欲 +插 +疫 +師 +朗 +綠 +限 +疾 +繪 +狩 +𠮟 +壞 +憎 +構 +頓 +膚 +纖 +燈 +栃 +銅 +版 +垣 +虐 +抗 +備 +處 +冠 +接 +六 +殼 +閑 +親 +隷 +奏 +貼 +慨 +藥 +落 +賠 +曜 +闇 +戲 +幅 +考 +刀 +徳 +焼 +恥 +塡 +茎 +掲 +徴 +小 +黨 +簡 +隠 +訳 +株 +軸 +崎 +球 +倣 +火 +枝 +覺 +袖 +紳 +印 +釜 +哲 +戯 +蔽 +悔 +福 +瞬 +滋 \ No newline at end of file diff --git a/tn/japanese/data/char/fullwidth_to_halfwidth.tsv b/tn/japanese/data/char/fullwidth_to_halfwidth.tsv new file mode 100644 index 0000000..068c215 --- /dev/null +++ b/tn/japanese/data/char/fullwidth_to_halfwidth.tsv @@ -0,0 +1,95 @@ +, , +。 . +. . +“ " +” " +! ! +" " +# # +% % +& & +' ' +( ( +) ) +* * ++ + +- - +/ / +: : +; ; +< < += = +> > +? ? +@ @ +\ \ +^ ^ +_ _ +` ` +{ { +| | +} } +~ ~ +$ $ +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +a a +A A +b b +B B +c c +C C +d d +D D +e e +E E +f f +F F +g g +G G +h h +H H +i i +I I +j j +J J +k k +K K +l l +L L +m m +M M +n n +N N +o o +O O +p p +P P +q q +Q Q +r r +R R +s s +S S +t t +T T +u u +U U +v v +V V +w w +W W +x x +X X +y y +Y Y +z z +Z Z diff --git a/tn/japanese/data/char/hiragana_and_katakana.tsv b/tn/japanese/data/char/hiragana_and_katakana.tsv new file mode 100644 index 0000000..d09d8a1 --- /dev/null +++ b/tn/japanese/data/char/hiragana_and_katakana.tsv @@ -0,0 +1,160 @@ +あ +い +う +え +お +か +き +く +け +こ +さ +し +す +せ +そ +た +ち +つ +て +と +な +に +ぬ +ね +の +は +ひ +ふ +へ +ほ +ま +み +む +め +も +や +ゆ +よ +ら +り +る +れ +ろ +わ +を +ん +ア +イ +ウ +エ +オ +カ +キ +ク +ケ +コ +サ +シ +ス +セ +ソ +タ +チ +ツ +テ +ト +ナ +ニ +ヌ +ネ +ノ +ハ +ヒ +フ +ヘ +ホ +マ +ミ +ム +メ +モ +ヤ +ユ +ヨ +ラ +リ +ル +レ +ロ +ワ +ヲ +ン +が +ぎ +ぐ +げ +ご +ざ +じ +ず +ぜ +ぞ +だ +ぢ +づ +で +ど +ば +び +ぶ +べ +ぼ +ぱ +ぴ +ぷ +ぺ +ぽ +ガ +ギ +グ +ゲ +ゴ +ザ +ジ +ズ +ゼ +ゾ +ダ +ヂ +ヅ +デ +ド +バ +ビ +ブ +ベ +ボ +パ +ピ +プ +ペ +ポ +ャ +ァ +ィ +ュ +ッ +ゥ +ェ +ョ +ォ +ぁ +ぃ +ぅ +ぇ +ぉ +っ +ゃ +ゅ +ょ \ No newline at end of file diff --git a/tn/japanese/data/char/oov_tags.tsv b/tn/japanese/data/char/oov_tags.tsv new file mode 100644 index 0000000..8902fe6 --- /dev/null +++ b/tn/japanese/data/char/oov_tags.tsv @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tn/japanese/data/char/punctuations_ja.tsv b/tn/japanese/data/char/punctuations_ja.tsv new file mode 100644 index 0000000..169cc4d --- /dev/null +++ b/tn/japanese/data/char/punctuations_ja.tsv @@ -0,0 +1,72 @@ +! +? +。 +。 +" +# +$ +% +& +' +( +) +* ++ +, +- +/ +: +; +< += +> +@ +[ +\ +] +^ +_ +` +{ +| +} +~ +⦅ +⦆ +「 +」 +、 +、 +〃 +》 +「 +」 +『 +』 +【 +】 +〔 +〕 +〖 +〗 +〘 +〙 +〚 +〛 +〜 +〝 +〞 +〟 +〰 +– +— +‘ +’ +‛ +“ +” +„ +‟ +… +‧ +﹏ \ No newline at end of file diff --git a/tn/japanese/data/date/d.tsv b/tn/japanese/data/date/d.tsv new file mode 100644 index 0000000..d0df2d1 --- /dev/null +++ b/tn/japanese/data/date/d.tsv @@ -0,0 +1,31 @@ +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 三十一日 \ No newline at end of file diff --git a/tn/japanese/data/date/date.tsv b/tn/japanese/data/date/date.tsv new file mode 100644 index 0000000..484a8f7 --- /dev/null +++ b/tn/japanese/data/date/date.tsv @@ -0,0 +1,7 @@ +月 月曜日 +火 火曜日 +水 水曜日 +木 木曜日 +金 金曜日 +土 土曜日 +日 日曜日 \ No newline at end of file diff --git a/tn/japanese/data/date/dd.tsv b/tn/japanese/data/date/dd.tsv new file mode 100644 index 0000000..1ce1af7 --- /dev/null +++ b/tn/japanese/data/date/dd.tsv @@ -0,0 +1,9 @@ +01 一日 +02 二日 +03 三日 +04 四日 +05 五日 +06 六日 +07 七日 +08 八日 +09 九日 \ No newline at end of file diff --git a/tn/japanese/data/date/m.tsv b/tn/japanese/data/date/m.tsv new file mode 100644 index 0000000..0339235 --- /dev/null +++ b/tn/japanese/data/date/m.tsv @@ -0,0 +1,12 @@ +1 一月 +2 二月 +3 三月 +4 四月 +5 五月 +6 六月 +7 七月 +8 八月 +9 九月 +10 十月 +11 十一月 +12 十二月 \ No newline at end of file diff --git a/tn/japanese/data/date/mm.tsv b/tn/japanese/data/date/mm.tsv new file mode 100644 index 0000000..263db88 --- /dev/null +++ b/tn/japanese/data/date/mm.tsv @@ -0,0 +1,9 @@ +01 一月 +02 二月 +03 三月 +04 四月 +05 五月 +06 六月 +07 七月 +08 八月 +09 九月 \ No newline at end of file diff --git a/tn/japanese/data/default/blacklist.tsv b/tn/japanese/data/default/blacklist.tsv new file mode 100644 index 0000000..e69de29 diff --git a/tn/japanese/data/default/whitelist.tsv b/tn/japanese/data/default/whitelist.tsv new file mode 100644 index 0000000..1ed2327 --- /dev/null +++ b/tn/japanese/data/default/whitelist.tsv @@ -0,0 +1,14 @@ +B2B B to B +M.V.P M V P +O2O O to O +P2P P to P +BY2 BY TWO +By2 By Two +R-18 R十八 +r-18 R十八 +M-1 Mワン +M-1 Mワン +M1 Mワン +M1 Mワン +FOREVER21 FOREVERトゥエンティーワン +@ アットマーク \ No newline at end of file diff --git a/tn/japanese/data/math/operator.tsv b/tn/japanese/data/math/operator.tsv new file mode 100644 index 0000000..f896b36 --- /dev/null +++ b/tn/japanese/data/math/operator.tsv @@ -0,0 +1,7 @@ +× カケル +- マイナス ++ プラス += イコール +÷ ワル +~ から +: 対 \ No newline at end of file diff --git a/tn/japanese/data/measure/units_en.tsv b/tn/japanese/data/measure/units_en.tsv new file mode 100644 index 0000000..17e2dea --- /dev/null +++ b/tn/japanese/data/measure/units_en.tsv @@ -0,0 +1,100 @@ +g グラム +kg キログラム +mg ミリグラム +µg マイクログラム +oz オンス +t トン +lb ポンド +cm センチメートル +m メートル +km キロメートル +dm デシメートル +mm ミリメートル +μm マイクロメートル +nm ナノメートル +ft フィート +h 時 +hour 時 +min 分 +sec 秒 +s 秒 +ms ミリ秒 +°C 摂氏温度 +℃ 摂氏温度 +°F 華氏温度 +mm² 平方ミリメートル +cm² 平方センチメートル +m² 平方メートル +km² 平方キロメートル +ha ヘクタール +ml ミリリットル +L リットル +mm³ 立方ミリメートル +cm³ 立方センチメートル +gal ガロン +m³ 立方メートル +mol モル +μmol マイクロモル +nmol ナノモル +mmol ミリモル +cd カンデラ +Lm ルーメン +Lux ルクス +lm ルーメン +fpm フィート毎分 +fph フィート毎時 +fps フィート毎秒 +mpm マイル毎分 +ips インチ毎秒 +ipm インチ毎分 +mph マイル毎時 +mps マイル毎秒 +in インチ +mi マイル +s² 毎秒毎秒 +s³ 毎秒毎秒毎秒 +kn ノット +° 度 +' 分 +Pa パスカル +N/m² パスカル +pz ピエーズ +N ニュートン +mmHg 水銀柱ミリメートル +hPa ヘクトパスカル +MPa メガパスカル +mbar ミリバール +bar バール +J ジュール +kcal キロカロリー +cal カロリー +KCal キロカロリー +Cal カロリー +W ワット +kWh キロワットアワー +kW キロワット +J·s ジュール秒 +A アンペア +V ボルト +Ω オーム +A/m アンペア毎メートル +Wb ウェーバ +mAh ミリアンペアアワー +Pa·s パスカル秒 +Bq ベクレル +Gy グレイ +rad ラド +Sv シーベルト +rem レム +kat カタール +Np ネーパ +Hz ヘルツ +dB デシベル +hz ヘルツ +bit ビット +Byte バイト +byte バイト +MB メガバイト +KB キロバイト +GB ギガバイト +TB テラバイト \ No newline at end of file diff --git a/tn/japanese/data/measure/units_ja.tsv b/tn/japanese/data/measure/units_ja.tsv new file mode 100644 index 0000000..018742a --- /dev/null +++ b/tn/japanese/data/measure/units_ja.tsv @@ -0,0 +1,45 @@ +つ +枚 +部 +台 +杯 +匹 +本 +階 +個 +箇 +个 +ヶ +面 +名 +人 +歳 +才 +冊 +話 +秒 +分 +月 +泊 +時 +時間 +日 +ヶ月 +箇月 +年 +日 +週 +倍 +番 +度 +畳 +回 +年前 +年後 +年以内 +平方 +平方メートル +立方 +立方メートル +キロ +キロメトル \ No newline at end of file diff --git a/tn/japanese/data/money/code.tsv b/tn/japanese/data/money/code.tsv new file mode 100644 index 0000000..8f7fa9e --- /dev/null +++ b/tn/japanese/data/money/code.tsv @@ -0,0 +1,24 @@ +A$ 豪ドル +AED UAEディルハム +ARS アルゼンチンペソ +AUD 豪ドル +CAD$ カナダドル +CAD カナダドル +CHF スイスフラン +CNY 人民元 +EUR ユーロ +GBP ポンド +HK$ 香港ドル +HKD 香港ドル +INR インドルピー +J¥ 円 +JPY¥ 円 +JPY 円 +KRW ウォン +RUB ロシアルーブル +SAR サウジリヤル +SEK スウェーデンクローナ +SGD シンガポールドル +THB タイバーツ +TRY トルコリラ +USD アメリカドル diff --git a/tn/japanese/data/money/symbol.tsv b/tn/japanese/data/money/symbol.tsv new file mode 100644 index 0000000..61e2d73 --- /dev/null +++ b/tn/japanese/data/money/symbol.tsv @@ -0,0 +1,11 @@ +$ ドル +£ ポンド +£ ポンド +¥ 円 +¥ 円 +฿ バーツ +€ ユーロ +₹ インドルピー +₽ ルーブル +CHF スイスフラン +R$ レアル diff --git a/tn/japanese/data/number/digit.tsv b/tn/japanese/data/number/digit.tsv new file mode 100644 index 0000000..b6b4ae0 --- /dev/null +++ b/tn/japanese/data/number/digit.tsv @@ -0,0 +1,18 @@ +1 一 +2 二 +3 三 +4 四 +5 五 +6 六 +7 七 +8 八 +9 九 +1 一 +2 二 +3 三 +4 四 +5 五 +6 六 +7 七 +8 八 +9 九 diff --git a/tn/japanese/data/number/dot.tsv b/tn/japanese/data/number/dot.tsv new file mode 100644 index 0000000..ae90278 --- /dev/null +++ b/tn/japanese/data/number/dot.tsv @@ -0,0 +1 @@ +. 点 diff --git a/tn/japanese/data/number/en_digit.tsv b/tn/japanese/data/number/en_digit.tsv new file mode 100644 index 0000000..108c8c9 --- /dev/null +++ b/tn/japanese/data/number/en_digit.tsv @@ -0,0 +1,18 @@ +1 いち +2 に +3 さん +4 よん +5 ご +6 ろく +7 なな +8 はち +9 きゅう +1 いち +2 に +3 さん +4 よん +5 ご +6 ろく +7 なな +8 はち +9 きゅう \ No newline at end of file diff --git a/tn/japanese/data/number/sign.tsv b/tn/japanese/data/number/sign.tsv new file mode 100644 index 0000000..6a7498e --- /dev/null +++ b/tn/japanese/data/number/sign.tsv @@ -0,0 +1,3 @@ ++ プラス +± プラスマイナス +- マイナス diff --git a/tn/japanese/data/number/teen.tsv b/tn/japanese/data/number/teen.tsv new file mode 100644 index 0000000..55620af --- /dev/null +++ b/tn/japanese/data/number/teen.tsv @@ -0,0 +1,18 @@ +1 +2 二 +3 三 +4 四 +5 五 +6 六 +7 七 +8 八 +9 九 +1 +2 二 +3 三 +4 四 +5 五 +6 六 +7 七 +8 八 +9 九 diff --git a/tn/japanese/data/number/zero.tsv b/tn/japanese/data/number/zero.tsv new file mode 100644 index 0000000..1979ed8 --- /dev/null +++ b/tn/japanese/data/number/zero.tsv @@ -0,0 +1,2 @@ +0 ゼロ +0 ゼロ diff --git a/tn/japanese/data/sport/club.tsv b/tn/japanese/data/sport/club.tsv new file mode 100644 index 0000000..d3d4b51 --- /dev/null +++ b/tn/japanese/data/sport/club.tsv @@ -0,0 +1,31 @@ +FCバルセロナ +レアル・マドリード +マンチェスター・ユナイテッド +マンチェスター・シティ +バイエルン・ミュンヘン +リヴァプールFC +ユヴェントスFC +パリ・サンジェルマンFC +ACミラン +インテル・ミラノ +チェルシーFC +アーセナルFC +ボルシア・ドルトムント +トッテナム・ホットスパーFC +ASローマ +アトレティコ・マドリード +SSCナポリ +バレンシアCF +オリンピック・リヨン +オリンピック・マルセイユ +SLベンフィカ +FCポルト +アヤックス・アムステルダム +フェイエノールト +SSラツィオ +ビジャレアルCF +セビージャFC +スパルタク・モスクワ +ゼニト・サンクトペテルブルク +セルティックFC +レンジャーズFC \ No newline at end of file diff --git a/tn/japanese/data/sport/country.tsv b/tn/japanese/data/sport/country.tsv new file mode 100644 index 0000000..3127e55 --- /dev/null +++ b/tn/japanese/data/sport/country.tsv @@ -0,0 +1,185 @@ +アフガニスタン +アルバニア +アルジェリア +アンドラ +アンゴラ +アルゼンチン +アルメニア +オーストラリア +オーストリア +アゼルバイジャン +バハマ +バーレーン +バングラデシュ +バルバドス +ベラルーシ +ベルギー +ベリーズ +ベナン +ブータン +ボリビア +ボスニア・ヘルツェゴビナ +ボツワナ +ブラジル +ブルネイ +ブルガリア +ブルキナファソ +ミャンマー +ブルンジ +カーボベルデ +カンボジア +カメルーン +カナダ +中央アフリカ共和国 +チャド +チリ +中国 +コロンビア +コモロ +コスタリカ +クロアチア +キューバ +キプロス +チェコ +コンゴ民主共和国 +コンゴ共和国 +デンマーク +ジブチ +ドミニカ共和国 +ドミニカ国 +東ティモール +エクアドル +エジプト +エルサルバドル +赤道ギニア +エリトリア +エストニア +エチオピア +フィジー +フィンランド +フランス +ガボン +ガンビア +ジョージア +ドイツ +ガーナ +ギリシャ +グレナダ +グアテマラ +ギニア +ギニアビサウ +ガイアナ +ハイチ +ホンジュラス +ハンガリー +アイスランド +インド +インドネシア +イラン +イラク +アイルランド +イスラエル +イタリア +ジャマイカ +日本 +ヨルダン +カザフスタン +ケニア +北朝鮮 +韓国 +クウェート +キルギス +ラオス +ラトビア +レバノン +レソト +リベリア +リビア +リヒテンシュタイン +リトアニア +ルクセンブルク +マダガスカル +マラウイ +マレーシア +モルディブ +マリ +マルタ +モーリタニア +モーリシャス +メキシコ +モルドバ +モナコ +モンゴル +モンテネグロ +モロッコ +モザンビーク +ナミビア +ネパール +オランダ +ニュージーランド +ニカラグア +ニジェール +ナイジェリア +ノルウェー +オマーン +パキスタン +パナマ +パプアニューギニア +パラグアイ +ペルー +フィリピン +ポーランド +ポルトガル +カタール +ルーマニア +ロシア +ルワンダ +セントクリストファー・ネイビス +セントルシア +セントビンセントおよびグレナディーン諸島 +サモア +サンマリノ +サウジアラビア +セネガル +セルビア +セーシェル +シエラレオネ +シンガポール +スロバキア +スロベニア +ソロモン諸島 +ソマリア +南アフリカ +南スーダン +スペイン +スリランカ +スーダン +スリナム +エスワティニ +スウェーデン +スイス +シリア +タジキスタン +タンザニア +タイ +東ティモール +トーゴ +トンガ +トリニダード・トバゴ +チュニジア +トルコ +トルクメニスタン +ツバル +ウガンダ +ウクライナ +アラブ首長国連邦 +イギリス +アメリカ +ウルグアイ +ウズベキスタン +バヌアツ +ベネズエラ +ベトナム +イエメン +ザンビア +ジンバブエ \ No newline at end of file diff --git a/tn/japanese/data/time/hour.tsv b/tn/japanese/data/time/hour.tsv new file mode 100644 index 0000000..bedfb76 --- /dev/null +++ b/tn/japanese/data/time/hour.tsv @@ -0,0 +1,34 @@ +1 一時 +2 两時 +3 三時 +4 四時 +5 五時 +6 六時 +7 七時 +8 八時 +9 九時 +00 零時 +01 一時 +02 两時 +03 三時 +04 四時 +05 五時 +06 六時 +07 七時 +08 八時 +09 九時 +10 十時 +11 十一時 +12 十二時 +13 十三時 +14 十四時 +15 十五時 +16 十六時 +17 十七時 +18 十八時 +19 十九時 +20 二十時 +21 二十一時 +22 二十二時 +23 二十三時 +24 二十四時 diff --git a/tn/japanese/data/time/minute.tsv b/tn/japanese/data/time/minute.tsv new file mode 100644 index 0000000..85438db --- /dev/null +++ b/tn/japanese/data/time/minute.tsv @@ -0,0 +1,60 @@ +00 +01 一分 +02 二分 +03 三分 +04 四分 +05 五分 +06 六分 +07 七分 +08 八分 +09 九分 +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 五十九分 diff --git a/tn/japanese/data/time/noon.tsv b/tn/japanese/data/time/noon.tsv new file mode 100644 index 0000000..00de74e --- /dev/null +++ b/tn/japanese/data/time/noon.tsv @@ -0,0 +1,10 @@ +a m 午前 +a.m. 午前 +am 午前 +A M 午前 +AM 午前 +p m 午後 +p.m. 午後 +pm 午後 +P M 午後 +PM 午後 diff --git a/tn/japanese/data/time/second.tsv b/tn/japanese/data/time/second.tsv new file mode 100644 index 0000000..ac6280d --- /dev/null +++ b/tn/japanese/data/time/second.tsv @@ -0,0 +1,60 @@ +00 +01 一秒 +02 二秒 +03 三秒 +04 四秒 +05 五秒 +06 六秒 +07 七秒 +08 八秒 +09 九秒 +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 五十九秒 diff --git a/tn/japanese/normalizer.py b/tn/japanese/normalizer.py new file mode 100644 index 0000000..2fcd236 --- /dev/null +++ b/tn/japanese/normalizer.py @@ -0,0 +1,86 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.japanese.rules.cardinal import Cardinal +from tn.japanese.rules.char import Char +from tn.japanese.rules.date import Date +from tn.japanese.rules.fraction import Fraction +from tn.japanese.rules.math import Math +from tn.japanese.rules.measure import Measure +from tn.japanese.rules.money import Money +from tn.japanese.rules.postprocessor import PostProcessor +from tn.japanese.rules.preprocessor import PreProcessor +from tn.japanese.rules.sport import Sport +from tn.japanese.rules.time import Time +from tn.japanese.rules.whitelist import Whitelist + +from pynini.lib.pynutil import add_weight, delete +from importlib_resources import files + + +class Normalizer(Processor): + + def __init__(self, + cache_dir=None, + overwrite_cache=False, + remove_interjections=False, + remove_puncts=False, + full_to_half=True, + tag_oov=False): + super().__init__(name='ja_normalizer') + self.remove_interjections = remove_interjections + self.remove_puncts = remove_puncts + self.full_to_half = full_to_half + self.tag_oov = tag_oov + if cache_dir is None: + cache_dir = files("tn") + self.build_fst('ja_tn', cache_dir, overwrite_cache) + + def build_tagger(self): + processor = PreProcessor(full_to_half=self.full_to_half).processor + cardinal = add_weight(Cardinal().tagger, 1.06) + char = add_weight(Char().tagger, 100) + date = add_weight(Date().tagger, 1.02) + fraction = add_weight(Fraction().tagger, 1.05) + math = add_weight(Math().tagger, 90) + measure = add_weight(Measure().tagger, 1.05) + money = add_weight(Money().tagger, 1.05) + sport = add_weight(Sport().tagger, 1.04) + time = add_weight(Time().tagger, 1.05) + whitelist = add_weight(Whitelist().tagger, 1.03) + tagger = (cardinal | char | date | fraction | math | measure | money + | sport | time | whitelist).optimize() + tagger = (processor @ tagger).star + self.tagger = tagger @ self.build_rule(delete(' '), r='[EOS]') + + def build_verbalizer(self): + cardinal = Cardinal().verbalizer + char = Char().verbalizer + date = Date().verbalizer + fraction = Fraction().verbalizer + math = Math().verbalizer + measure = Measure().verbalizer + money = Money().verbalizer + sport = Sport().verbalizer + time = Time().verbalizer + whitelist = Whitelist().verbalizer + verbalizer = (cardinal | char | date | fraction | math | measure + | money | sport | time | whitelist).optimize() + + processor = PostProcessor( + remove_interjections=self.remove_interjections, + remove_puncts=self.remove_puncts, + tag_oov=self.tag_oov).processor + self.verbalizer = (verbalizer @ processor).star diff --git a/tn/japanese/rules/cardinal.py b/tn/japanese/rules/cardinal.py new file mode 100644 index 0000000..e67319d --- /dev/null +++ b/tn/japanese/rules/cardinal.py @@ -0,0 +1,90 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file, cross +from pynini.lib.pynutil import delete, insert + + +class Cardinal(Processor): + + def __init__(self): + super().__init__(name='cardinal') + self.thousand = None + self.thousands = None + self.number = None + self.digits = None + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + zero = string_file(get_abs_path('japanese/data/number/zero.tsv')) + # 1-9 + digit = string_file(get_abs_path('japanese/data/number/digit.tsv')) + en_digit = string_file( + get_abs_path('japanese/data/number/en_digit.tsv')) + teen = string_file(get_abs_path('japanese/data/number/teen.tsv')) + sign = string_file(get_abs_path('japanese/data/number/sign.tsv')) + dot = string_file(get_abs_path('japanese/data/number/dot.tsv')) + + rmzero = delete('0') | delete('0') + rmpunct = delete(',').ques + rmspace = delete(' ').ques + + # 0-9 + digits = zero | digit + en_digits = zero | en_digit + self.digits = digits + # 10-99 + ten = teen + insert('十') + (digit | rmzero) + # 100-999 + hundred = (teen + insert('百') + (ten | (rmzero + digit) | rmzero**2)) + # 1000-9999 + thousand = (teen + insert('千') + rmpunct + (hundred + | (rmzero + ten) + | (rmzero**2 + digit) + | rmzero**3)) + self.thousand = thousand + # 10000-99999999 + ten_thousand = ((thousand | hundred | ten | digit) + insert('万') + + (thousand + | (rmzero + rmpunct + hundred) + | (rmzero + rmpunct + rmzero + ten) + | (rmzero + rmpunct + rmzero + rmzero + digit) + | rmzero**4)) + # 0-99999999 + number = digits | ten | hundred | thousand | ten_thousand + self.thousands = digits | ten | hundred | thousand + # ±0.0 - ±99999999.99999999 + number = sign.ques + number + (dot + en_digits.plus).ques + self.number = number + + # % like -27.00% + percent = number + delete('%') + insert('パーセント') + # ip like 127.0.0.1 + ip_dot = cross('.', 'ドット') + ip = en_digits.plus + (ip_dot + en_digits.plus)**3 + # phone like 0xx-xxxx-xxxx + country_code = (cross('+81', 'プラス八一') + cross('-', 'の').ques + rmspace) + phone = (zero + en_digit + zero.ques + cross('-', 'の') + en_digits**3 + + en_digits.ques + cross('-', 'の').ques + en_digits**4) + phone = country_code.ques + phone + # others like 342388491 + others = en_digits**8 + en_digits.plus + + number = number | percent | ip | phone | others + tagger = insert('value: "') + number.optimize() + insert('"') + self.tagger = self.add_tokens(tagger) diff --git a/tn/japanese/rules/char.py b/tn/japanese/rules/char.py new file mode 100644 index 0000000..f574405 --- /dev/null +++ b/tn/japanese/rules/char.py @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor + +from pynini.lib.pynutil import insert + + +class Char(Processor): + + def __init__(self): + super().__init__(name='char') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + tagger = insert('value: "') + self.CHAR + insert('"') + self.tagger = self.add_tokens(tagger) diff --git a/tn/japanese/rules/date.py b/tn/japanese/rules/date.py new file mode 100644 index 0000000..c2441fd --- /dev/null +++ b/tn/japanese/rules/date.py @@ -0,0 +1,81 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import delete, insert + + +class Date(Processor): + """ + 1日 -> 一日 + 5~9日 -> 五から九日 + 1月 -> 一月 + 3~4月 -> 三から四月 + 1月1日 -> 一月一日 + 70年代 -> 七十年代 + 70~80年代 -> 七十から八十年代 + 21世紀 -> 二十一世紀 + 2009年 -> 二千九年 + 23年2月25日(土) -> 二十三年二月二十五日土曜日 + 7月5〜9日(月〜金) -> 七月五から九日月曜日から金曜日 + 今年は令和6 -> 今年はR六 + 2019年3月2日 -> 二千十九年三月二日 + 1986年8月18日 -> 千九百八十六年八月十八日 + ---以上都可以把日期做为普通数字进行转换,以下要添加对应规则--- + 2008/08/08 -> 二千八年八月八日 + 1008/08/10 -> 千八年八月十日 + 1108/08/10 -> 千百八年八月十日 + 1000.08.10 -> 千年八月十日 + """ + + def __init__(self): + super().__init__(name='date') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + yyyy = Cardinal().thousand + m = string_file(get_abs_path('japanese/data/date/m.tsv')) + mm = string_file(get_abs_path('japanese/data/date/mm.tsv')) + d = string_file(get_abs_path('japanese/data/date/d.tsv')) + dd = string_file(get_abs_path('japanese/data/date/dd.tsv')) + rmsign = (delete('/') | delete('-') | delete('.')) + insert(' ') + + year = insert('year: "') + yyyy + insert('年"') + month = insert('month: "') + (m | mm) + insert('"') + day = insert('day: "') + (d | dd) + insert('"') + + # yyyy/m/d | yyyy/mm/dd | dd/mm/yyyy + # yyyy/0m | 0m/yyyy | 0m/dd + mm = insert('month: "') + mm + insert('"') + date = ((year + rmsign + month + rmsign + day) + | (day + rmsign + month + rmsign + year) + | (year + rmsign + mm) + | (mm + rmsign + year) + | (mm + rmsign + day)) + tagger = self.add_tokens(date) + + to = (delete('-') | delete('~')) + insert(' char { value: "から" } ') + self.tagger = tagger + (to + tagger).ques + + def build_verbalizer(self): + year = delete('year: "') + self.SIGMA + delete('" ') + month = delete('month: "') + self.SIGMA + delete('"') + day = delete(' day: "') + self.SIGMA + delete('"') + verbalizer = year.ques + month + day.ques + self.verbalizer = self.delete_tokens(verbalizer) diff --git a/tn/japanese/rules/fraction.py b/tn/japanese/rules/fraction.py new file mode 100644 index 0000000..e2b208d --- /dev/null +++ b/tn/japanese/rules/fraction.py @@ -0,0 +1,41 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor + +from pynini.lib.pynutil import delete, insert + + +class Fraction(Processor): + + def __init__(self): + super().__init__(name='fraction') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + rmspace = delete(' ').ques + number = Cardinal().number + + tagger = (insert('numerator: "') + number + rmspace + delete('/') + + rmspace + insert('" denominator: "') + number + + insert('"')).optimize() + self.tagger = self.add_tokens(tagger) + + def build_verbalizer(self): + denominator = delete('denominator: "') + self.SIGMA + delete('" ') + numerator = delete('numerator: "') + self.SIGMA + delete('"') + verbalizer = denominator + insert('の') + numerator + self.verbalizer = self.delete_tokens(verbalizer) diff --git a/tn/japanese/rules/math.py b/tn/japanese/rules/math.py new file mode 100644 index 0000000..3eb4a22 --- /dev/null +++ b/tn/japanese/rules/math.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import delete, insert + + +class Math(Processor): + + def __init__(self): + super().__init__(name="math") + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + operator = string_file(get_abs_path("japanese/data/math/operator.tsv")) + + number = Cardinal().number + operator = number + (delete(" ").ques + operator + delete(" ").ques + + number).star + bigger = operator + (delete(" ").ques + delete(">") + insert("は") + + delete(" ").ques + number + insert("より大きい")).star + smaller = operator + (delete(" ").ques + delete("<") + insert("は") + + delete(" ").ques + number + insert("より小きい")).star + no_less = operator + (delete(" ").ques + + (delete("≥") | delete(">=")) + insert("は") + + delete(" ").ques + number + insert("以上")).star + no_more = operator + (delete(" ").ques + + (delete("≤") | delete("<=")) + insert("は") + + delete(" ").ques + number + insert("以下")).star + tagger = (operator) | (bigger) | (smaller) | (no_less) | (no_more) + tagger = insert('value: "') + tagger + insert('"') + self.tagger = self.add_tokens(tagger) diff --git a/tn/japanese/rules/measure.py b/tn/japanese/rules/measure.py new file mode 100644 index 0000000..74a9221 --- /dev/null +++ b/tn/japanese/rules/measure.py @@ -0,0 +1,50 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import accep, cross, string_file +from pynini.lib.pynutil import delete, insert + + +class Measure(Processor): + + def __init__(self): + super().__init__(name='measure') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + units_en = string_file( + get_abs_path('japanese/data/measure/units_en.tsv')) + units_ja = string_file( + get_abs_path('japanese/data/measure/units_ja.tsv')) + + # taking '-' '~' as 'から' if the follwing word in units + units = (units_en | units_ja) + rmspace = delete(' ').ques + to = cross('-', 'から') | cross('~', 'から') | accep('から') + + number = Cardinal().number + # 1-11月,1月-11月 + prefix = number + (rmspace + units).ques + to + measure = prefix.ques + number + rmspace + units + measure |= (measure + rmspace + delete('/') + insert('毎') + rmspace + + units) + tagger = insert('value: "') + measure + insert('"') + + # 10km/h, 2m/s + self.tagger = self.add_tokens(tagger) diff --git a/tn/japanese/rules/money.py b/tn/japanese/rules/money.py new file mode 100644 index 0000000..3522dcb --- /dev/null +++ b/tn/japanese/rules/money.py @@ -0,0 +1,43 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import delete, insert + + +class Money(Processor): + + def __init__(self): + super().__init__(name='money') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + code = string_file(get_abs_path('japanese/data/money/code.tsv')) + symbol = string_file(get_abs_path('japanese/data/money/symbol.tsv')) + + number = Cardinal().number + tagger = (insert('currency: "') + (code | symbol) + delete(' ').ques + + insert('" ') + insert('value: "') + number + insert('"')) + self.tagger = self.add_tokens(tagger) + + def build_verbalizer(self): + value = delete('value: "') + self.SIGMA + delete('" ') + currency = delete('currency: "') + self.SIGMA + delete('"') + verbalizer = value + currency + self.verbalizer = self.delete_tokens(verbalizer) diff --git a/tn/japanese/rules/postprocessor.py b/tn/japanese/rules/postprocessor.py new file mode 100644 index 0000000..940d0bc --- /dev/null +++ b/tn/japanese/rules/postprocessor.py @@ -0,0 +1,54 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import difference, string_file +from pynini.lib.pynutil import delete +from pynini.lib.tagger import Tagger + + +class PostProcessor(Processor): + + def __init__(self, + remove_interjections=True, + remove_puncts=False, + tag_oov=False): + super().__init__(name='postprocessor') + blacklist = string_file( + get_abs_path('japanese/data/default/blacklist.tsv')) + puncts = string_file( + get_abs_path('japanese/data/char/punctuations_ja.tsv')) + # 片假名/平假名/浊音/半浊音/小写假名 + ja_charset_std = string_file( + get_abs_path('japanese/data/char/hiragana_and_katakana.tsv')) + # 日语常用汉字表 + ja_charset_ext = string_file( + get_abs_path('japanese/data/char/common_chinese_char.tsv')) + + processor = self.build_rule('') + if remove_interjections: + processor @= self.build_rule(delete(blacklist)) + + if remove_puncts: + processor @= self.build_rule(delete(puncts | self.PUNCT)) + + if tag_oov: + charset = (ja_charset_std | ja_charset_ext | puncts | self.DIGIT + | self.ALPHA | self.PUNCT | self.SPACE) + oov = difference(self.VCHAR, charset) + processor @= Tagger('oov', oov, self.VSIGMA)._tagger + + self.processor = processor.optimize() diff --git a/tn/japanese/rules/preprocessor.py b/tn/japanese/rules/preprocessor.py new file mode 100644 index 0000000..c84df4c --- /dev/null +++ b/tn/japanese/rules/preprocessor.py @@ -0,0 +1,32 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file + + +class PreProcessor(Processor): + + def __init__(self, full_to_half=True): + super().__init__(name='preprocessor') + traditional2simple = string_file( + get_abs_path('japanese/data/char/fullwidth_to_halfwidth.tsv')) + + processor = self.build_rule('') + if full_to_half: + processor @= self.build_rule(traditional2simple) + + self.processor = processor.optimize() diff --git a/tn/japanese/rules/sport.py b/tn/japanese/rules/sport.py new file mode 100644 index 0000000..e4a20c1 --- /dev/null +++ b/tn/japanese/rules/sport.py @@ -0,0 +1,47 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import delete, insert + + +class Sport(Processor): + + def __init__(self): + super().__init__(name='sport') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + country = string_file(get_abs_path('japanese/data/sport/country.tsv')) + club = string_file(get_abs_path('japanese/data/sport/club.tsv')) + rmsign = delete('/') | delete('-') | delete(':') + rmspace = delete(' ').ques + + number = Cardinal().number + score = rmspace + number + rmsign + insert('対') + number + rmspace + tagger = (insert('team: "') + (country | club) + insert('" score: "') + + score + insert('"')) + self.tagger = self.add_tokens(tagger) + + def build_verbalizer(self): + super().build_verbalizer() + team = delete('team: "') + self.SIGMA + delete('" ') + score = delete('score: "') + self.SIGMA + delete('"') + verbalizer = team + score + self.verbalizer |= self.delete_tokens(verbalizer) diff --git a/tn/japanese/rules/time.py b/tn/japanese/rules/time.py new file mode 100644 index 0000000..ecedcec --- /dev/null +++ b/tn/japanese/rules/time.py @@ -0,0 +1,52 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import delete, insert + + +class Time(Processor): + + def __init__(self): + super().__init__(name='time') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + h = string_file(get_abs_path('japanese/data/time/hour.tsv')) + m = string_file(get_abs_path('japanese/data/time/minute.tsv')) + s = string_file(get_abs_path('japanese/data/time/second.tsv')) + noon = string_file(get_abs_path('japanese/data/time/noon.tsv')) + colon = delete(':') | delete(':') + + tagger = (insert('hour: "') + h + insert('" ') + colon + + insert('minute: "') + m + insert('"') + + (colon + insert(' second: "') + s + insert('"')).ques + + delete(' ').ques + + (insert(' noon: "') + noon + insert('"')).ques) + tagger = self.add_tokens(tagger) + + to = (delete('-') | delete('~')) + insert(' char { value: "から" } ') + self.tagger = tagger + (to + tagger).ques + + def build_verbalizer(self): + noon = delete('noon: "') + self.SIGMA + delete('" ') + hour = delete('hour: "') + self.SIGMA + delete('" ') + minute = delete('minute: "') + self.SIGMA + delete('"') + second = delete(' second: "') + self.SIGMA + delete('"') + verbalizer = noon.ques + hour + minute + second.ques + self.verbalizer = self.delete_tokens(verbalizer) diff --git a/tn/japanese/rules/whitelist.py b/tn/japanese/rules/whitelist.py new file mode 100644 index 0000000..747ee0c --- /dev/null +++ b/tn/japanese/rules/whitelist.py @@ -0,0 +1,37 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import insert + + +class Whitelist(Processor): + + def __init__(self): + super().__init__(name='whitelist') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + whitelist = (string_file( + get_abs_path('japanese/data/default/whitelist.tsv'))) + + tagger = (insert('value: "') + whitelist) + insert('"') + self.tagger = self.add_tokens(tagger) + + def build_verbalizer(self): + super().build_verbalizer() diff --git a/tn/japanese/test/__init__.py b/tn/japanese/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tn/japanese/test/data/cardinal.txt b/tn/japanese/test/data/cardinal.txt new file mode 100644 index 0000000..010e9c6 --- /dev/null +++ b/tn/japanese/test/data/cardinal.txt @@ -0,0 +1,18 @@ +1118 => 千百十八 +-1118 => マイナス千百十八 +9.99999 => 九点きゅうきゅうきゅうきゅうきゅう +20099.1001 => 二万九十九点いちゼロゼロいち +11118 => 一万千百十八 +-200.001 => マイナス二百点ゼロゼロいち +100% => 百パーセント +-50.04% => マイナス五十点ゼロよんパーセント +-50.07% => マイナス五十点ゼロななパーセント +192.168.0.1 => いちきゅうにドットいちろくはちドットゼロドットいち +090-1234-5678 => ゼロきゅうゼロのいちにさんよんのごろくななはち +090-12345678 => ゼロきゅうゼロのいちにさんよんごろくななはち ++81-090-1234-5678 => プラス八一のゼロきゅうゼロのいちにさんよんのごろくななはち ++81 090-1234-5678 => プラス八一ゼロきゅうゼロのいちにさんよんのごろくななはち ++81 090-123-5678 => プラス八一ゼロきゅうゼロのいちにさんのごろくななはち ++81 09012345678 => プラス八十一 ゼロきゅうゼロいちにさんよんごろくななはち +02-1234-5678 => ゼロにのいちにさんよんのごろくななはち +1.1234567 => 一点いちにさんよんごろくなな diff --git a/tn/japanese/test/data/char.txt b/tn/japanese/test/data/char.txt new file mode 100644 index 0000000..dca416b --- /dev/null +++ b/tn/japanese/test/data/char.txt @@ -0,0 +1,2 @@ +中 => 中 +A => A diff --git a/tn/japanese/test/data/date.txt b/tn/japanese/test/data/date.txt new file mode 100644 index 0000000..1aab68e --- /dev/null +++ b/tn/japanese/test/data/date.txt @@ -0,0 +1,15 @@ +1998/04/23 => 千九百九十八年四月二十三日 +2023/11/34 => 二千二十三年十一月三日四 +2008/08 => 二千八年八月 +08/2008 => 二千八年八月 +08/08 => 八月八日 +2008-08-23 => 二千八年八月二十三日 +2008-8-8 => 二千八年八月八日 +2008-08 => 二千八年八月 +08-2008 => 二千八年八月 +08-08 => 八月八日 +2008.08.08 => 二千八年八月八日 +2008.8.8 => 二千八年八月八日 +2008.08 => 二千八年八月 +08.2008 => 二千八年八月 +08.08 => 八月八日 \ No newline at end of file diff --git a/tn/japanese/test/data/fraction.txt b/tn/japanese/test/data/fraction.txt new file mode 100644 index 0000000..3fbd90b --- /dev/null +++ b/tn/japanese/test/data/fraction.txt @@ -0,0 +1,3 @@ +1/100 => 百の一 +-1/100 => 百のマイナス一 +1 / 2 => 二の一 \ No newline at end of file diff --git a/tn/japanese/test/data/math.txt b/tn/japanese/test/data/math.txt new file mode 100644 index 0000000..b4ae038 --- /dev/null +++ b/tn/japanese/test/data/math.txt @@ -0,0 +1,26 @@ +1-2=-1 => 一マイナス二イコールマイナス一 +1+2>2 => 一プラス二は二より大きい +2:3 => 二対三 +4×5=20 => 四カケル五イコール二十 +4x5=20 => 四x五イコール二十 +1~100 => 一から百 +3>=3 => 三は三以上 +3≥2≥1 => 三は二以上は一以上 +3 ≥ 2 => 三は二以上 +2>1 => 二は一より大きい +2 > 1 => 二は一より大きい +1<2 => 一は二より小きい +5×4÷2+3-6 ≥ 7 => 五カケル四ワル二プラス三マイナス六は七以上 +1+3+2+3>3 => 一プラス三プラス二プラス三は三より大きい +1-1 => 一マイナス一 +1:1 => 一対一 +1+1 => 一プラス一 +abc/3 => abc/三 +1/3 => 三の一 +1 + 1 => 一プラス一 +±5 => プラスマイナス五 +abc+5 => abcプラス五 +1+1=2 => 一プラス一イコール二 +1+2+3=6 => 一プラス二プラス三イコール六 +911-1234-5678 => 九百十一マイナス千二百三十四マイナス五千六百七十八 +112-1234-5678 => 百十二マイナス千二百三十四マイナス五千六百七十八 \ No newline at end of file diff --git a/tn/japanese/test/data/measure.txt b/tn/japanese/test/data/measure.txt new file mode 100644 index 0000000..e58f3db --- /dev/null +++ b/tn/japanese/test/data/measure.txt @@ -0,0 +1,10 @@ +2022-2023年 => 二千二十二から二千二十三年 +1-3年 => 一から三年 +22-26年 => 二十二から二十六年 +1~3年 => 一から三年 +1-3平方 => 一から三平方 +10km/h => 十キロメートル毎時 +2m/s => 二メートル毎秒 +100fph/s => 百フィート毎時毎秒 +1-200キロ => 一から二百キロ +10-11月 => 十から十一月 \ No newline at end of file diff --git a/tn/japanese/test/data/money.txt b/tn/japanese/test/data/money.txt new file mode 100644 index 0000000..f94a3b5 --- /dev/null +++ b/tn/japanese/test/data/money.txt @@ -0,0 +1,7 @@ +USD1001 => 千一アメリカドル +HKD1002 => 千二香港ドル +¥22 => 二十二円 +¥ 22 => 二十二円 +$10000 => 一万ドル +CAD => CAD +CAD1001 => 千一カナダドル \ No newline at end of file diff --git a/tn/japanese/test/data/normalizer.txt b/tn/japanese/test/data/normalizer.txt new file mode 100644 index 0000000..8902ba9 --- /dev/null +++ b/tn/japanese/test/data/normalizer.txt @@ -0,0 +1,110 @@ +1998/04/23 +2023/11/34 +2008-08-23 +2008.8.8 +1118 +-1118 +9.99999 +20099.1001 +11118 +-200.001 +100% +-50.01% +192.168.0.1 +090-1234-5678 +090-12345678 +2000人 +せいれき せんねん じゅうがつ ついたち +P2P finance + +3:2 +3:02 +3:40am +3:40a.m. +3:40AM +3:40A M +3:30pm +3:30 +3:30-4:34 + +USD1001 +HKD1002 +¥22 +¥ 22 +$10000 +CAD +CAD1001 + +1/100 +-1/100 + +1-2=-1 +1+2>2 +2:3 +4×5=20 +4x5=20 +1~100 +3>=3 +3≥2≥1 +3 ≥ 2 +2>1 +2 > 1 +1<2 +5×4÷2+3-6 ≥ 7 +1+3+2+3>3 +<足す> +足す~ +足す: +1-1 三种读法 の 対 マイナス +1:1 +1+1 +abc/3 +1/3 +1 + 1 +±5 +abc+5 +1+1=2 +1+2+3=6 + +2022-2023年 +1-3年 +22-26年 +1~3年 +1-3平方 +10km/h +2m/s +100fph/s +1-200キロ +10-11月 + +R-18 +FOREVER21 +2319277867@qq.com +中国韓国3:2 +中国韓国3-2 +ACミラン3:2 +ACミラン3-2 +国韓3:2 +国韓3-2 + +手机号 +1-2-3 +1-2-3-4 +112 +11111111 +1111111111 +090-1234-5678 +911-1234-5678 +9000-1234-5678 +09012345678 +02-1234-5678 +112-1234-5678 ++81-090-1234-5678 ++81 090-1234-5678 ++81 090-123-5678 ++81 09012345678 ++81 911-1234-5678 +9000 + +なんぼやと思う?一万円?なんでやねん。そんな高いわけないやん。2000円やで。ちょっと古いもんやけど、そら別にかまへんわ。ええもんだったら何でもええねん。え、それはちゃう? +人名用漢字表は随時見直されており、文化的な要請や使用者の要望に応じて、新たに追加されることがあります。例えば、2004年に488字が追加され、2023年には再び改訂されて863字となりました。 \ No newline at end of file diff --git a/tn/japanese/test/data/sport.txt b/tn/japanese/test/data/sport.txt new file mode 100644 index 0000000..784bc3e --- /dev/null +++ b/tn/japanese/test/data/sport.txt @@ -0,0 +1,5 @@ +中国韓国3:2 => 中国韓国三対二 +中国韓国3-2 => 中国韓国三対二 +ACミラン3:2 => ACミラン三対二 +ACミラン3-2 => ACミラン三対二 +国韓3:2 => 国韓三対二 \ No newline at end of file diff --git a/tn/japanese/test/data/time.txt b/tn/japanese/test/data/time.txt new file mode 100644 index 0000000..fbc4714 --- /dev/null +++ b/tn/japanese/test/data/time.txt @@ -0,0 +1,8 @@ +3:02 => 三時二分 +3:40am => 午前三時四十分 +3:40a.m. => 午前三時四十分 +3:40AM => 午前三時四十分 +3:40A M => 午前三時四十分 +3:30pm => 午後三時三十分 +3:30 => 三時三十分 +3:30-4:34 => 三時三十分から四時三十四分 \ No newline at end of file diff --git a/tn/japanese/test/data/whitelist.txt b/tn/japanese/test/data/whitelist.txt new file mode 100644 index 0000000..161ed14 --- /dev/null +++ b/tn/japanese/test/data/whitelist.txt @@ -0,0 +1,4 @@ +P2P => P to P +B2B => B to B +R-18 => R十八 +FOREVER21 => FOREVERトゥエンティーワン diff --git a/tn/japanese/test/normalizer_test.py b/tn/japanese/test/normalizer_test.py new file mode 100644 index 0000000..d5a5ace --- /dev/null +++ b/tn/japanese/test/normalizer_test.py @@ -0,0 +1,40 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +from itertools import chain + +from tn.japanese.normalizer import Normalizer +from tn.japanese.test.utils import parse_test_case + + +class TestNormalizer: + + normalizer = Normalizer(overwrite_cache=True) + + normalizer_cases = chain(parse_test_case('data/cardinal.txt'), + parse_test_case('data/char.txt'), + parse_test_case('data/date.txt'), + parse_test_case('data/fraction.txt'), + parse_test_case('data/math.txt'), + parse_test_case('data/measure.txt'), + parse_test_case('data/money.txt'), + parse_test_case('data/sport.txt'), + parse_test_case('data/time.txt'), + parse_test_case('data/whitelist.txt')) + + @pytest.mark.parametrize("spoken, written", normalizer_cases) + def test_normalizer(self, spoken, written): + assert self.normalizer.normalize(spoken) == written diff --git a/tn/japanese/test/utils.py b/tn/japanese/test/utils.py new file mode 120000 index 0000000..4fa4a19 --- /dev/null +++ b/tn/japanese/test/utils.py @@ -0,0 +1 @@ +../../chinese/test/utils.py \ No newline at end of file diff --git a/tn/main.py b/tn/main.py index 3ca45f1..f805643 100644 --- a/tn/main.py +++ b/tn/main.py @@ -17,6 +17,7 @@ # TODO(pzd17 & sxc19): multi-language support from tn.chinese.normalizer import Normalizer as ZhNormalizer from tn.english.normalizer import Normalizer as EnNormalizer +from tn.japanese.normalizer import Normalizer as JaNormalizer from itn.main import str2bool @@ -58,7 +59,7 @@ def main(): parser.add_argument('--language', type=str, default='zh', - choices=["zh", "en"], + choices=["zh", "en", "ja"], help='valid languages') args = parser.parse_args() @@ -75,6 +76,12 @@ def main(): elif args.language == "en": normalizer = EnNormalizer(cache_dir=args.cache_dir, overwrite_cache=args.overwrite_cache) + elif args.language == "ja": + normalizer = JaNormalizer(cache_dir=args.cache_dir, + overwrite_cache=args.overwrite_cache, + remove_puncts=str2bool(args.remove_puncts), + full_to_half=str2bool(args.full_to_half), + tag_oov=str2bool(args.tag_oov)) if args.text: print(normalizer.tag(args.text)) From 03c869cf2d02130a33e3ae7254479e369f119983 Mon Sep 17 00:00:00 2001 From: LoganLiu66 <2319277867@qq.com> Date: Tue, 22 Oct 2024 14:28:21 +0800 Subject: [PATCH 2/9] [itn] support Japanese ITN --- itn/japanese/__init__.py | 0 .../data/char/common_chinese_char.tsv | 2502 +++++++++++++++++ .../data/char/fullwidth_to_halfwidth.tsv | 95 + .../data/char/hiragana_and_katakana.tsv | 160 ++ itn/japanese/data/char/oov_tags.tsv | 1 + itn/japanese/data/char/punctuations_ja.tsv | 72 + itn/japanese/data/date/day.tsv | 31 + itn/japanese/data/date/month.tsv | 12 + itn/japanese/data/date/week.tsv | 14 + itn/japanese/data/default/blacklist.tsv | 0 itn/japanese/data/default/whitelist.tsv | 3 + itn/japanese/data/math/operator.tsv | 7 + itn/japanese/data/measure/unit_en.tsv | 107 + itn/japanese/data/measure/unit_ja.tsv | 47 + itn/japanese/data/money/currency.tsv | 35 + itn/japanese/data/number/digit.tsv | 9 + itn/japanese/data/number/dot.tsv | 1 + itn/japanese/data/number/hundred.tsv | 1 + itn/japanese/data/number/hundred_digit.tsv | 9 + itn/japanese/data/number/sign.tsv | 4 + itn/japanese/data/number/teen.tsv | 10 + itn/japanese/data/number/thousands.tsv | 9 + itn/japanese/data/number/ties.tsv | 8 + itn/japanese/data/number/zero.tsv | 3 + itn/japanese/data/time/hour.tsv | 34 + itn/japanese/data/time/minute.tsv | 60 + itn/japanese/data/time/second.tsv | 60 + itn/japanese/inverse_normalizer.py | 86 + itn/japanese/rules/__init__.py | 0 itn/japanese/rules/cardinal.py | 172 ++ itn/japanese/rules/char.py | 29 + itn/japanese/rules/date.py | 72 + itn/japanese/rules/fraction.py | 67 + itn/japanese/rules/math.py | 39 + itn/japanese/rules/measure.py | 48 + itn/japanese/rules/ordinal.py | 33 + itn/japanese/rules/postprocessor.py | 55 + itn/japanese/rules/preprocessor.py | 33 + itn/japanese/rules/time.py | 51 + itn/japanese/rules/whitelist.py | 34 + itn/japanese/test/__init__.py | 0 itn/japanese/test/data/cardinal.txt | 56 + itn/japanese/test/data/char.txt | 2 + itn/japanese/test/data/date.txt | 15 + itn/japanese/test/data/fraction.txt | 12 + itn/japanese/test/data/math.txt | 6 + itn/japanese/test/data/measure.txt | 7 + itn/japanese/test/data/normalizer.txt | 127 + itn/japanese/test/data/number.txt | 6 + itn/japanese/test/data/time.txt | 9 + itn/japanese/test/data/whitelist.txt | 2 + itn/japanese/test/normalizer_test.py | 42 + itn/japanese/test/utils.py | 1 + itn/main.py | 28 +- 54 files changed, 4319 insertions(+), 7 deletions(-) create mode 100644 itn/japanese/__init__.py create mode 100644 itn/japanese/data/char/common_chinese_char.tsv create mode 100644 itn/japanese/data/char/fullwidth_to_halfwidth.tsv create mode 100644 itn/japanese/data/char/hiragana_and_katakana.tsv create mode 100644 itn/japanese/data/char/oov_tags.tsv create mode 100644 itn/japanese/data/char/punctuations_ja.tsv create mode 100644 itn/japanese/data/date/day.tsv create mode 100644 itn/japanese/data/date/month.tsv create mode 100644 itn/japanese/data/date/week.tsv create mode 100644 itn/japanese/data/default/blacklist.tsv create mode 100644 itn/japanese/data/default/whitelist.tsv create mode 100644 itn/japanese/data/math/operator.tsv create mode 100644 itn/japanese/data/measure/unit_en.tsv create mode 100644 itn/japanese/data/measure/unit_ja.tsv create mode 100644 itn/japanese/data/money/currency.tsv create mode 100644 itn/japanese/data/number/digit.tsv create mode 100644 itn/japanese/data/number/dot.tsv create mode 100644 itn/japanese/data/number/hundred.tsv create mode 100644 itn/japanese/data/number/hundred_digit.tsv create mode 100644 itn/japanese/data/number/sign.tsv create mode 100644 itn/japanese/data/number/teen.tsv create mode 100644 itn/japanese/data/number/thousands.tsv create mode 100644 itn/japanese/data/number/ties.tsv create mode 100644 itn/japanese/data/number/zero.tsv create mode 100644 itn/japanese/data/time/hour.tsv create mode 100644 itn/japanese/data/time/minute.tsv create mode 100644 itn/japanese/data/time/second.tsv create mode 100644 itn/japanese/inverse_normalizer.py create mode 100644 itn/japanese/rules/__init__.py create mode 100644 itn/japanese/rules/cardinal.py create mode 100644 itn/japanese/rules/char.py create mode 100644 itn/japanese/rules/date.py create mode 100644 itn/japanese/rules/fraction.py create mode 100644 itn/japanese/rules/math.py create mode 100644 itn/japanese/rules/measure.py create mode 100644 itn/japanese/rules/ordinal.py create mode 100644 itn/japanese/rules/postprocessor.py create mode 100644 itn/japanese/rules/preprocessor.py create mode 100644 itn/japanese/rules/time.py create mode 100644 itn/japanese/rules/whitelist.py create mode 100644 itn/japanese/test/__init__.py create mode 100644 itn/japanese/test/data/cardinal.txt create mode 100644 itn/japanese/test/data/char.txt create mode 100644 itn/japanese/test/data/date.txt create mode 100644 itn/japanese/test/data/fraction.txt create mode 100644 itn/japanese/test/data/math.txt create mode 100644 itn/japanese/test/data/measure.txt create mode 100644 itn/japanese/test/data/normalizer.txt create mode 100644 itn/japanese/test/data/number.txt create mode 100644 itn/japanese/test/data/time.txt create mode 100644 itn/japanese/test/data/whitelist.txt create mode 100644 itn/japanese/test/normalizer_test.py create mode 120000 itn/japanese/test/utils.py diff --git a/itn/japanese/__init__.py b/itn/japanese/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/itn/japanese/data/char/common_chinese_char.tsv b/itn/japanese/data/char/common_chinese_char.tsv new file mode 100644 index 0000000..f047193 --- /dev/null +++ b/itn/japanese/data/char/common_chinese_char.tsv @@ -0,0 +1,2502 @@ +尽 +愼 +霸 +伯 +健 +市 +盤 +萬 +致 +奈 +眺 +衞 +声 +徹 +衣 +比 +巡 +革 +謡 +険 +玄 +獸 +沈 +商 +住 +艦 +傳 +祈 +彰 +渓 +酸 +刹 +苗 +齢 +詠 +號 +盛 +薰 +昨 +敢 +背 +陛 +貌 +等 +怖 +大 +丘 +到 +緖 +門 +瀨 +然 +貢 +録 +裕 +咲 +耕 +勅 +梨 +三 +授 +謹 +斥 +田 +視 +貸 +緩 +降 +杉 +濯 +童 +竊 +薦 +靴 +既 +胴 +沸 +渡 +卑 +方 +爲 +罪 +図 +命 +俵 +蛍 +彙 +甚 +腕 +圍 +会 +損 +腸 +俸 +沃 +寺 +諦 +峠 +朕 +鯨 +泣 +枢 +確 +蔵 +熊 +邪 +遺 +給 +遲 +辣 +莊 +發 +陽 +雑 +把 +昔 +和 +騎 +種 +卷 +誰 +乙 +紅 +零 +汚 +詰 +蓄 +剛 +拉 +遅 +餌 +渋 +合 +統 +映 +踊 +漁 +腰 +瓦 +王 +存 +孤 +擇 +旨 +併 +渴 +還 +知 +餘 +井 +渦 +戀 +凶 +餓 +逸 +亡 +犯 +舗 +刻 +今 +嫌 +形 +売 +詣 +諸 +廃 +貧 +忠 +后 +架 +祥 +雲 +葉 +加 +化 +心 +錄 +継 +搾 +般 +蜂 +捜 +負 +尾 +空 +洗 +回 +行 +沖 +太 +偉 +坊 +刈 +虎 +恭 +朴 +暑 +君 +悠 +尚 +思 +增 +汰 +虛 +響 +輪 +漂 +乘 +書 +打 +捗 +現 +弐 +邊 +軍 +植 +鼻 +頻 +迭 +蟲 +擁 +汽 +官 +干 +抵 +慣 +傾 +非 +迫 +微 +是 +拓 +純 +出 +排 +勤 +薫 +福 +社 +醜 +諾 +峽 +浴 +若 +舟 +契 +聞 +詮 +庫 +妊 +帯 +丙 +以 +塀 +柵 +詔 +錮 +瀧 +塩 +元 +遡 +煮 +殉 +脂 +陶 +去 +癡 +候 +稲 +慢 +眠 +穩 +討 +巾 +訟 +貳 +勝 +支 +深 +蚕 +探 +党 +堂 +乗 +龍 +象 +數 +澄 +人 +峰 +魚 +粹 +喚 +丹 +輩 +奮 +墜 +廉 +懸 +退 +譽 +概 +裝 +糾 +械 +喝 +寛 +丁 +者 +置 +洋 +九 +繊 +瞳 +斤 +夜 +瘍 +隆 +爆 +赦 +御 +哀 +雌 +提 +姉 +賓 +歌 +諧 +芽 +挨 +仕 +音 +府 +買 +依 +錦 +祉 +待 +催 +浮 +塀 +泥 +櫻 +払 +麓 +崖 +切 +物 +織 +西 +縄 +妙 +賂 +緻 +郡 +眞 +悟 +憲 +製 +郞 +静 +俊 +県 +團 +基 +車 +叔 +界 +驅 +陪 +班 +繁 +苛 +博 +伏 +二 +稚 +絵 +月 +賢 +乳 +滿 +具 +坂 +兼 +労 +聲 +讀 +仰 +隱 +材 +顯 +英 +免 +沙 +枠 +弁 +拙 +組 +砲 +固 +髄 +歡 +天 +凍 +副 +肘 +柱 +款 +崇 +由 +鍊 +瀬 +麵 +軌 +妹 +林 +徑 +舷 +匂 +祉 +拠 +係 +着 +旧 +盡 +北 +挙 +赤 +宝 +阻 +諮 +疑 +淡 +毛 +夕 +将 +近 +斷 +擴 +鉛 +惠 +弟 +極 +妻 +誉 +珍 +突 +畳 +放 +券 +圈 +賓 +妄 +海 +猫 +嫡 +紫 +薄 +褐 +刷 +壯 +送 +堕 +挟 +毆 +憬 +綻 +獲 +粧 +晴 +中 +幣 +柿 +旅 +飢 +飛 +本 +症 +紛 +服 +営 +滞 +但 +罐 +済 +審 +家 +須 +程 +票 +自 +爽 +米 +寡 +詳 +角 +泡 +倒 +稿 +戦 +災 +距 +捕 +族 +璧 +坪 +毎 +阪 +路 +得 +品 +尻 +蛇 +樂 +淑 +茶 +聴 +学 +施 +運 +海 +策 +弥 +憾 +莖 +削 +膳 +隻 +積 +浜 +濫 +尋 +臨 +灣 +詞 +許 +列 +伎 +豪 +斉 +婦 +斗 +芸 +療 +俳 +評 +幼 +他 +励 +希 +築 +南 +麻 +寒 +町 +必 +典 +一 +儀 +匠 +紹 +呂 +歷 +艶 +廣 +煎 +奔 +頑 +摯 +剖 +茨 +怨 +私 +寶 +減 +陷 +管 +盜 +條 +留 +込 +玩 +德 +永 +答 +薬 +軽 +国 +頭 +頒 +仏 +罰 +口 +齡 +龜 +署 +謙 +麦 +科 +白 +驗 +岡 +互 +愛 +囲 +氷 +卸 +周 +勉 +翌 +嚇 +浅 +案 +直 +姿 +座 +五 +藝 +索 +獨 +塞 +所 +礁 +菌 +呪 +撃 +拜 +冒 +伐 +胆 +没 +濕 +仙 +佳 +隣 +栄 +曆 +楷 +笛 +吟 +怠 +寄 +腹 +弱 +驛 +灰 +俗 +那 +改 +器 +亜 +兒 +凝 +輕 +連 +操 +取 +駄 +態 +絲 +訂 +梅 +昼 +測 +禍 +糸 +母 +衰 +春 +拳 +暑 +漫 +瑠 +卓 +押 +儒 +嵐 +猛 +麗 +逸 +奨 +感 +制 +線 +軟 +圖 +病 +舌 +懲 +謁 +硬 +垂 +肢 +懷 +江 +鈍 +葬 +正 +望 +吉 +踐 +翻 +末 +脅 +且 +袋 +電 +芋 +隅 +却 +碁 +作 +妃 +貫 +量 +同 +笑 +栓 +稱 +遭 +拒 +敏 +朽 +試 +競 +長 +筆 +兵 +召 +皿 +兩 +禁 +看 +妖 +揭 +憂 +壊 +濟 +涉 +牧 +卵 +問 +徒 +畔 +蓋 +膽 +土 +己 +叫 +禮 +建 +頻 +載 +略 +恒 +暖 +混 +内 +岐 +財 +箱 +窓 +硏 +劍 +奥 +止 +擧 +応 +苦 +鮮 +遍 +傍 +申 +繁 +抹 +徵 +濱 +顧 +結 +上 +否 +采 +藍 +倍 +幹 +殘 +歓 +睦 +犬 +肖 +逓 +胸 +塁 +謎 +成 +鳴 +錬 +添 +惧 +雪 +墓 +特 +波 +百 +寸 +璃 +債 +詩 +企 +剤 +木 +喩 +庭 +広 +避 +新 +葛 +系 +防 +娘 +卑 +曇 +星 +冗 +墨 +吐 +欠 +彫 +敕 +賀 +鑛 +戚 +鷄 +頼 +才 +穗 +猶 +集 +僚 +壌 +暮 +段 +蔑 +騒 +醸 +懐 +衝 +従 +偏 +唾 +侮 +報 +員 +潛 +粗 +刃 +利 +畜 +犧 +戻 +恵 +繩 +術 +習 +攝 +腎 +脳 +遞 +配 +氣 +國 +劇 +釣 +應 +劾 +埼 +鉢 +媒 +稼 +級 +勸 +節 +棋 +穴 +憶 +四 +選 +封 +妥 +唆 +網 +複 +酬 +飯 +據 +尼 +堤 +泰 +甁 +至 +縱 +責 +鹿 +因 +味 +下 +度 +肝 +場 +序 +鋳 +村 +尊 +埋 +底 +瓣 +写 +抄 +推 +耐 +断 +崩 +判 +項 +駆 +既 +擬 +含 +督 +艷 +嫉 +努 +杯 +痩 +辭 +潮 +蜜 +業 +続 +育 +演 +謹 +頃 +椅 +從 +更 +踏 +屯 +央 +養 +優 +岳 +舊 +悦 +赴 +駅 +凡 +疊 +晩 +訓 +經 +楽 +面 +陰 +違 +險 +源 +簿 +汎 +矯 +骸 +錠 +棄 +湿 +砂 +寫 +調 +幻 +穀 +争 +劑 +睡 +脊 +剰 +整 +搬 +戾 +賦 +括 +郎 +邸 +慎 +專 +晝 +昧 +伺 +章 +教 +阜 +吏 +週 +換 +臆 +炊 +満 +勤 +陣 +腐 +甲 +餅 +某 +窟 +勃 +樓 +臟 +蛮 +酷 +賄 +狙 +恆 +嘱 +嬢 +曖 +宰 +貝 +患 +遂 +厄 +桑 +卽 +總 +蚊 +攻 +暇 +較 +漢 +黃 +壁 +猿 +昇 +川 +室 +慮 +前 +団 +越 +敷 +未 +廳 +注 +億 +画 +失 +慰 +妬 +姫 +講 +験 +殴 +示 +拭 +曉 +銘 +涼 +発 +情 +石 +勧 +旬 +傷 +膜 +靜 +故 +茂 +澁 +乾 +髪 +岸 +詐 +粛 +仁 +騷 +豆 +根 +慕 +績 +剝 +誤 +秋 +役 +悼 +悪 +滝 +休 +挑 +披 +床 +地 +魂 +史 +馬 +持 +修 +騰 +夏 +橋 +氾 +領 +涙 +忌 +液 +辯 +滑 +堪 +幕 +類 +朱 +千 +経 +殖 +著 +遵 +識 +圏 +札 +釀 +丸 +粘 +禅 +榮 +握 +歐 +鏡 +穏 +導 +話 +虞 +両 +震 +飲 +的 +骨 +観 +局 +侯 +寮 +拡 +採 +汗 +肉 +桟 +護 +厚 +矛 +芯 +安 +藤 +価 +腦 +廢 +顎 +缺 +検 +殊 +欺 +水 +型 +膨 +薪 +畑 +規 +菜 +裁 +參 +姓 +鎌 +碑 +醫 +嚴 +耗 +諭 +痛 +祖 +潰 +鬱 +分 +別 +購 +寿 +步 +終 +蹴 +拍 +囑 +真 +霊 +浦 +蠻 +宇 +對 +里 +侮 +爪 +麥 +燃 +廷 +異 +狭 +淚 +欧 +河 +狂 +燥 +縦 +強 +孝 +則 +兆 +無 +良 +舞 +糖 +彈 +湯 +氏 +實 +秀 +点 +鬼 +紋 +戒 +言 +點 +雨 +槪 +興 +威 +續 +浄 +脈 +富 +肯 +慶 +援 +桜 +芝 +多 +題 +奉 +在 +閉 +循 +理 +単 +籠 +随 +盆 +窮 +轄 +総 +衷 +後 +便 +銃 +帶 +訪 +敬 +荘 +酒 +影 +砕 +生 +離 +京 +釋 +帳 +煮 +怪 +陸 +殺 +超 +転 +閥 +透 +嘲 +弦 +属 +鍋 +繼 +付 +並 +惱 +殺 +壘 +吸 +淫 +洞 +質 +磨 +迎 +稻 +甘 +跡 +效 +塚 +効 +恣 +双 +議 +伴 +殻 +皇 +署 +庶 +弄 +況 +譲 +響 +潟 +扇 +公 +想 +締 +犠 +陵 +停 +晶 +証 +宵 +遷 +搜 +雄 +毀 +賛 +令 +受 +層 +環 +朗 +円 +孔 +拷 +覆 +監 +酌 +瞭 +旺 +羨 +掛 +剩 +琴 +男 +牙 +鋼 +景 +衡 +勳 +鎮 +専 +虹 +巨 +残 +獣 +俺 +驚 +潔 +善 +社 +躍 +紡 +辱 +仮 +柔 +困 +黄 +実 +娠 +算 +挾 +常 +墮 +投 +傲 +脇 +遜 +表 +弧 +該 +叙 +都 +届 +手 +雜 +事 +准 +廊 +任 +児 +飽 +賊 +拶 +尉 +抜 +遇 +暴 +差 +勉 +読 +芳 +帝 +塊 +張 +漬 +靈 +字 +刑 +郭 +頰 +曹 +寢 +途 +縮 +与 +消 +韻 +唐 +記 +願 +歳 +惨 +涯 +慌 +賣 +節 +及 +死 +境 +獵 +牛 +子 +忙 +熟 +七 +敏 +携 +対 +履 +縫 +漏 +日 +租 +保 +際 +台 +塗 +轉 +駐 +翼 +暫 +奧 +鎖 +婆 +雰 +折 +値 +悩 +計 +篤 +毒 +均 +箋 +婿 +破 +房 +編 +繕 +鬭 +覇 +宅 +反 +誌 +青 +恐 +冷 +謝 +森 +鍵 +慨 +八 +立 +壇 +第 +焦 +衆 +鄕 +繭 +竜 +募 +課 +贈 +緯 +初 +域 +肺 +侶 +勞 +収 +沼 +齊 +早 +花 +霧 +暗 +密 +膝 +帽 +帥 +慄 +脱 +害 +老 +勾 +要 +動 +菊 +恩 +懇 +沢 +客 +遮 +相 +約 +舶 +全 +讓 +果 +玉 +飼 +滅 +秘 +疲 +往 +宣 +贈 +燒 +承 +臺 +視 +松 +鐵 +彌 +主 +傘 +僧 +穂 +奬 +旦 +端 +鉱 +來 +細 +盗 +乱 +期 +標 +堆 +樣 +警 +裂 +霜 +魔 +宛 +慘 +政 +店 +万 +察 +鼓 +漠 +湧 +径 +觸 +蠶 +恋 +隊 +季 +塚 +隔 +屬 +捨 +閲 +佐 +秩 +麺 +通 +校 +孃 +紙 +幾 +體 +武 +割 +箇 +賞 +褐 +忍 +僕 +宜 +奇 +逐 +状 +挿 +擔 +荷 +逝 +克 +流 +盟 +隆 +機 +圧 +覧 +桁 +供 +疎 +盾 +每 +布 +屋 +穀 +移 +句 +煩 +竹 +乞 +釈 +澤 +凄 +巢 +礼 +檢 +平 +貞 +尺 +酢 +撮 +務 +泳 +宙 +朝 +僅 +匿 +査 +淨 +賜 +処 +橫 +盲 +壽 +棧 +岬 +曲 +筒 +喝 +漆 +鶏 +顕 +裾 +枕 +法 +錯 +針 +絡 +溫 +意 +高 +束 +儉 +偶 +勢 +納 +勘 +唱 +栽 +順 +敍 +冊 +津 +介 +酎 +摘 +墾 +韓 +娯 +黑 +辺 +臭 +陥 +僞 +變 +光 +酵 +弊 +了 +賭 +棚 +時 +暦 +抱 +熱 +墨 +溶 +練 +祭 +鶴 +位 +鹽 +撲 +寝 +危 +惰 +邦 +胞 +研 +都 +開 +色 +魅 +隙 +舎 +粋 +風 +呉 +佛 +狀 +腺 +被 +浸 +喜 +癒 +午 +憤 +縛 +宗 +追 +撤 +謄 +露 +治 +文 +僧 +指 +血 +硫 +濃 +貨 +迅 +秒 +幸 +能 +] +彩 +畝 +兄 +格 +獻 +側 +碎 +賴 +擦 +昭 +易 +語 +彼 +歸 +雇 +精 +爵 +圓 +屈 +漸 +明 +拐 +穫 +年 +当 +駒 +摂 +速 +憧 +康 +挫 +倉 +名 +辨 +亂 +右 +重 +街 +据 +屆 +抑 +個 +淺 +臣 +棒 +難 +容 +功 +侵 +羊 +刊 +漢 +足 +槽 +壓 +析 +椎 +間 +次 +嗅 +緑 +器 +緒 +居 +扉 +触 +油 +歴 +矢 +装 +気 +信 +進 +草 +絶 +齋 +範 +鑑 +[ +礎 +顔 +肪 +綱 +道 +始 +勲 +輝 +培 +鉄 +貪 +譯 +牲 +温 +友 +士 +免 +志 +皆 +眼 +迷 +臼 +登 +絞 +糧 +創 +箸 +食 +又 +璽 +辞 +原 +潜 +余 +谷 +蒸 +證 +額 +枯 +設 +郊 +説 +短 +夢 +池 +嫁 +拂 +髓 +遠 +践 +虫 +不 +冬 +襃 +席 +独 +使 +裏 +船 +達 +享 +掘 +件 +禍 +農 +祕 +群 +觀 +助 +粒 +十 +拾 +灯 +炉 +鍛 +変 +為 +資 +歯 +遣 +緣 +欄 +嶽 +拝 +瘦 +補 +者 +剣 +冥 +黙 +維 +廊 +完 +繰 +敵 +惜 +突 +来 +紺 +揮 +罵 +悲 +摩 +溪 +税 +趣 +豐 +潤 +卒 +執 +髮 +凹 +神 +義 +性 +古 +金 +冶 +輸 +入 +融 +求 +首 +普 +島 +館 +素 +譜 +收 +雅 +階 +獄 +批 +欄 +爐 +用 +復 +酔 +塑 +愁 +奪 +祖 +會 +著 +墳 +權 +働 +醒 +堀 +華 +適 +造 +緊 +喪 +串 +跳 +衛 +謀 +低 +覽 +似 +肅 +起 +共 +称 +描 +煙 +餠 +快 +愚 +交 +荒 +豫 +酪 +身 +坑 +羞 +岩 +銀 +航 +神 +戰 +掃 +弾 +民 +述 +模 +訴 +省 +闘 +予 +層 +慈 +唯 +泊 +升 +射 +眉 +猟 +侍 +單 +胃 +硝 +益 +誇 +艇 +美 +何 +桃 +飜 +見 +竝 +山 +皮 +揚 +學 +預 +照 +厘 +綿 +敗 +守 +亭 +晚 +炭 +献 +謁 +劣 +尿 +野 +借 +珠 +償 +院 +障 +縣 +黒 +錢 +偵 +旋 +誠 +銭 +惡 +訃 +外 +託 +力 +峡 +増 +戴 +當 +軒 +最 +式 +腫 +女 +畏 +談 +搭 +如 +沿 +逆 +枚 +律 +世 +陳 +勵 +好 +憩 +爭 +走 +委 +促 +宮 +虚 +掌 +費 +裸 +畫 +隨 +扶 +捉 +厳 +滯 +囚 +踪 +丈 +亀 +嘆 +征 +清 +覚 +痕 +搖 +例 +措 +壹 +伸 +醉 +郵 +歩 +惑 +鳥 +豚 +狹 +呈 +鋭 +渉 +激 +左 +占 +体 +恨 +區 +捻 +湖 +痘 +累 +番 +控 +殿 +戸 +可 +有 +先 +勇 +難 +偽 +與 +過 +鈴 +診 +壮 +愉 +園 +貴 +泌 +倂 +禪 +誓 +藏 +罷 +翁 +關 +粉 +巧 +姻 +率 +臭 +悔 +区 +雙 +贊 +再 +我 +藻 +默 +倹 +準 +技 +孫 +担 +返 +啓 +賃 +鎭 +巣 +溝 +択 +横 +洪 +活 +寂 +解 +丼 +婚 +念 +謠 +宴 +港 +喫 +練 +濁 +久 +決 +引 +刺 +將 +香 +職 +凸 +畿 +祈 +逮 +請 +吹 +烈 +類 +昆 +籍 +宿 +幽 +様 +派 +倫 +曽 +臓 +父 +楼 +参 +羽 +頂 +巻 +憎 +褒 +急 +諸 +机 +梅 +遊 +息 +条 +誘 +聖 +旗 +菓 +唇 +各 +定 +梗 +向 +癖 +縁 +窃 +嘆 +像 +貯 +延 +肌 +産 +少 +充 +片 +汁 +胎 +城 +半 +湾 +庁 +咽 +郷 +筋 +滴 +柄 +祝 +関 +祥 +振 +乏 +肥 +忘 +磁 +散 +塔 +塾 +包 +窒 +祝 +襲 +襟 +符 +樞 +懲 +扱 +豊 +究 +斬 +東 +肩 +耳 +痴 +棺 +柳 +虜 +渇 +擊 +染 +溺 +羅 +壤 +怒 +假 +附 +絹 +協 +痢 +逃 +鑄 +股 +寧 +喉 +就 +徐 +奴 +代 +泉 +帆 +核 +除 +棟 +噴 +認 +夫 +救 +價 +仲 +辛 +工 +誕 +告 +伝 +替 +紀 +浪 +即 +弓 +号 +亞 +堅 +板 +庸 +部 +雷 +斎 +炎 +司 +目 +匹 +螢 +鐘 +販 +斑 +閣 +拔 +樹 +窯 +聽 +傑 +呼 +州 +招 +缶 +暁 +壱 +齒 +碑 +嗣 +数 +哺 +揺 +營 +寬 +帰 +抽 +展 +脚 +斜 +媛 +飾 +医 +唄 +料 +需 +藩 +弔 +貿 +曾 +妨 +瓶 +拘 +権 +萎 +虜 +稽 +論 +欲 +插 +疫 +師 +朗 +綠 +限 +疾 +繪 +狩 +𠮟 +壞 +憎 +構 +頓 +膚 +纖 +燈 +栃 +銅 +版 +垣 +虐 +抗 +備 +處 +冠 +接 +六 +殼 +閑 +親 +隷 +奏 +貼 +慨 +藥 +落 +賠 +曜 +闇 +戲 +幅 +考 +刀 +徳 +焼 +恥 +塡 +茎 +掲 +徴 +小 +黨 +簡 +隠 +訳 +株 +軸 +崎 +球 +倣 +火 +枝 +覺 +袖 +紳 +印 +釜 +哲 +戯 +蔽 +悔 +福 +瞬 +滋 \ No newline at end of file diff --git a/itn/japanese/data/char/fullwidth_to_halfwidth.tsv b/itn/japanese/data/char/fullwidth_to_halfwidth.tsv new file mode 100644 index 0000000..068c215 --- /dev/null +++ b/itn/japanese/data/char/fullwidth_to_halfwidth.tsv @@ -0,0 +1,95 @@ +, , +。 . +. . +“ " +” " +! ! +" " +# # +% % +& & +' ' +( ( +) ) +* * ++ + +- - +/ / +: : +; ; +< < += = +> > +? ? +@ @ +\ \ +^ ^ +_ _ +` ` +{ { +| | +} } +~ ~ +$ $ +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +a a +A A +b b +B B +c c +C C +d d +D D +e e +E E +f f +F F +g g +G G +h h +H H +i i +I I +j j +J J +k k +K K +l l +L L +m m +M M +n n +N N +o o +O O +p p +P P +q q +Q Q +r r +R R +s s +S S +t t +T T +u u +U U +v v +V V +w w +W W +x x +X X +y y +Y Y +z z +Z Z diff --git a/itn/japanese/data/char/hiragana_and_katakana.tsv b/itn/japanese/data/char/hiragana_and_katakana.tsv new file mode 100644 index 0000000..d09d8a1 --- /dev/null +++ b/itn/japanese/data/char/hiragana_and_katakana.tsv @@ -0,0 +1,160 @@ +あ +い +う +え +お +か +き +く +け +こ +さ +し +す +せ +そ +た +ち +つ +て +と +な +に +ぬ +ね +の +は +ひ +ふ +へ +ほ +ま +み +む +め +も +や +ゆ +よ +ら +り +る +れ +ろ +わ +を +ん +ア +イ +ウ +エ +オ +カ +キ +ク +ケ +コ +サ +シ +ス +セ +ソ +タ +チ +ツ +テ +ト +ナ +ニ +ヌ +ネ +ノ +ハ +ヒ +フ +ヘ +ホ +マ +ミ +ム +メ +モ +ヤ +ユ +ヨ +ラ +リ +ル +レ +ロ +ワ +ヲ +ン +が +ぎ +ぐ +げ +ご +ざ +じ +ず +ぜ +ぞ +だ +ぢ +づ +で +ど +ば +び +ぶ +べ +ぼ +ぱ +ぴ +ぷ +ぺ +ぽ +ガ +ギ +グ +ゲ +ゴ +ザ +ジ +ズ +ゼ +ゾ +ダ +ヂ +ヅ +デ +ド +バ +ビ +ブ +ベ +ボ +パ +ピ +プ +ペ +ポ +ャ +ァ +ィ +ュ +ッ +ゥ +ェ +ョ +ォ +ぁ +ぃ +ぅ +ぇ +ぉ +っ +ゃ +ゅ +ょ \ No newline at end of file diff --git a/itn/japanese/data/char/oov_tags.tsv b/itn/japanese/data/char/oov_tags.tsv new file mode 100644 index 0000000..8902fe6 --- /dev/null +++ b/itn/japanese/data/char/oov_tags.tsv @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/itn/japanese/data/char/punctuations_ja.tsv b/itn/japanese/data/char/punctuations_ja.tsv new file mode 100644 index 0000000..169cc4d --- /dev/null +++ b/itn/japanese/data/char/punctuations_ja.tsv @@ -0,0 +1,72 @@ +! +? +。 +。 +" +# +$ +% +& +' +( +) +* ++ +, +- +/ +: +; +< += +> +@ +[ +\ +] +^ +_ +` +{ +| +} +~ +⦅ +⦆ +「 +」 +、 +、 +〃 +》 +「 +」 +『 +』 +【 +】 +〔 +〕 +〖 +〗 +〘 +〙 +〚 +〛 +〜 +〝 +〞 +〟 +〰 +– +— +‘ +’ +‛ +“ +” +„ +‟ +… +‧ +﹏ \ No newline at end of file diff --git a/itn/japanese/data/date/day.tsv b/itn/japanese/data/date/day.tsv new file mode 100644 index 0000000..32794ad --- /dev/null +++ b/itn/japanese/data/date/day.tsv @@ -0,0 +1,31 @@ +一 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 \ No newline at end of file diff --git a/itn/japanese/data/date/month.tsv b/itn/japanese/data/date/month.tsv new file mode 100644 index 0000000..ab397ba --- /dev/null +++ b/itn/japanese/data/date/month.tsv @@ -0,0 +1,12 @@ +一 1 +二 2 +三 3 +四 4 +五 5 +六 6 +七 7 +八 8 +九 9 +十 10 +十一 11 +十二 12 \ No newline at end of file diff --git a/itn/japanese/data/date/week.tsv b/itn/japanese/data/date/week.tsv new file mode 100644 index 0000000..8fb9c96 --- /dev/null +++ b/itn/japanese/data/date/week.tsv @@ -0,0 +1,14 @@ +月曜日 月 +月曜 月 +火曜日 火 +火曜 火 +水曜日 水 +水曜 水 +木曜日 木 +木曜 木 +金曜日 金 +金曜 金 +土曜日 土 +土曜 土 +日曜日 日 +日曜 日 diff --git a/itn/japanese/data/default/blacklist.tsv b/itn/japanese/data/default/blacklist.tsv new file mode 100644 index 0000000..e69de29 diff --git a/itn/japanese/data/default/whitelist.tsv b/itn/japanese/data/default/whitelist.tsv new file mode 100644 index 0000000..91d7bf0 --- /dev/null +++ b/itn/japanese/data/default/whitelist.tsv @@ -0,0 +1,3 @@ +十三湖 +一月三舟 +一日之長 \ No newline at end of file diff --git a/itn/japanese/data/math/operator.tsv b/itn/japanese/data/math/operator.tsv new file mode 100644 index 0000000..0534dad --- /dev/null +++ b/itn/japanese/data/math/operator.tsv @@ -0,0 +1,7 @@ +カケル × +マイナス - +プラス + +イコール = +ワル ÷ +から ~ +対 : \ No newline at end of file diff --git a/itn/japanese/data/measure/unit_en.tsv b/itn/japanese/data/measure/unit_en.tsv new file mode 100644 index 0000000..c30c655 --- /dev/null +++ b/itn/japanese/data/measure/unit_en.tsv @@ -0,0 +1,107 @@ +華氏 f +摂氏 c +キロメートル km +千キロメートル km +メートル m +センチメートル cm +ミリメートル mm +ヘクタール ha +マイル mi +平方メートル m² +平方キロメートル km² +足 ft +パーセント % +ヘルツ hz +キロワット kw +馬力 hp +ミリグラム mg +キログラム kg +キロ kg +ギガヘルツ ghz +キロヘルツ khz +メガヘルツ mhz +ボルト v +メガクーロン mc +ナノメートル nm +毎分回転数 rpm +ミリアンペア mA +パーセント % +キロワット時 kwh +立方メートル m³ +時速マイル mph +テラワット tw +ミリボルト mv +メガワット mw +マイクロメータ μm +インチ " +テラバイト tb +c c cc +グラム g +ダルトン da +雰囲気 atm +オーム ω +デシベル db +ペタ秒 ps +オンス oz +ヘクトリットル hl +マイクログラム μg +ペタグラム pg +ギガバイト gb +キロビット kb +電子ボルト ev +メガバイト mb +キロバイト kb +キロビット/秒 kbps +毎秒メガビット mbps +結石 st +キロリットル kl +テラジュール tj +キロボルト kv +メガボルト mv +キロニュートン kn +メガメーター mm +天文単位 au +ヤード yd +ラジアン rad +ルーメン lm +ヘクト秒 hs +モル mol +ギガパスカル gpa +ミリリットル ml +ギガワット gw +メガアンペア ma +結び目 kt +キログラム力 kgf +ナノグラム ng +ナノ秒 ns +メガシーメンス ms +バー bar +ギガリットル gl +マイクロ秒 μs +デシアンペア da +パスカル pa +デシ秒 ds +ミリ秒 ms +デシメートル dm +立方デシメートル dm³ +原子質量単位 amu +メガビット mb +メガファラッド mf +ベクレル bq +ペタビット pb +平方ミリメートル mm² +平方センチメートル cm² +平方マイル sq mi +平方フィート sq ft +キロパスカル kpa +カンデラ cd +テラリットル tl +メガ秒 ms +メガパスカル mpa +ペタメーター pm +ペタバイト pb +ギガワットアワー gwh +キロカロリー kcal +グレー gy +シーベルト sv +ハンドレッド cwt \ No newline at end of file diff --git a/itn/japanese/data/measure/unit_ja.tsv b/itn/japanese/data/measure/unit_ja.tsv new file mode 100644 index 0000000..c214b70 --- /dev/null +++ b/itn/japanese/data/measure/unit_ja.tsv @@ -0,0 +1,47 @@ +つ +枚 +部 +台 +杯 +匹 +本 +階 +個 +箇 +个 +ヶ +面 +名 +人 +歳 +才 +冊 +話 +秒 +分 +月 +泊 +時 +時間 +日 +ヶ月 +箇月 +年 +日 +週 +倍 +番 +度 +畳 +回 +年前 +年後 +年以内 +平方 +平方メートル +立方 +立方メートル +キロ +キロメトル +世紀 +年代 \ No newline at end of file diff --git a/itn/japanese/data/money/currency.tsv b/itn/japanese/data/money/currency.tsv new file mode 100644 index 0000000..58cdfc4 --- /dev/null +++ b/itn/japanese/data/money/currency.tsv @@ -0,0 +1,35 @@ +$ ドル +$ 米ドル +$ 米ドル +£ 英国ポンド +€ ユーロ +₩ 勝った +nzd ニュージーランドドル +rs ルピー +chf スイスフラン +dkk デンマーククローネ +fim フィンランドのマルッカ +aed アラブ首長国連邦ディルハム +¥ 円 +czk チェココルナ +mro モーリタニアのウギア +pkr パキスタン・ルピー +crc コスタリカのコロン +hk$ 香港ドル +npr ネパールルピー +awg アルバフロリン +nok ノルウェークローネ +tzs タンザニアシリング +sek スウェーデンクローナ +cyp キプロスポンド +r 本物 +sar サウジアラビアリヤル +cve カーボベルデ エスクード +rsd セルビアディナール +dm ドイツマーク +shp セントヘレナ・ポンド +php フィリピンペソ +cad カナダドル +ssp 南スーダンポンド +scr セーシェル・ルピー +mvr モルディブ・ルフィア \ No newline at end of file diff --git a/itn/japanese/data/number/digit.tsv b/itn/japanese/data/number/digit.tsv new file mode 100644 index 0000000..d0bdca3 --- /dev/null +++ b/itn/japanese/data/number/digit.tsv @@ -0,0 +1,9 @@ +一 1 +二 2 +三 3 +四 4 +五 5 +六 6 +七 7 +八 8 +九 9 \ No newline at end of file diff --git a/itn/japanese/data/number/dot.tsv b/itn/japanese/data/number/dot.tsv new file mode 100644 index 0000000..c15a4cd --- /dev/null +++ b/itn/japanese/data/number/dot.tsv @@ -0,0 +1 @@ +点 . \ No newline at end of file diff --git a/itn/japanese/data/number/hundred.tsv b/itn/japanese/data/number/hundred.tsv new file mode 100644 index 0000000..a58eff3 --- /dev/null +++ b/itn/japanese/data/number/hundred.tsv @@ -0,0 +1 @@ +百 \ No newline at end of file diff --git a/itn/japanese/data/number/hundred_digit.tsv b/itn/japanese/data/number/hundred_digit.tsv new file mode 100644 index 0000000..0cbd132 --- /dev/null +++ b/itn/japanese/data/number/hundred_digit.tsv @@ -0,0 +1,9 @@ +百一 101 +百二 102 +百三 103 +百四 104 +百五 105 +百六 106 +百七 107 +百八 108 +百九 109 \ No newline at end of file diff --git a/itn/japanese/data/number/sign.tsv b/itn/japanese/data/number/sign.tsv new file mode 100644 index 0000000..49ec76f --- /dev/null +++ b/itn/japanese/data/number/sign.tsv @@ -0,0 +1,4 @@ +プラス + +プラスマイナス ± +マイナス - +负の - \ No newline at end of file diff --git a/itn/japanese/data/number/teen.tsv b/itn/japanese/data/number/teen.tsv new file mode 100644 index 0000000..3b4370e --- /dev/null +++ b/itn/japanese/data/number/teen.tsv @@ -0,0 +1,10 @@ +十 10 +十一 11 +十二 12 +十三 13 +十四 14 +十五 15 +十六 16 +十七 17 +十八 18 +十九 19 \ No newline at end of file diff --git a/itn/japanese/data/number/thousands.tsv b/itn/japanese/data/number/thousands.tsv new file mode 100644 index 0000000..e37d2bf --- /dev/null +++ b/itn/japanese/data/number/thousands.tsv @@ -0,0 +1,9 @@ +千 +万 +亿 +兆 +京 +垓 +秭 +穰 +沟 \ No newline at end of file diff --git a/itn/japanese/data/number/ties.tsv b/itn/japanese/data/number/ties.tsv new file mode 100644 index 0000000..365df8b --- /dev/null +++ b/itn/japanese/data/number/ties.tsv @@ -0,0 +1,8 @@ +二十 2 +三十 3 +四十 4 +五十 5 +六十 6 +七十 7 +八十 8 +九十 9 \ No newline at end of file diff --git a/itn/japanese/data/number/zero.tsv b/itn/japanese/data/number/zero.tsv new file mode 100644 index 0000000..f9b960e --- /dev/null +++ b/itn/japanese/data/number/zero.tsv @@ -0,0 +1,3 @@ +〇 0 +零 0 +ゼロ 0 \ No newline at end of file diff --git a/itn/japanese/data/time/hour.tsv b/itn/japanese/data/time/hour.tsv new file mode 100644 index 0000000..39c6325 --- /dev/null +++ b/itn/japanese/data/time/hour.tsv @@ -0,0 +1,34 @@ +一時 1 +两時 2 +三時 3 +四時 4 +五時 5 +六時 6 +七時 7 +八時 8 +九時 9 +零時 0 +一時 1 +两時 2 +三時 3 +四時 4 +五時 5 +六時 6 +七時 7 +八時 8 +九時 9 +十時 10 +十一時 11 +十二時 12 +十三時 13 +十四時 14 +十五時 15 +十六時 16 +十七時 17 +十八時 18 +十九時 19 +二十時 20 +二十一時 21 +二十二時 22 +二十三時 23 +二十四時 24 \ No newline at end of file diff --git a/itn/japanese/data/time/minute.tsv b/itn/japanese/data/time/minute.tsv new file mode 100644 index 0000000..a60da05 --- /dev/null +++ b/itn/japanese/data/time/minute.tsv @@ -0,0 +1,60 @@ +一分 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 \ No newline at end of file diff --git a/itn/japanese/data/time/second.tsv b/itn/japanese/data/time/second.tsv new file mode 100644 index 0000000..baf926e --- /dev/null +++ b/itn/japanese/data/time/second.tsv @@ -0,0 +1,60 @@ +一秒 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 \ No newline at end of file diff --git a/itn/japanese/inverse_normalizer.py b/itn/japanese/inverse_normalizer.py new file mode 100644 index 0000000..9444230 --- /dev/null +++ b/itn/japanese/inverse_normalizer.py @@ -0,0 +1,86 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from itn.japanese.rules.cardinal import Cardinal +from itn.japanese.rules.char import Char +from itn.japanese.rules.date import Date +from itn.japanese.rules.fraction import Fraction +from itn.japanese.rules.math import Math +from itn.japanese.rules.measure import Measure +from itn.japanese.rules.ordinal import Ordinal +from itn.japanese.rules.preprocessor import PreProcessor +from itn.japanese.rules.postprocessor import PostProcessor +from itn.japanese.rules.whitelist import Whitelist +from itn.japanese.rules.time import Time + +from pynini.lib.pynutil import add_weight, delete +from importlib_resources import files + + +class InverseNormalizer(Processor): + + def __init__(self, + cache_dir=None, + overwrite_cache=False, + full_to_half=False, + enable_standalone_number=True, + enable_0_to_9=False, + enable_million=False): + super().__init__(name='ja_inverse_normalizer', ordertype='itn') + self.full_to_half = full_to_half + 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('ja_itn', cache_dir, overwrite_cache) + + def build_tagger(self): + processor = PreProcessor(full_to_half=self.full_to_half).processor + + cardinal = add_weight( + Cardinal(self.convert_number, self.enable_0_to_9, + self.enable_million).tagger, 1.06) + char = add_weight(Char().tagger, 100) + date = add_weight(Date().tagger, 1.02) + fraction = add_weight(Fraction().tagger, 1.05) + math = add_weight(Math().tagger, 90) + measure = add_weight( + Measure(enable_0_to_9=self.enable_0_to_9).tagger, 1.05) + ordinal = add_weight(Ordinal().tagger, 1.04) + time = add_weight(Time().tagger, 1.04) + whitelist = add_weight(Whitelist().tagger, 1.01) + + tagger = (cardinal | char | date | fraction | math | measure | ordinal + | time | whitelist).optimize().star + tagger = (processor @ tagger).star + # remove the last space + self.tagger = tagger @ self.build_rule(delete(' '), '', '[EOS]') + + def build_verbalizer(self): + cardinal = Cardinal(self.convert_number, self.enable_0_to_9).verbalizer + char = Char().verbalizer + date = Date().verbalizer + fraction = Fraction().verbalizer + math = Math().verbalizer + measure = Measure().verbalizer + ordinal = Ordinal().verbalizer + time = Time().verbalizer + whitelist = Whitelist().verbalizer + + verbalizer = cardinal | char | date | fraction | math | measure | ordinal | time | whitelist + + processor = PostProcessor().processor + self.verbalizer = (verbalizer @ processor).star diff --git a/itn/japanese/rules/__init__.py b/itn/japanese/rules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/itn/japanese/rules/cardinal.py b/itn/japanese/rules/cardinal.py new file mode 100644 index 0000000..9e5a3f6 --- /dev/null +++ b/itn/japanese/rules/cardinal.py @@ -0,0 +1,172 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import accep, cross, string_file +from pynini.lib.pynutil import delete, insert + + +class Cardinal(Processor): + + def __init__(self, + enable_standalone_number=True, + enable_0_to_9=True, + enable_million=False): + super().__init__(name='cardinal') + self.enable_standalone_number = enable_standalone_number + self.enable_0_to_9 = enable_0_to_9 + self.enable_million = enable_million + self.ten_thousand_minus = None # used for year of date + self.positive_integer = None # used for ordinal、measure + self.big_integer = None # for math + self.number = None + self.decimal = None # used for math + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + zero = string_file( + get_abs_path("../itn/japanese/data/number/zero.tsv")) + digit = string_file( + get_abs_path("../itn/japanese/data/number/digit.tsv")) + hundred_digit = string_file( + get_abs_path("../itn/japanese/data/number/hundred_digit.tsv")) + sign = string_file( + get_abs_path("../itn/japanese/data/number/sign.tsv")) + dot = string_file(get_abs_path("../itn/japanese/data/number/dot.tsv")) + ties = string_file( + get_abs_path("../itn/japanese/data/number/ties.tsv")) + graph_teen = string_file( + get_abs_path("../itn/japanese/data/number/teen.tsv")) + + addzero = insert("0") + # 〇 三 九 + digits = zero | digit # 0 ~ 9 + # 十 十一 十九 + teen = graph_teen + teen |= cross("十", "1") + (digit | addzero) + # 三十 三十一 九十 九十一 + tens = ties + addzero | (ties + (digit | addzero)) + + # 三百二 三百 + hundred = (digit + delete("百") + + (tens | teen | addzero**1 + digits | addzero**2)) + # 百 百十 百二十三 + hundred |= cross("百", + "1") + (tens | teen | addzero + digits | addzero**2) + # 百一 百二 + hundred |= hundred_digit + + # 二千百 二千三百 二千百一 九千百二十三 九千二十三 九千二十 九千二 + thousand = ((hundred | teen | tens | digits) + delete("千") + + (hundred | addzero + tens | addzero + teen + | addzero**2 + digits | addzero**3)) + # 千百 千三百 千百一 千百二十三 千二十三 千二十 千二 + thousand |= cross('千', '1') + (hundred | addzero + tens | addzero + + teen | addzero**2 + digits | addzero**3) + + # 一万 二万二 二万二千百 二万二千三百 一万二千百一 一万九千百二十三 一万九千二十三 九万九千二十 四万九千二 + ten_thousand = ((thousand | hundred | teen | tens | digits) + + delete("万") + + (thousand | addzero + hundred | addzero**2 + tens | + addzero**2 + teen | addzero**3 + digits | addzero**4)) + + hundred_thousand = (digits + delete("十万") + (ten_thousand + | addzero + thousand + | addzero**2 + hundred + | addzero**3 + tens + | addzero**3 + teen + | addzero**4 + digits + | addzero**5)) + + million = (digits + delete("百万") + (hundred_thousand + | addzero + ten_thousand + | addzero**2 + thousand + | addzero**3 + hundred + | addzero**4 + tens + | addzero**4 + teen + | addzero**5 + digits + | addzero**6)) + + ten_million = (digits + delete("千万") + (million + | addzero + hundred_thousand + | addzero**2 + ten_thousand + | addzero**3 + thousand + | addzero**4 + hundred + | addzero**5 + tens + | addzero**5 + teen + | addzero**6 + digits + | addzero**7)) + + # 0~9999 + ten_thousand_minus = digits | teen | tens | hundred | thousand + self.ten_thousand_minus = ten_thousand_minus + # 0~99999999 + positive_integer = (digits | teen | tens | hundred | thousand + | ten_thousand | hundred_thousand | million + | ten_million) + self.positive_integer = positive_integer + + # ±0~9999 + number = (sign.ques + ten_thousand_minus).optimize() + self.number = number + + # ±0.0~99999999.99... + decimal = sign.ques + positive_integer + dot + digits.plus + self.decimal = decimal + + if self.enable_million: + # 三百二十万五千 => 3255000 + number = (sign.ques + positive_integer).optimize() + + # ±10000~∞ e.g. 一兆三百二十万五千 => 1兆320万5000 + big_integer = (sign.ques + ( + (ten_thousand_minus + accep("兆")).ques + + (ten_thousand_minus + accep("億")).ques + + (ten_thousand_minus + accep("万")).ques + ten_thousand_minus + | (ten_thousand_minus + accep("兆")).ques + + (ten_thousand_minus + accep("億")).ques + + (ten_thousand_minus + accep("万")) + | (ten_thousand_minus + accep("兆")).ques + + (ten_thousand_minus + accep("億")) + | ten_thousand_minus + accep("兆") + | ten_thousand_minus)) + self.big_integer = big_integer + number |= big_integer + + # cardinal string like 127.0.0.1, used in ID, IP, etc. + cardinal = digit.plus + (dot + digits.plus).plus + # float number like 1.11 + cardinal |= decimal + # cardinal string like 110 or 12306 or 13125617878, used in phone + cardinal |= digits**3 | digits**5 | digits**10 | digits**11 | digits**12 + + # allow convert standalone number + if self.enable_standalone_number: + if self.enable_0_to_9: + # 一 => 1 四 => 4 一秒 => 1秒 一万二 => 1万2 二三 => 23 + cardinal |= number + else: + # 一 => 一 四 => 四 一秒 => 1秒 一万二 => 一万二 二三 => 23 + number_two_plus = ((digits + digits.plus) + | teen + | tens + | hundred + | thousand) + cardinal |= number_two_plus + + self.tagger = self.add_tokens( + insert('value: "') + cardinal + insert('"')).optimize() diff --git a/itn/japanese/rules/char.py b/itn/japanese/rules/char.py new file mode 100644 index 0000000..f574405 --- /dev/null +++ b/itn/japanese/rules/char.py @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor + +from pynini.lib.pynutil import insert + + +class Char(Processor): + + def __init__(self): + super().__init__(name='char') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + tagger = insert('value: "') + self.CHAR + insert('"') + self.tagger = self.add_tokens(tagger) diff --git a/itn/japanese/rules/date.py b/itn/japanese/rules/date.py new file mode 100644 index 0000000..b03794a --- /dev/null +++ b/itn/japanese/rules/date.py @@ -0,0 +1,72 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from itn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import accep, cross, string_file, union +from pynini.lib.pynutil import delete, insert + + +class Date(Processor): + + def __init__(self): + super().__init__(name="date") + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + cardinal = Cardinal().ten_thousand_minus + day = string_file(get_abs_path('../itn/japanese/data/date/day.tsv')) + month = string_file( + get_abs_path('../itn/japanese/data/date/month.tsv')) + to = cross('から', '〜') + + # 一月 一日 一年 + year = insert('year: "') + cardinal + ( + to + cardinal).ques + delete('年') + insert('"') + month = insert('month: "') + month + ( + to + month).ques + delete('月') + insert('"') + day = insert('day: "') + day + (to + + day).ques + delete('日') + insert('"') + + # 二千二十四年十月一日 二千二十四年十月 十月一日 + graph_date = (year + insert(" ") + month + | month + insert(" ") + day + | year + insert(" ") + month + insert(" ") + day) + + # specific context for era year, e.g., L6 -> "令和6年" + context = union(accep('今年は'), accep('来年は'), accep('再来年は'), + accep('去年は'), accep('一昨年は'), accep('おととしは')) + era_year = union(cross("R", "令和"), cross("H", "平成"), cross("S", "昭和"), + cross("T", "大正"), cross("M", "明治")) + era_year = context + era_year + cardinal + era_year = insert('year: "') + era_year + insert('"') + + date = graph_date | era_year + self.tagger = self.add_tokens(date).optimize() + + def build_verbalizer(self): + year = delete('year: "') + self.SIGMA + insert('年') + delete('"') + era_year = delete('year: "') + self.SIGMA + delete('"') + month = delete('month: "') + self.SIGMA + insert('月') + delete('"') + day = delete('day: "') + self.SIGMA + insert('日') + delete('"') + + graph_regular = (year + delete(' ') + month + | month + delete(' ') + day + | year + delete(' ') + month + delete(' ') + day) + + graph = graph_regular | era_year + self.verbalizer = self.delete_tokens(graph).optimize() diff --git a/itn/japanese/rules/fraction.py b/itn/japanese/rules/fraction.py new file mode 100644 index 0000000..7c13178 --- /dev/null +++ b/itn/japanese/rules/fraction.py @@ -0,0 +1,67 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from itn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import accep, cross, string_file, closure +from pynini.lib.pynutil import delete, insert + + +class Fraction(Processor): + + def __init__(self): + super().__init__(name='fraction') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + cardinal = Cardinal(enable_million=True).positive_integer + decimal = Cardinal(enable_million=True).decimal + sign = string_file( + get_abs_path('../itn/japanese/data/number/sign.tsv')) + sign = insert('sign: "') + sign + insert('"') + + fraction_word = delete("分の") | delete(" 分 の ") | delete( + "分 の ") | delete("分 の") + root_word = accep("√") | cross("ルート", "√") + + denominator = ((decimal | (cardinal + root_word + cardinal) | + (root_word + cardinal) | cardinal) + delete(' ').ques) + denominator = insert('denominator: "') + denominator + insert('"') + + numerator = (closure(delete(' ')) + + (decimal | cardinal + root_word + cardinal + | root_word + cardinal | cardinal)) + numerator = insert('numerator: "') + numerator + insert('"') + + fraction_sign = sign + insert(" ") + denominator + insert( + " ") + fraction_word + numerator + fraction_no_sign = denominator + insert( + " ") + fraction_word + numerator + regular_fractions = fraction_sign | fraction_no_sign + + integer_fraction_sign = ((sign + insert(" ")).ques + denominator + + insert(" ") + fraction_word + numerator) + fraction = regular_fractions | integer_fraction_sign + self.tagger = self.add_tokens(fraction).optimize() + + def build_verbalizer(self): + sign = delete('sign: "') + self.SIGMA + delete('"') + denominator = delete('denominator: "') + self.SIGMA + delete('"') + numerator = delete('numerator: "') + self.SIGMA + delete('"') + fraction = ((sign + delete(' ')).ques + numerator + delete(' ') + + insert('/') + denominator) + self.verbalizer = self.delete_tokens(fraction).optimize() diff --git a/itn/japanese/rules/math.py b/itn/japanese/rules/math.py new file mode 100644 index 0000000..0eea2be --- /dev/null +++ b/itn/japanese/rules/math.py @@ -0,0 +1,39 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from itn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import insert + + +class Math(Processor): + + def __init__(self): + super().__init__(name='math') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + operator = string_file( + get_abs_path('../itn/japanese/data/math/operator.tsv')) + + number = Cardinal().big_integer + decimal = Cardinal().decimal + number |= decimal + tagger = (number + (operator + number).plus) + tagger = insert('value: "') + tagger + insert('"') + self.tagger = self.add_tokens(tagger) diff --git a/itn/japanese/rules/measure.py b/itn/japanese/rules/measure.py new file mode 100644 index 0000000..7ca637e --- /dev/null +++ b/itn/japanese/rules/measure.py @@ -0,0 +1,48 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from itn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import cross, string_file +from pynini.lib.pynutil import delete, insert + + +class Measure(Processor): + + def __init__(self, enable_0_to_9=True): + super().__init__(name='measure') + self.enable_0_to_9 = enable_0_to_9 + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + unit_en = string_file( + get_abs_path('../itn/japanese/data/measure/unit_en.tsv')) + unit_ja = string_file( + get_abs_path('../itn/japanese/data/measure/unit_ja.tsv')) + + cardinal = Cardinal(self.enable_0_to_9).positive_integer + decimal = Cardinal(self.enable_0_to_9).decimal + + suffix = ( + insert('/') + (delete('每') | delete('毎')) + + (unit_en | cross('時', 'h') | cross('分', 'min') | cross('秒', 's'))) + + measure = ((cardinal | decimal) + unit_en + suffix.ques + | (cardinal | decimal) + unit_ja) + + tagger = insert('value: "') + measure + insert('"') + self.tagger = self.add_tokens(tagger) diff --git a/itn/japanese/rules/ordinal.py b/itn/japanese/rules/ordinal.py new file mode 100644 index 0000000..61bd6fd --- /dev/null +++ b/itn/japanese/rules/ordinal.py @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from itn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor + +from pynini import accep +from pynini.lib.pynutil import insert + + +class Ordinal(Processor): + + def __init__(self): + super().__init__(name='ordinal') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + cardinal = Cardinal().positive_integer + ordinal = (cardinal + accep('番目')) | (accep('第') + cardinal) + tagger = insert('value: "') + ordinal + insert('"') + self.tagger = self.add_tokens(tagger) diff --git a/itn/japanese/rules/postprocessor.py b/itn/japanese/rules/postprocessor.py new file mode 100644 index 0000000..04cd078 --- /dev/null +++ b/itn/japanese/rules/postprocessor.py @@ -0,0 +1,55 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file, difference +from pynini.lib.pynutil import delete +from pynini.lib.tagger import Tagger + + +class PostProcessor(Processor): + + def __init__(self, + remove_interjections=False, + remove_puncts=False, + tag_oov=False): + super().__init__(name='postprocessor') + blacklist = string_file( + get_abs_path('../itn/japanese/data/default/blacklist.tsv')) + puncts = string_file( + get_abs_path('../itn/japanese/data/char/punctuations_ja.tsv')) + # 片假名/平假名/浊音/半浊音/小写假名 + ja_charset_std = string_file( + get_abs_path( + '../itn/japanese/data/char/hiragana_and_katakana.tsv')) + # 日语常用汉字表 + ja_charset_ext = string_file( + get_abs_path('../itn/japanese/data/char/common_chinese_char.tsv')) + + processor = self.build_rule('') + if remove_interjections: + processor @= self.build_rule(delete(blacklist)) + + if remove_puncts: + processor @= self.build_rule(delete(puncts | self.PUNCT)) + + if tag_oov: + charset = (ja_charset_std | ja_charset_ext | puncts | self.DIGIT + | self.ALPHA | self.PUNCT | self.SPACE) + oov = difference(self.VCHAR, charset) + processor @= Tagger('oov', oov, self.VSIGMA)._tagger + + self.processor = processor.optimize() diff --git a/itn/japanese/rules/preprocessor.py b/itn/japanese/rules/preprocessor.py new file mode 100644 index 0000000..c4767e0 --- /dev/null +++ b/itn/japanese/rules/preprocessor.py @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file + + +class PreProcessor(Processor): + + def __init__(self, full_to_half): + super().__init__(name='preprocessor') + traditional2simple = string_file( + get_abs_path( + '../itn/japanese/data/char/fullwidth_to_halfwidth.tsv')) + + processor = self.build_rule('') + if full_to_half: + processor @= self.build_rule(traditional2simple) + + self.processor = processor.optimize() diff --git a/itn/japanese/rules/time.py b/itn/japanese/rules/time.py new file mode 100644 index 0000000..5b94bcb --- /dev/null +++ b/itn/japanese/rules/time.py @@ -0,0 +1,51 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import delete, insert + + +class Time(Processor): + + def __init__(self): + super().__init__(name='time') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + h = string_file(get_abs_path('../itn/japanese/data/time/hour.tsv')) + m = string_file(get_abs_path('../itn/japanese/data/time/minute.tsv')) + s = string_file(get_abs_path('../itn/japanese/data/time/second.tsv')) + + # 一時三十分三秒 一時三十分 三十分三秒 一時 三十分 三秒 + tagger = ((insert('hour: "') + h + insert('" ')).ques + + (insert('minute: "') + m + insert('"')) + + (insert(' second: "') + s + insert('"')).ques + | insert('hour: "') + h + insert('" ') + | insert(' second: "') + s + insert('"')) + tagger = self.add_tokens(tagger) + self.tagger = tagger + + def build_verbalizer(self): + hour = delete('hour: "') + self.SIGMA + delete('"') + delete( + ' ').ques + insert('時') + minute = delete('minute: "') + self.SIGMA + delete('"') + insert('分') + second = delete(' ').ques + delete('second: "') + self.SIGMA + delete( + '"') + insert('秒') + + verbalizer = hour.ques + minute + second.ques | second | hour + self.verbalizer = self.delete_tokens(verbalizer) diff --git a/itn/japanese/rules/whitelist.py b/itn/japanese/rules/whitelist.py new file mode 100644 index 0000000..7249baf --- /dev/null +++ b/itn/japanese/rules/whitelist.py @@ -0,0 +1,34 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import insert + + +class Whitelist(Processor): + + def __init__(self): + super().__init__(name='whitelist') + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + whitelist = string_file( + get_abs_path('../itn/japanese/data/default/whitelist.tsv')) + + tagger = insert('value: "') + whitelist + insert('"') + self.tagger = self.add_tokens(tagger) diff --git a/itn/japanese/test/__init__.py b/itn/japanese/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/itn/japanese/test/data/cardinal.txt b/itn/japanese/test/data/cardinal.txt new file mode 100644 index 0000000..e0b31f3 --- /dev/null +++ b/itn/japanese/test/data/cardinal.txt @@ -0,0 +1,56 @@ +一 => 1 +四 => 4 +十 => 10 +十四 => 14 +四十四 => 44 +四十 => 40 +百一 => 101 +百十二 => 112 +四百四 => 404 +九千百二十三 => 9123 +一千二百三十四 => 1234 +五千六百七十八 => 5678 +二千二十 => 2020 +二千二 => 2002 +二千十 => 2010 +二千百 => 2100 +九千 => 9000 +九千二 => 9002 +十 => 10 +百 => 100 +千 => 1000 +万 => 万 +兆 => 兆 +千百 => 1100 +千三百 => 1300 +千三百十 => 1310 +千十 => 1010 +千二十 => 1020 +千二十一 => 1021 +千一 => 1001 +千百十 => 1110 +千百一 => 1101 +マイナス百十二 => -112 +二十万二 => 20万2 +一万二 => 1万2 +二十万二千百 => 20万2100 +四百万 => 400万 +四百四万 => 404万 +五千万 => 5000万 +二万 => 2万 +一億五千万 => 1億5000万 +一億五万 => 1億5万 +一億一百万 => 1億100万 +一億一千万 => 1億1000万 +二千億一千万 => 2000億1000万 +二千億 => 2000億 +二兆二億 => 2兆2億 +二兆二千億 => 2兆2000億 +二兆二千万 => 2兆2000万 +二兆二百万 => 2兆200万 +一兆三百二十万五千 => 1兆320万5000 +二兆三十 => 2兆30 +二兆一百 => 2兆100 +二十兆一百 => 20兆100 +一九二点一六八点零点一 => 192.168.0.1 +一二三四五六七八九 => 123456789 \ No newline at end of file diff --git a/itn/japanese/test/data/char.txt b/itn/japanese/test/data/char.txt new file mode 100644 index 0000000..dca416b --- /dev/null +++ b/itn/japanese/test/data/char.txt @@ -0,0 +1,2 @@ +中 => 中 +A => A diff --git a/itn/japanese/test/data/date.txt b/itn/japanese/test/data/date.txt new file mode 100644 index 0000000..0cddc37 --- /dev/null +++ b/itn/japanese/test/data/date.txt @@ -0,0 +1,15 @@ +二千二十四年十月一日 => 2024年10月1日 +二千二十四年十月 => 2024年10月 +一日 => 1日 +五から九日 => 5~9日 +一月 => 1月 +三から四月 => 3~4月 +一月一日 => 1月1日 +二十一世紀 => 21世紀 +七十年代 => 70年代 +七から八年 => 7~8年 +二千九年 => 2009年 +月曜日から金曜日 => 月曜日から金曜日 +二十三年二月二十五日土曜日 => 23年2月25日土曜日 +七月五から九日月曜日から金曜日 => 7月5〜9日月曜日から金曜日 +今年はR六 => 今年は令和6 \ No newline at end of file diff --git a/itn/japanese/test/data/fraction.txt b/itn/japanese/test/data/fraction.txt new file mode 100644 index 0000000..81890bf --- /dev/null +++ b/itn/japanese/test/data/fraction.txt @@ -0,0 +1,12 @@ +一荷四分の三 => 1荷3/4 +一荷一分の一 => 1荷1/1 +四分の三 => 3/4 +二と四分の三 => 2と3/4 +二万分の三 => 3/20000 +二万点三 => 20000.3 +ルート三分の一 => 1/√3 +一点六五分の五十 => 50/1.65 +二ルート六分の三 => 3/2√6 +二万 => 2万 +三千 => 3000 +三千分の三 => 3/3000 \ No newline at end of file diff --git a/itn/japanese/test/data/math.txt b/itn/japanese/test/data/math.txt new file mode 100644 index 0000000..19df416 --- /dev/null +++ b/itn/japanese/test/data/math.txt @@ -0,0 +1,6 @@ +四百四万マイナス二万 => 404万-2万 +一マイナス二プラス三十 => 1-2+30 +三対二 => 3:2 +一プラス一イコール二 => 1+1=2 +一カケル二マイナス三プラス四ワル五イコール二 => 1×2-3+4÷5=2 +六から七 => 6~7 \ No newline at end of file diff --git a/itn/japanese/test/data/measure.txt b/itn/japanese/test/data/measure.txt new file mode 100644 index 0000000..cdfc1d3 --- /dev/null +++ b/itn/japanese/test/data/measure.txt @@ -0,0 +1,7 @@ +二千センチメートル每秒 => 2000cm/s +二万センチメートル每秒 => 20000cm/s +二万二千センチメートル每秒 => 22000cm/s +八メガ秒 => 8ms +八百メガ秒 => 800ms +三点五千キロメートル => 3.5km +百人 => 100人 \ No newline at end of file diff --git a/itn/japanese/test/data/normalizer.txt b/itn/japanese/test/data/normalizer.txt new file mode 100644 index 0000000..470f83d --- /dev/null +++ b/itn/japanese/test/data/normalizer.txt @@ -0,0 +1,127 @@ +一 +四 +十 +十四 +四十四 +四十 +百一 +百十二 +四百四 +九千百二十三 +一千二百三十四 +五千六百七十八 +二千二十 +二千二 +二千十 +二千百 +九千 +九千二 +十 +百 +千 +万 +兆 +千百 +千三百 +千三百十 +千十 +千二十 +千二十一 +千一 +千百十 +千百一 +マイナス百十二 +二十万二 +一万二 +二十万二千百 +四百万 +四百四万 +五千万 +二万 +一億五千万 +一億五万 +一億一百万 +一億一千万 +二千億一千万 +二千億 +二兆二億 +二兆二千億 +二兆二千万 +二兆二百万 +一兆三百二十万五千人 +二兆三十 +二兆一百 +二十兆一百 +一九二点一六八点零点一 + +マイナス二万 +プラスマイナス四百四万 +プラスマイナス二 +プラスマイナス千百十 +プラス千百十 + +一二三 +一点五万 + +一日 +五から九日 +一月 +三から四月 +一月一日 +二十一世紀 +七十年代 +七十から八十年代 +二千九年 +二十三年二月二十五日土曜日 +二千二十四年十月一日 +七月五から九日月曜日から金曜日 +今年はR六 + +一荷四分の三 +一荷一分の一 +四分の三 +二と四分の三 +二万分の三 +ルート三分の一 +一点六五分の五十 +二ルート六分の三 + +四百四万マイナス二万 +一マイナス二プラス三十 +三対二 +一プラス一イコール二 +一カケル二マイナス三プラス四ワル五イコール二 +六から七 + +二千センチメートル每秒 +二万センチメートル每秒 +二万二千センチメートル每秒 +八メガ秒 +八百メガ秒 +三点五千キロメートル +百人 +百鸟 +百 千 万 + +第二十三 +二十三番目 + +一時三十分三秒 +五時二十分過ぎ +七分 +七秒 +七時 +八時半頃 +十時五分前 +正午一分前 +正午十分過ぎ + +MNO + +正午一分前,。! + +なんぼやと思う?一万円?なんでやねん。そんな高いわけないやん。2000円やで。ちょっと古いもんやけど、そら別にかまへんわ。ええもんだったら何でもええねん。え、それはちゃう? +焼鳥 +人名用漢字表は随時見直されており、文化的な要請や使用者の要望に応じて、新たに追加されることがあります。例えば、2004年に488字が追加され、2023年には再び改訂されて863字となりました。 +二人 +二十三人 \ No newline at end of file diff --git a/itn/japanese/test/data/number.txt b/itn/japanese/test/data/number.txt new file mode 100644 index 0000000..d08c0b8 --- /dev/null +++ b/itn/japanese/test/data/number.txt @@ -0,0 +1,6 @@ +三点一四一五九二六 => 3.1415926 +マイナス三点一四一五九二六 => -3.1415926 +一百万千百十一 => 100万1111 +一万千百十一 => 1万1111 +一万二千三百 => 1万2300 +二万 => 2万 \ No newline at end of file diff --git a/itn/japanese/test/data/time.txt b/itn/japanese/test/data/time.txt new file mode 100644 index 0000000..4bf37c1 --- /dev/null +++ b/itn/japanese/test/data/time.txt @@ -0,0 +1,9 @@ +一時三十分三秒 => 1時30分3秒 +五時二十分過ぎ => 5時20分過ぎ +七分 => 7分 +七秒 => 7秒 +七時 => 7時 +八時半頃 => 8時半頃 +十時五分前 => 10時5分前 +正午一分前 => 正午1分前 +正午十分過ぎ => 正午10分過ぎ \ No newline at end of file diff --git a/itn/japanese/test/data/whitelist.txt b/itn/japanese/test/data/whitelist.txt new file mode 100644 index 0000000..94fdb4a --- /dev/null +++ b/itn/japanese/test/data/whitelist.txt @@ -0,0 +1,2 @@ +十三湖 => 十三湖 +一月三舟 => 一月三舟 \ No newline at end of file diff --git a/itn/japanese/test/normalizer_test.py b/itn/japanese/test/normalizer_test.py new file mode 100644 index 0000000..75e4d57 --- /dev/null +++ b/itn/japanese/test/normalizer_test.py @@ -0,0 +1,42 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +from itertools import chain + +from itn.japanese.inverse_normalizer import InverseNormalizer +from itn.japanese.test.utils import parse_test_case + + +class TestNormalizer: + + normalizer = InverseNormalizer(overwrite_cache=True, + enable_standalone_number=True, + enable_0_to_9=True, + enable_million=False) + + normalizer_cases = chain(parse_test_case('data/cardinal.txt'), + parse_test_case('data/char.txt'), + parse_test_case('data/date.txt'), + parse_test_case('data/fraction.txt'), + parse_test_case('data/math.txt'), + parse_test_case('data/measure.txt'), + parse_test_case('data/number.txt'), + parse_test_case('data/time.txt'), + parse_test_case('data/whitelist.txt')) + + @pytest.mark.parametrize("spoken, written", normalizer_cases) + def test_normalizer(self, spoken, written): + assert self.normalizer.normalize(spoken) == written diff --git a/itn/japanese/test/utils.py b/itn/japanese/test/utils.py new file mode 120000 index 0000000..a2ade7b --- /dev/null +++ b/itn/japanese/test/utils.py @@ -0,0 +1 @@ +../../../tn/chinese/test/utils.py \ No newline at end of file diff --git a/itn/main.py b/itn/main.py index d14ee8f..58693e9 100644 --- a/itn/main.py +++ b/itn/main.py @@ -15,7 +15,8 @@ import argparse # TODO(xcsong): multi-language support -from itn.chinese.inverse_normalizer import InverseNormalizer +from itn.chinese.inverse_normalizer import InverseNormalizer as ZhInverseNormalizer +from itn.japanese.inverse_normalizer import InverseNormalizer as JaInverseNormalizer def str2bool(s, default=False): @@ -51,14 +52,27 @@ def main(): type=str, default='False', help='六百万 = 6000000 if True else 600万') + parser.add_argument('--language', + type=str, + default='zh', + choices=["zh", "ja"], + help='valid languages') 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_million=str2bool(args.enable_million)) + if args.language == 'zh': + normalizer = ZhInverseNormalizer( + 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_million=str2bool(args.enable_million)) + elif args.language == 'ja': + normalizer = JaInverseNormalizer( + 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_million=str2bool(args.enable_million)) if args.text: print(normalizer.tag(args.text)) From 76522f937ac1de04bb27595524154e2e48aeb8ec Mon Sep 17 00:00:00 2001 From: LoganLiu66 <2319277867@qq.com> Date: Wed, 23 Oct 2024 15:36:33 +0800 Subject: [PATCH 3/9] [tn] fix Japanese TN --- tn/japanese/data/date/d.tsv | 2 +- tn/japanese/data/date/dd.tsv | 2 +- tn/japanese/data/math/operator.tsv | 9 ++- tn/japanese/data/measure/units_en.tsv | 9 ++- tn/japanese/data/number/zero.tsv | 4 +- tn/japanese/data/time/hour.tsv | 7 +- tn/japanese/normalizer.py | 2 +- tn/japanese/rules/cardinal.py | 62 ++++++++++----- tn/japanese/rules/date.py | 12 ++- tn/japanese/rules/fraction.py | 2 +- tn/japanese/rules/math.py | 13 +-- tn/japanese/rules/sport.py | 12 +-- tn/japanese/rules/time.py | 18 +++-- tn/japanese/test/data/cardinal.txt | 51 ++++++++---- tn/japanese/test/data/date.txt | 17 +++- tn/japanese/test/data/fraction.txt | 6 +- tn/japanese/test/data/math.txt | 26 +++--- tn/japanese/test/data/measure.txt | 1 + tn/japanese/test/data/normalizer.txt | 110 -------------------------- tn/japanese/test/data/sport.txt | 6 +- tn/japanese/test/data/time.txt | 4 +- 21 files changed, 170 insertions(+), 205 deletions(-) delete mode 100644 tn/japanese/test/data/normalizer.txt diff --git a/tn/japanese/data/date/d.tsv b/tn/japanese/data/date/d.tsv index d0df2d1..5734e96 100644 --- a/tn/japanese/data/date/d.tsv +++ b/tn/japanese/data/date/d.tsv @@ -1,4 +1,4 @@ -1 一日 +1 一日 2 二日 3 三日 4 四日 diff --git a/tn/japanese/data/date/dd.tsv b/tn/japanese/data/date/dd.tsv index 1ce1af7..0a5f563 100644 --- a/tn/japanese/data/date/dd.tsv +++ b/tn/japanese/data/date/dd.tsv @@ -1,4 +1,4 @@ -01 一日 +01 一日 02 二日 03 三日 04 四日 diff --git a/tn/japanese/data/math/operator.tsv b/tn/japanese/data/math/operator.tsv index f896b36..c04eba8 100644 --- a/tn/japanese/data/math/operator.tsv +++ b/tn/japanese/data/math/operator.tsv @@ -2,6 +2,11 @@ - マイナス + プラス = イコール +> 大なり +< 小なり +≥ 大なりイコール +≤ 小なりイコール +>= 大なりイコール +<= 小なりイコール ÷ ワル -~ から -: 対 \ No newline at end of file +~ から \ No newline at end of file diff --git a/tn/japanese/data/measure/units_en.tsv b/tn/japanese/data/measure/units_en.tsv index 17e2dea..b56e183 100644 --- a/tn/japanese/data/measure/units_en.tsv +++ b/tn/japanese/data/measure/units_en.tsv @@ -19,12 +19,13 @@ min 分 sec 秒 s 秒 ms ミリ秒 -°C 摂氏温度 -℃ 摂氏温度 -°F 華氏温度 +°C 摂氏 +℃ 摂氏 +°F 華氏 mm² 平方ミリメートル cm² 平方センチメートル m² 平方メートル +㎡ 平方メートル km² 平方キロメートル ha ヘクタール ml ミリリットル @@ -71,7 +72,7 @@ cal カロリー KCal キロカロリー Cal カロリー W ワット -kWh キロワットアワー +kWh キロワット時 kW キロワット J·s ジュール秒 A アンペア diff --git a/tn/japanese/data/number/zero.tsv b/tn/japanese/data/number/zero.tsv index 1979ed8..c407666 100644 --- a/tn/japanese/data/number/zero.tsv +++ b/tn/japanese/data/number/zero.tsv @@ -1,2 +1,2 @@ -0 ゼロ -0 ゼロ +0 〇 +0 〇 diff --git a/tn/japanese/data/time/hour.tsv b/tn/japanese/data/time/hour.tsv index bedfb76..a1014f0 100644 --- a/tn/japanese/data/time/hour.tsv +++ b/tn/japanese/data/time/hour.tsv @@ -1,5 +1,6 @@ +0 〇時 1 一時 -2 两時 +2 二時 3 三時 4 四時 5 五時 @@ -7,9 +8,9 @@ 7 七時 8 八時 9 九時 -00 零時 +00 〇時 01 一時 -02 两時 +02 二時 03 三時 04 四時 05 五時 diff --git a/tn/japanese/normalizer.py b/tn/japanese/normalizer.py index 2fcd236..42ef6c1 100644 --- a/tn/japanese/normalizer.py +++ b/tn/japanese/normalizer.py @@ -57,7 +57,7 @@ def build_tagger(self): math = add_weight(Math().tagger, 90) measure = add_weight(Measure().tagger, 1.05) money = add_weight(Money().tagger, 1.05) - sport = add_weight(Sport().tagger, 1.04) + sport = add_weight(Sport().tagger, 1.06) time = add_weight(Time().tagger, 1.05) whitelist = add_weight(Whitelist().tagger, 1.03) tagger = (cardinal | char | date | fraction | math | measure | money diff --git a/tn/japanese/rules/cardinal.py b/tn/japanese/rules/cardinal.py index e67319d..d2e7898 100644 --- a/tn/japanese/rules/cardinal.py +++ b/tn/japanese/rules/cardinal.py @@ -15,7 +15,7 @@ from tn.processor import Processor from tn.utils import get_abs_path -from pynini import string_file, cross +from pynini import string_file, cross, accep from pynini.lib.pynutil import delete, insert @@ -23,8 +23,8 @@ class Cardinal(Processor): def __init__(self): super().__init__(name='cardinal') - self.thousand = None - self.thousands = None + self.thousand = None # used for year of date + self.positive_integer = None # used for sport self.number = None self.digits = None self.build_tagger() @@ -32,10 +32,9 @@ def __init__(self): def build_tagger(self): zero = string_file(get_abs_path('japanese/data/number/zero.tsv')) + en_zero = cross('0', 'ゼロ') # 1-9 digit = string_file(get_abs_path('japanese/data/number/digit.tsv')) - en_digit = string_file( - get_abs_path('japanese/data/number/en_digit.tsv')) teen = string_file(get_abs_path('japanese/data/number/teen.tsv')) sign = string_file(get_abs_path('japanese/data/number/sign.tsv')) dot = string_file(get_abs_path('japanese/data/number/dot.tsv')) @@ -46,45 +45,70 @@ def build_tagger(self): # 0-9 digits = zero | digit - en_digits = zero | en_digit self.digits = digits # 10-99 ten = teen + insert('十') + (digit | rmzero) + # 100-999 hundred = (teen + insert('百') + (ten | (rmzero + digit) | rmzero**2)) + # hundred prefix like "1,11" in "1,115,000" + hundred_prefix = (teen + insert('百') + rmpunct + + (ten | (rmzero + digit) | rmzero**2)) + # 1000-9999 thousand = (teen + insert('千') + rmpunct + (hundred | (rmzero + ten) | (rmzero**2 + digit) | rmzero**3)) + # thousand prefix like "10,00" in "10,000,000" + thousand_prefix = (digit + insert('千') + + (hundred_prefix + | (rmzero + rmpunct + ten) + | (rmzero + rmpunct + rmzero + digit) + | rmzero + rmpunct + rmzero**2)) self.thousand = thousand - # 10000-99999999 - ten_thousand = ((thousand | hundred | ten | digit) + insert('万') + + + # 10000-99999999 1,115,000 10,000,000 + ten_thousand = ((thousand_prefix | hundred_prefix | ten | digit) + + insert('万') + (thousand | (rmzero + rmpunct + hundred) | (rmzero + rmpunct + rmzero + ten) | (rmzero + rmpunct + rmzero + rmzero + digit) - | rmzero**4)) + | rmzero + rmpunct + rmzero**3)) + # 100,000,000+ + hundred_millon = ((thousand_prefix | hundred_prefix | ten | digit) + + insert('億') + rmzero**2 + rmpunct + rmzero**2 + + (thousand + | (rmzero + rmpunct + hundred) + | (rmzero + rmpunct + rmzero + ten) + | (rmzero + rmpunct + rmzero + rmzero + digit) + | rmzero + rmpunct + rmzero**3)) # 0-99999999 - number = digits | ten | hundred | thousand | ten_thousand - self.thousands = digits | ten | hundred | thousand + number = digits | ten | hundred | thousand | ten_thousand | hundred_millon + self.positive_integer = number # ±0.0 - ±99999999.99999999 - number = sign.ques + number + (dot + en_digits.plus).ques + number = sign.ques + number + (dot + digits.plus).ques self.number = number # % like -27.00% percent = number + delete('%') + insert('パーセント') # ip like 127.0.0.1 - ip_dot = cross('.', 'ドット') - ip = en_digits.plus + (ip_dot + en_digits.plus)**3 + ip = digits.plus + (dot + digits.plus)**3 # phone like 0xx-xxxx-xxxx country_code = (cross('+81', 'プラス八一') + cross('-', 'の').ques + rmspace) - phone = (zero + en_digit + zero.ques + cross('-', 'の') + en_digits**3 + - en_digits.ques + cross('-', 'の').ques + en_digits**4) - phone = country_code.ques + phone + en_digits = en_zero | digit + phone = (en_zero + digit + en_zero.ques + cross('-', 'の') + + en_digits**3 + en_digits.ques + cross('-', 'の').ques + + en_digits**4) + phone = country_code.ques + ( + phone | en_zero + digit + en_zero.ques + en_digits**8) + # No. 番号 + ordinal = (accep('No.') | accep('番号') | accep('番号は')) + digits.plus + room = digits.plus + accep('号室') # others like 342388491 - others = en_digits**8 + en_digits.plus + others = digits**8 + digits.plus - number = number | percent | ip | phone | others + number = number | percent | ip | phone | ordinal | room | others tagger = insert('value: "') + number.optimize() + insert('"') self.tagger = self.add_tokens(tagger) diff --git a/tn/japanese/rules/date.py b/tn/japanese/rules/date.py index c2441fd..ae8fb08 100644 --- a/tn/japanese/rules/date.py +++ b/tn/japanese/rules/date.py @@ -68,10 +68,18 @@ def build_tagger(self): | (year + rmsign + mm) | (mm + rmsign + year) | (mm + rmsign + day)) + # yyyy/0m | 0m/yyyy | 0m/dd + simple_date = ((year + rmsign + month) + | (month + rmsign + year) + | (month + rmsign + day)) + tagger = self.add_tokens(date) + simple_tagger = self.add_tokens(simple_date) - to = (delete('-') | delete('~')) + insert(' char { value: "から" } ') - self.tagger = tagger + (to + tagger).ques + to = ((delete('-') | delete('~') | delete('から')) + + insert(' char { value: "から" } ')) + self.tagger = (tagger + (to + tagger).ques + | simple_tagger + to + simple_tagger) def build_verbalizer(self): year = delete('year: "') + self.SIGMA + delete('" ') diff --git a/tn/japanese/rules/fraction.py b/tn/japanese/rules/fraction.py index e2b208d..ced4f39 100644 --- a/tn/japanese/rules/fraction.py +++ b/tn/japanese/rules/fraction.py @@ -37,5 +37,5 @@ def build_tagger(self): def build_verbalizer(self): denominator = delete('denominator: "') + self.SIGMA + delete('" ') numerator = delete('numerator: "') + self.SIGMA + delete('"') - verbalizer = denominator + insert('の') + numerator + verbalizer = denominator + insert('分の') + numerator self.verbalizer = self.delete_tokens(verbalizer) diff --git a/tn/japanese/rules/math.py b/tn/japanese/rules/math.py index 3eb4a22..3c795ea 100644 --- a/tn/japanese/rules/math.py +++ b/tn/japanese/rules/math.py @@ -33,16 +33,5 @@ def build_tagger(self): number = Cardinal().number operator = number + (delete(" ").ques + operator + delete(" ").ques + number).star - bigger = operator + (delete(" ").ques + delete(">") + insert("は") + - delete(" ").ques + number + insert("より大きい")).star - smaller = operator + (delete(" ").ques + delete("<") + insert("は") + - delete(" ").ques + number + insert("より小きい")).star - no_less = operator + (delete(" ").ques + - (delete("≥") | delete(">=")) + insert("は") + - delete(" ").ques + number + insert("以上")).star - no_more = operator + (delete(" ").ques + - (delete("≤") | delete("<=")) + insert("は") + - delete(" ").ques + number + insert("以下")).star - tagger = (operator) | (bigger) | (smaller) | (no_less) | (no_more) - tagger = insert('value: "') + tagger + insert('"') + tagger = insert('value: "') + operator + insert('"') self.tagger = self.add_tokens(tagger) diff --git a/tn/japanese/rules/sport.py b/tn/japanese/rules/sport.py index e4a20c1..3a019c0 100644 --- a/tn/japanese/rules/sport.py +++ b/tn/japanese/rules/sport.py @@ -16,7 +16,7 @@ from tn.processor import Processor from tn.utils import get_abs_path -from pynini import string_file +from pynini import string_file, cross from pynini.lib.pynutil import delete, insert @@ -33,15 +33,17 @@ def build_tagger(self): rmsign = delete('/') | delete('-') | delete(':') rmspace = delete(' ').ques - number = Cardinal().number + number = Cardinal().positive_integer score = rmspace + number + rmsign + insert('対') + number + rmspace + only_score = rmspace + number + cross(':', '対') + number + rmspace tagger = (insert('team: "') + (country | club) + insert('" score: "') + - score + insert('"')) + score + insert('"')) | (insert('score: "') + only_score + + insert('"')) self.tagger = self.add_tokens(tagger) def build_verbalizer(self): super().build_verbalizer() team = delete('team: "') + self.SIGMA + delete('" ') score = delete('score: "') + self.SIGMA + delete('"') - verbalizer = team + score - self.verbalizer |= self.delete_tokens(verbalizer) + verbalizer = team.ques + score + self.verbalizer = self.delete_tokens(verbalizer) diff --git a/tn/japanese/rules/time.py b/tn/japanese/rules/time.py index ecedcec..75b4050 100644 --- a/tn/japanese/rules/time.py +++ b/tn/japanese/rules/time.py @@ -33,11 +33,13 @@ def build_tagger(self): noon = string_file(get_abs_path('japanese/data/time/noon.tsv')) colon = delete(':') | delete(':') - tagger = (insert('hour: "') + h + insert('" ') + colon + - insert('minute: "') + m + insert('"') + - (colon + insert(' second: "') + s + insert('"')).ques + - delete(' ').ques + - (insert(' noon: "') + noon + insert('"')).ques) + tagger = ( + (insert('hour: "') + h + insert('" ') + colon + + insert('minute: "') + m + insert('"') + + (colon + insert(' second: "') + s + insert('"')).ques + + delete(' ').ques + (insert(' noon: "') + noon + insert('"')).ques) + | + (insert('hour: "') + h + insert('" noon: "') + noon + insert('"'))) tagger = self.add_tokens(tagger) to = (delete('-') | delete('~')) + insert(' char { value: "から" } ') @@ -45,8 +47,8 @@ def build_tagger(self): def build_verbalizer(self): noon = delete('noon: "') + self.SIGMA + delete('" ') - hour = delete('hour: "') + self.SIGMA + delete('" ') - minute = delete('minute: "') + self.SIGMA + delete('"') + hour = delete('hour: "') + self.SIGMA + delete('"') + minute = delete(' minute: "') + self.SIGMA + delete('"') second = delete(' second: "') + self.SIGMA + delete('"') - verbalizer = noon.ques + hour + minute + second.ques + verbalizer = noon.ques + hour + minute + second.ques | noon + hour self.verbalizer = self.delete_tokens(verbalizer) diff --git a/tn/japanese/test/data/cardinal.txt b/tn/japanese/test/data/cardinal.txt index 010e9c6..a47d452 100644 --- a/tn/japanese/test/data/cardinal.txt +++ b/tn/japanese/test/data/cardinal.txt @@ -1,18 +1,41 @@ 1118 => 千百十八 -1118 => マイナス千百十八 -9.99999 => 九点きゅうきゅうきゅうきゅうきゅう -20099.1001 => 二万九十九点いちゼロゼロいち +9.99999 => 九点九九九九九 +20099.1001 => 二万九十九点一〇〇一 11118 => 一万千百十八 --200.001 => マイナス二百点ゼロゼロいち +-200.001 => マイナス二百点〇〇一 100% => 百パーセント --50.04% => マイナス五十点ゼロよんパーセント --50.07% => マイナス五十点ゼロななパーセント -192.168.0.1 => いちきゅうにドットいちろくはちドットゼロドットいち -090-1234-5678 => ゼロきゅうゼロのいちにさんよんのごろくななはち -090-12345678 => ゼロきゅうゼロのいちにさんよんごろくななはち -+81-090-1234-5678 => プラス八一のゼロきゅうゼロのいちにさんよんのごろくななはち -+81 090-1234-5678 => プラス八一ゼロきゅうゼロのいちにさんよんのごろくななはち -+81 090-123-5678 => プラス八一ゼロきゅうゼロのいちにさんのごろくななはち -+81 09012345678 => プラス八十一 ゼロきゅうゼロいちにさんよんごろくななはち -02-1234-5678 => ゼロにのいちにさんよんのごろくななはち -1.1234567 => 一点いちにさんよんごろくなな +-50.04% => マイナス五十点〇四パーセント +-50.07% => マイナス五十点〇七パーセント +192.168.0.1 => 一九二点一六八点〇点一 +090-1234-5678 => ゼロ九ゼロの一二三四の五六七八 +090-12345678 => ゼロ九ゼロの一二三四五六七八 ++81-090-1234-5678 => プラス八一のゼロ九ゼロの一二三四の五六七八 ++81 090-1234-5678 => プラス八一ゼロ九ゼロの一二三四の五六七八 ++81 090-123-5678 => プラス八一ゼロ九ゼロの一二三の五六七八 ++81 09012345678 => プラス八一ゼロ九ゼロ一二三四五六七八 +02-1234-5678 => ゼロ二の一二三四の五六七八 +1.1234567 => 一点一二三四五六七 +123456789 => 一二三四五六七八九 +0.0005 => 〇点〇〇〇五 +No.1005 => No.一〇〇五 +番号1234 => 番号一二三四 +1234号室 => 一二三四号室 +150,000 => 十五万 +10,000 => 一万 +11,000 => 一万千 +1,115,000 => 百十一万五千 +10,000,000 => 一千万 +10,100,000 => 一千十万 +1,000 => 千 +150000 => 十五万 +10000 => 一万 +11000 => 一万千 +1115000 => 百十一万五千 +1000 => 千 +100000 => 十万 +1000000 => 百万 +10100000 => 一千十万 +0時に花火が打ち上げられます => 〇時に花火が打ち上げられます +-80000000600 => マイナス八百億六百 +-80010000600 => マイナス八〇〇一〇〇〇〇六〇〇 \ No newline at end of file diff --git a/tn/japanese/test/data/date.txt b/tn/japanese/test/data/date.txt index 1aab68e..e9baa67 100644 --- a/tn/japanese/test/data/date.txt +++ b/tn/japanese/test/data/date.txt @@ -1,5 +1,6 @@ 1998/04/23 => 千九百九十八年四月二十三日 -2023/11/34 => 二千二十三年十一月三日四 +2023/11/14 => 二千二十三年十一月十四日 +2023/11/01 => 二千二十三年十一月一日 2008/08 => 二千八年八月 08/2008 => 二千八年八月 08/08 => 八月八日 @@ -12,4 +13,16 @@ 2008.8.8 => 二千八年八月八日 2008.08 => 二千八年八月 08.2008 => 二千八年八月 -08.08 => 八月八日 \ No newline at end of file +08.08 => 八月八日 +来月の旅行は12/15から12/20までです => 来月の旅行は十二月十五日から十二月二十日までです +次の週末は11/5から11/6です => 次の週末は十一月五日から十一月六日です +2008.08.08-2008.08.10 => 二千八年八月八日から二千八年八月十日 +23/10 => 十分の二十三 +1/3 => 三分の一 +今日は2036-03-01です => 今日は二千三十六年三月一日です +今日は2036/03/01です => 今日は二千三十六年三月一日です +来週の月曜日は2036.2.28です => 来週の月曜日は二千三十六年二月二十八日です +次の週末は4/30から5/1です => 次の週末は四月三十日から五月一日です +来月の旅行は5-15から5-20です => 来月の旅行は五月十五日から五月二十日です +次の会議は2022-12-1に開催されます => 次の会議は二千二十二年十二月一日に開催されます +今日は2022.11.19です => 今日は二千二十二年十一月十九日です \ No newline at end of file diff --git a/tn/japanese/test/data/fraction.txt b/tn/japanese/test/data/fraction.txt index 3fbd90b..387d852 100644 --- a/tn/japanese/test/data/fraction.txt +++ b/tn/japanese/test/data/fraction.txt @@ -1,3 +1,3 @@ -1/100 => 百の一 --1/100 => 百のマイナス一 -1 / 2 => 二の一 \ No newline at end of file +1/100 => 百分の一 +-1/100 => 百分のマイナス一 +1 / 2 => 二分の一 \ No newline at end of file diff --git a/tn/japanese/test/data/math.txt b/tn/japanese/test/data/math.txt index b4ae038..1727723 100644 --- a/tn/japanese/test/data/math.txt +++ b/tn/japanese/test/data/math.txt @@ -1,26 +1,26 @@ 1-2=-1 => 一マイナス二イコールマイナス一 -1+2>2 => 一プラス二は二より大きい -2:3 => 二対三 +1+2>2 => 一プラス二大なり二 4×5=20 => 四カケル五イコール二十 4x5=20 => 四x五イコール二十 1~100 => 一から百 -3>=3 => 三は三以上 -3≥2≥1 => 三は二以上は一以上 -3 ≥ 2 => 三は二以上 -2>1 => 二は一より大きい -2 > 1 => 二は一より大きい -1<2 => 一は二より小きい -5×4÷2+3-6 ≥ 7 => 五カケル四ワル二プラス三マイナス六は七以上 -1+3+2+3>3 => 一プラス三プラス二プラス三は三より大きい +3>=3 => 三大なりイコール三 +3≥2≥1 => 三大なりイコール二大なりイコール一 +3 ≥ 2 => 三大なりイコール二 +2>1 => 二大なり一 +2 > 1 => 二大なり一 +1<2 => 一小なり二 +5×4÷2+3-6 ≥ 7 => 五カケル四ワル二プラス三マイナス六大なりイコール七 +1≥0 => 一大なりイコール〇 +1+3+2+3>3 => 一プラス三プラス二プラス三大なり三 1-1 => 一マイナス一 -1:1 => 一対一 1+1 => 一プラス一 abc/3 => abc/三 -1/3 => 三の一 1 + 1 => 一プラス一 ±5 => プラスマイナス五 abc+5 => abcプラス五 1+1=2 => 一プラス一イコール二 1+2+3=6 => 一プラス二プラス三イコール六 911-1234-5678 => 九百十一マイナス千二百三十四マイナス五千六百七十八 -112-1234-5678 => 百十二マイナス千二百三十四マイナス五千六百七十八 \ No newline at end of file +112-1234-5678 => 百十二マイナス千二百三十四マイナス五千六百七十八 +5-15 => 五マイナス十五 +4/900000000を切る => 九億分の四を切る \ No newline at end of file diff --git a/tn/japanese/test/data/measure.txt b/tn/japanese/test/data/measure.txt index e58f3db..bc81fea 100644 --- a/tn/japanese/test/data/measure.txt +++ b/tn/japanese/test/data/measure.txt @@ -3,6 +3,7 @@ 22-26年 => 二十二から二十六年 1~3年 => 一から三年 1-3平方 => 一から三平方 +0km/h => 〇キロメートル毎時 10km/h => 十キロメートル毎時 2m/s => 二メートル毎秒 100fph/s => 百フィート毎時毎秒 diff --git a/tn/japanese/test/data/normalizer.txt b/tn/japanese/test/data/normalizer.txt deleted file mode 100644 index 8902ba9..0000000 --- a/tn/japanese/test/data/normalizer.txt +++ /dev/null @@ -1,110 +0,0 @@ -1998/04/23 -2023/11/34 -2008-08-23 -2008.8.8 -1118 --1118 -9.99999 -20099.1001 -11118 --200.001 -100% --50.01% -192.168.0.1 -090-1234-5678 -090-12345678 -2000人 -せいれき せんねん じゅうがつ ついたち -P2P finance - -3:2 -3:02 -3:40am -3:40a.m. -3:40AM -3:40A M -3:30pm -3:30 -3:30-4:34 - -USD1001 -HKD1002 -¥22 -¥ 22 -$10000 -CAD -CAD1001 - -1/100 --1/100 - -1-2=-1 -1+2>2 -2:3 -4×5=20 -4x5=20 -1~100 -3>=3 -3≥2≥1 -3 ≥ 2 -2>1 -2 > 1 -1<2 -5×4÷2+3-6 ≥ 7 -1+3+2+3>3 -<足す> -足す~ -足す: -1-1 三种读法 の 対 マイナス -1:1 -1+1 -abc/3 -1/3 -1 + 1 -±5 -abc+5 -1+1=2 -1+2+3=6 - -2022-2023年 -1-3年 -22-26年 -1~3年 -1-3平方 -10km/h -2m/s -100fph/s -1-200キロ -10-11月 - -R-18 -FOREVER21 -2319277867@qq.com -中国韓国3:2 -中国韓国3-2 -ACミラン3:2 -ACミラン3-2 -国韓3:2 -国韓3-2 - -手机号 -1-2-3 -1-2-3-4 -112 -11111111 -1111111111 -090-1234-5678 -911-1234-5678 -9000-1234-5678 -09012345678 -02-1234-5678 -112-1234-5678 -+81-090-1234-5678 -+81 090-1234-5678 -+81 090-123-5678 -+81 09012345678 -+81 911-1234-5678 -9000 - -なんぼやと思う?一万円?なんでやねん。そんな高いわけないやん。2000円やで。ちょっと古いもんやけど、そら別にかまへんわ。ええもんだったら何でもええねん。え、それはちゃう? -人名用漢字表は随時見直されており、文化的な要請や使用者の要望に応じて、新たに追加されることがあります。例えば、2004年に488字が追加され、2023年には再び改訂されて863字となりました。 \ No newline at end of file diff --git a/tn/japanese/test/data/sport.txt b/tn/japanese/test/data/sport.txt index 784bc3e..a76fe77 100644 --- a/tn/japanese/test/data/sport.txt +++ b/tn/japanese/test/data/sport.txt @@ -1,5 +1,9 @@ 中国韓国3:2 => 中国韓国三対二 中国韓国3-2 => 中国韓国三対二 +中国韓国3-0 => 中国韓国三対〇 ACミラン3:2 => ACミラン三対二 ACミラン3-2 => ACミラン三対二 -国韓3:2 => 国韓三対二 \ No newline at end of file +国韓3:2 => 国韓三対二 +2:3 => 二対三 +3:0 => 三対〇 +1:1 => 一対一 diff --git a/tn/japanese/test/data/time.txt b/tn/japanese/test/data/time.txt index fbc4714..5742cdb 100644 --- a/tn/japanese/test/data/time.txt +++ b/tn/japanese/test/data/time.txt @@ -5,4 +5,6 @@ 3:40A M => 午前三時四十分 3:30pm => 午後三時三十分 3:30 => 三時三十分 -3:30-4:34 => 三時三十分から四時三十四分 \ No newline at end of file +3:30-4:34 => 三時三十分から四時三十四分 +10p.m. => 午後十時 +0:30くらいつく => 〇時三十分くらいつく \ No newline at end of file From ec2071705c7b231087e8fd420c14e3ae46e7f984 Mon Sep 17 00:00:00 2001 From: LoganLiu66 <2319277867@qq.com> Date: Mon, 28 Oct 2024 01:04:12 +0800 Subject: [PATCH 4/9] [itn] fix Japanese ITN --- itn/japanese/data/money/currency.tsv | 35 ----- itn/japanese/data/money/symbol.tsv | 11 ++ itn/japanese/data/number/zero.tsv | 3 +- itn/japanese/inverse_normalizer.py | 10 +- itn/japanese/rules/cardinal.py | 96 +++++-------- itn/japanese/rules/fraction.py | 5 +- itn/japanese/rules/measure.py | 5 +- itn/japanese/rules/money.py | 47 +++++++ itn/japanese/rules/ordinal.py | 2 +- itn/japanese/test/data/cardinal.txt | 13 +- itn/japanese/test/data/date.txt | 2 - itn/japanese/test/data/fraction.txt | 6 +- itn/japanese/test/data/math.txt | 2 +- itn/japanese/test/data/measure.txt | 1 - itn/japanese/test/data/money.txt | 1 + itn/japanese/test/data/normalizer.txt | 127 ------------------ ...sable_standalone_number_disable_0_to_9.txt | 71 ++++++++++ ...isable_standalone_number_enable_0_to_9.txt | 71 ++++++++++ ...nable_standalone_number_disable_0_to_9.txt | 69 ++++++++++ itn/japanese/test/data/number.txt | 11 +- itn/japanese/test/normalizer_test.py | 64 +++++++++ 21 files changed, 405 insertions(+), 247 deletions(-) delete mode 100644 itn/japanese/data/money/currency.tsv create mode 100644 itn/japanese/data/money/symbol.tsv create mode 100644 itn/japanese/rules/money.py create mode 100644 itn/japanese/test/data/money.txt delete mode 100644 itn/japanese/test/data/normalizer.txt create mode 100644 itn/japanese/test/data/normalizer_disable_standalone_number_disable_0_to_9.txt create mode 100644 itn/japanese/test/data/normalizer_disable_standalone_number_enable_0_to_9.txt create mode 100644 itn/japanese/test/data/normalizer_enable_standalone_number_disable_0_to_9.txt diff --git a/itn/japanese/data/money/currency.tsv b/itn/japanese/data/money/currency.tsv deleted file mode 100644 index 58cdfc4..0000000 --- a/itn/japanese/data/money/currency.tsv +++ /dev/null @@ -1,35 +0,0 @@ -$ ドル -$ 米ドル -$ 米ドル -£ 英国ポンド -€ ユーロ -₩ 勝った -nzd ニュージーランドドル -rs ルピー -chf スイスフラン -dkk デンマーククローネ -fim フィンランドのマルッカ -aed アラブ首長国連邦ディルハム -¥ 円 -czk チェココルナ -mro モーリタニアのウギア -pkr パキスタン・ルピー -crc コスタリカのコロン -hk$ 香港ドル -npr ネパールルピー -awg アルバフロリン -nok ノルウェークローネ -tzs タンザニアシリング -sek スウェーデンクローナ -cyp キプロスポンド -r 本物 -sar サウジアラビアリヤル -cve カーボベルデ エスクード -rsd セルビアディナール -dm ドイツマーク -shp セントヘレナ・ポンド -php フィリピンペソ -cad カナダドル -ssp 南スーダンポンド -scr セーシェル・ルピー -mvr モルディブ・ルフィア \ No newline at end of file diff --git a/itn/japanese/data/money/symbol.tsv b/itn/japanese/data/money/symbol.tsv new file mode 100644 index 0000000..dc37df0 --- /dev/null +++ b/itn/japanese/data/money/symbol.tsv @@ -0,0 +1,11 @@ +ドル $ +ポンド £ +ポンド £ +円 ¥ +円 ¥ +バーツ ฿ +ユーロ € +インドルピー ₹ +ルーブル ₽ +スイスフラン CHF +レアル R$ \ No newline at end of file diff --git a/itn/japanese/data/number/zero.tsv b/itn/japanese/data/number/zero.tsv index f9b960e..8c2f0f4 100644 --- a/itn/japanese/data/number/zero.tsv +++ b/itn/japanese/data/number/zero.tsv @@ -1,3 +1,4 @@ 〇 0 零 0 -ゼロ 0 \ No newline at end of file +ゼロ 0 +れい 0 \ No newline at end of file diff --git a/itn/japanese/inverse_normalizer.py b/itn/japanese/inverse_normalizer.py index 9444230..884ae19 100644 --- a/itn/japanese/inverse_normalizer.py +++ b/itn/japanese/inverse_normalizer.py @@ -19,6 +19,7 @@ from itn.japanese.rules.fraction import Fraction from itn.japanese.rules.math import Math from itn.japanese.rules.measure import Measure +from itn.japanese.rules.money import Money from itn.japanese.rules.ordinal import Ordinal from itn.japanese.rules.preprocessor import PreProcessor from itn.japanese.rules.postprocessor import PostProcessor @@ -59,12 +60,14 @@ def build_tagger(self): math = add_weight(Math().tagger, 90) measure = add_weight( Measure(enable_0_to_9=self.enable_0_to_9).tagger, 1.05) + money = add_weight( + Money(enable_0_to_9=self.enable_0_to_9).tagger, 1.04) ordinal = add_weight(Ordinal().tagger, 1.04) time = add_weight(Time().tagger, 1.04) whitelist = add_weight(Whitelist().tagger, 1.01) - tagger = (cardinal | char | date | fraction | math | measure | ordinal - | time | whitelist).optimize().star + tagger = (cardinal | char | date | fraction | math | measure | money + | ordinal | time | whitelist).optimize().star tagger = (processor @ tagger).star # remove the last space self.tagger = tagger @ self.build_rule(delete(' '), '', '[EOS]') @@ -76,11 +79,12 @@ def build_verbalizer(self): fraction = Fraction().verbalizer math = Math().verbalizer measure = Measure().verbalizer + money = Money().verbalizer ordinal = Ordinal().verbalizer time = Time().verbalizer whitelist = Whitelist().verbalizer - verbalizer = cardinal | char | date | fraction | math | measure | ordinal | time | whitelist + verbalizer = cardinal | char | date | fraction | math | measure | money | ordinal | time | whitelist processor = PostProcessor().processor self.verbalizer = (verbalizer @ processor).star diff --git a/itn/japanese/rules/cardinal.py b/itn/japanese/rules/cardinal.py index 9e5a3f6..b55040f 100644 --- a/itn/japanese/rules/cardinal.py +++ b/itn/japanese/rules/cardinal.py @@ -30,9 +30,8 @@ def __init__(self, self.enable_0_to_9 = enable_0_to_9 self.enable_million = enable_million self.ten_thousand_minus = None # used for year of date - self.positive_integer = None # used for ordinal、measure - self.big_integer = None # for math self.number = None + self.number_exclude_0_to_9 = None self.decimal = None # used for math self.build_tagger() self.build_verbalizer() @@ -79,73 +78,47 @@ def build_tagger(self): teen | addzero**2 + digits | addzero**3) # 一万 二万二 二万二千百 二万二千三百 一万二千百一 一万九千百二十三 一万九千二十三 九万九千二十 四万九千二 - ten_thousand = ((thousand | hundred | teen | tens | digits) + - delete("万") + - (thousand | addzero + hundred | addzero**2 + tens | - addzero**2 + teen | addzero**3 + digits | addzero**4)) - - hundred_thousand = (digits + delete("十万") + (ten_thousand - | addzero + thousand - | addzero**2 + hundred - | addzero**3 + tens - | addzero**3 + teen - | addzero**4 + digits - | addzero**5)) - - million = (digits + delete("百万") + (hundred_thousand - | addzero + ten_thousand - | addzero**2 + thousand - | addzero**3 + hundred - | addzero**4 + tens - | addzero**4 + teen - | addzero**5 + digits - | addzero**6)) - - ten_million = (digits + delete("千万") + (million - | addzero + hundred_thousand - | addzero**2 + ten_thousand - | addzero**3 + thousand - | addzero**4 + hundred - | addzero**5 + tens - | addzero**5 + teen - | addzero**6 + digits - | addzero**7)) + if self.enable_million: + ten_thousand = ( + (thousand | hundred | teen | tens | digits) + delete("万") + + (thousand | addzero + hundred | addzero**2 + tens + | addzero**2 + teen | addzero**3 + digits | addzero**4)) + else: + ten_thousand = ( + (teen | tens | digits) + delete("万") + + (thousand | addzero + hundred | addzero**2 + tens + | addzero**2 + teen | addzero**3 + digits | addzero**4)) + ten_thousand |= (thousand | hundred) + accep("万") + ( + thousand | hundred | tens | teen | digits).ques # 0~9999 ten_thousand_minus = digits | teen | tens | hundred | thousand self.ten_thousand_minus = ten_thousand_minus + # 0~99999999 - positive_integer = (digits | teen | tens | hundred | thousand - | ten_thousand | hundred_thousand | million - | ten_million) - self.positive_integer = positive_integer + positive_integer = ten_thousand_minus | ten_thousand - # ±0~9999 - number = (sign.ques + ten_thousand_minus).optimize() + # ±0~99999999 + number = (sign.ques + positive_integer).optimize() self.number = number + self.number_exclude_0_to_9 = teen | tens | hundred | thousand | ten_thousand # ±0.0~99999999.99... decimal = sign.ques + positive_integer + dot + digits.plus self.decimal = decimal + # % like -27.00% + percent = (number | decimal) + cross('パーセント', '%') - if self.enable_million: - # 三百二十万五千 => 3255000 - number = (sign.ques + positive_integer).optimize() - - # ±10000~∞ e.g. 一兆三百二十万五千 => 1兆320万5000 + # ±100,000,000~∞ e.g. 一兆三百二十万五千 => 1兆320万5000 big_integer = (sign.ques + ( (ten_thousand_minus + accep("兆")).ques + + (ten_thousand_minus + accep("億")) + + (ten_thousand_minus + accep("万").ques + ten_thousand_minus.ques) + | (ten_thousand_minus + accep("兆")) + (ten_thousand_minus + accep("億")).ques + - (ten_thousand_minus + accep("万")).ques + ten_thousand_minus - | (ten_thousand_minus + accep("兆")).ques + - (ten_thousand_minus + accep("億")).ques + - (ten_thousand_minus + accep("万")) - | (ten_thousand_minus + accep("兆")).ques + - (ten_thousand_minus + accep("億")) - | ten_thousand_minus + accep("兆") - | ten_thousand_minus)) - self.big_integer = big_integer + (ten_thousand_minus + accep("万").ques + ten_thousand_minus.ques))) number |= big_integer + self.big_integer = number # cardinal string like 127.0.0.1, used in ID, IP, etc. cardinal = digit.plus + (dot + digits.plus).plus @@ -153,19 +126,24 @@ def build_tagger(self): cardinal |= decimal # cardinal string like 110 or 12306 or 13125617878, used in phone cardinal |= digits**3 | digits**5 | digits**10 | digits**11 | digits**12 + # % like -27.00% + cardinal |= percent # allow convert standalone number if self.enable_standalone_number: if self.enable_0_to_9: - # 一 => 1 四 => 4 一秒 => 1秒 一万二 => 1万2 二三 => 23 + # 一 => 1 四 => 4 一秒 => 1秒 一万二 => 12000 二十三 => 23 cardinal |= number else: # 一 => 一 四 => 四 一秒 => 1秒 一万二 => 一万二 二三 => 23 - number_two_plus = ((digits + digits.plus) - | teen - | tens - | hundred - | thousand) + number_two_plus = sign.ques + ((digits + digits.plus) + | teen + | tens + | hundred + | thousand + | ten_thousand + | big_integer) + cardinal |= number_two_plus self.tagger = self.add_tokens( diff --git a/itn/japanese/rules/fraction.py b/itn/japanese/rules/fraction.py index 7c13178..ac571dd 100644 --- a/itn/japanese/rules/fraction.py +++ b/itn/japanese/rules/fraction.py @@ -28,7 +28,7 @@ def __init__(self): self.build_verbalizer() def build_tagger(self): - cardinal = Cardinal(enable_million=True).positive_integer + cardinal = Cardinal(enable_million=True).number decimal = Cardinal(enable_million=True).decimal sign = string_file( get_abs_path('../itn/japanese/data/number/sign.tsv')) @@ -38,15 +38,18 @@ def build_tagger(self): "分 の ") | delete("分 の") root_word = accep("√") | cross("ルート", "√") + # denominator denominator = ((decimal | (cardinal + root_word + cardinal) | (root_word + cardinal) | cardinal) + delete(' ').ques) denominator = insert('denominator: "') + denominator + insert('"') + # numerator numerator = (closure(delete(' ')) + (decimal | cardinal + root_word + cardinal | root_word + cardinal | cardinal)) numerator = insert('numerator: "') + numerator + insert('"') + # fraction fraction_sign = sign + insert(" ") + denominator + insert( " ") + fraction_word + numerator fraction_no_sign = denominator + insert( diff --git a/itn/japanese/rules/measure.py b/itn/japanese/rules/measure.py index 7ca637e..956cb1a 100644 --- a/itn/japanese/rules/measure.py +++ b/itn/japanese/rules/measure.py @@ -34,8 +34,9 @@ def build_tagger(self): unit_ja = string_file( get_abs_path('../itn/japanese/data/measure/unit_ja.tsv')) - cardinal = Cardinal(self.enable_0_to_9).positive_integer - decimal = Cardinal(self.enable_0_to_9).decimal + cardinal = Cardinal().number if self.enable_0_to_9 else \ + Cardinal().number_exclude_0_to_9 + decimal = Cardinal().decimal suffix = ( insert('/') + (delete('每') | delete('毎')) + diff --git a/itn/japanese/rules/money.py b/itn/japanese/rules/money.py new file mode 100644 index 0000000..163e9fa --- /dev/null +++ b/itn/japanese/rules/money.py @@ -0,0 +1,47 @@ +# Copyright (c) 2024 Logan Liu (2319277867@qq.com) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from itn.japanese.rules.cardinal import Cardinal +from tn.processor import Processor +from tn.utils import get_abs_path + +from pynini import string_file +from pynini.lib.pynutil import delete, insert + + +class Money(Processor): + + def __init__(self, enable_0_to_9=True): + super().__init__(name='money') + self.enable_0_to_9 = enable_0_to_9 + self.build_tagger() + self.build_verbalizer() + + def build_tagger(self): + symbol = string_file( + get_abs_path('../itn/japanese/data/money/symbol.tsv')) + + number = Cardinal().number if self.enable_0_to_9 else \ + Cardinal().number_exclude_0_to_9 + decimal = Cardinal().decimal + # 三千三百八十点五八円 => ¥3380.58 + tagger = (insert('value: "') + (number | decimal) + insert('"') + + insert(' currency: "') + symbol + insert('"')) + self.tagger = self.add_tokens(tagger) + + def build_verbalizer(self): + currency = delete('currency: "') + self.SIGMA + delete('"') + value = delete(' value: "') + self.SIGMA + delete('"') + verbalizer = currency + value + self.verbalizer = self.delete_tokens(verbalizer) diff --git a/itn/japanese/rules/ordinal.py b/itn/japanese/rules/ordinal.py index 61bd6fd..f720aea 100644 --- a/itn/japanese/rules/ordinal.py +++ b/itn/japanese/rules/ordinal.py @@ -27,7 +27,7 @@ def __init__(self): self.build_verbalizer() def build_tagger(self): - cardinal = Cardinal().positive_integer + cardinal = Cardinal().number ordinal = (cardinal + accep('番目')) | (accep('第') + cardinal) tagger = insert('value: "') + ordinal + insert('"') self.tagger = self.add_tokens(tagger) diff --git a/itn/japanese/test/data/cardinal.txt b/itn/japanese/test/data/cardinal.txt index e0b31f3..c3f692a 100644 --- a/itn/japanese/test/data/cardinal.txt +++ b/itn/japanese/test/data/cardinal.txt @@ -31,13 +31,14 @@ 千百十 => 1110 千百一 => 1101 マイナス百十二 => -112 -二十万二 => 20万2 -一万二 => 1万2 -二十万二千百 => 20万2100 +プラス百十二 => +112 +二十万二 => 200002 +一万二 => 10002 +二十万二千百 => 202100 四百万 => 400万 四百四万 => 404万 五千万 => 5000万 -二万 => 2万 +二万 => 20000 一億五千万 => 1億5000万 一億五万 => 1億5万 一億一百万 => 1億100万 @@ -50,7 +51,7 @@ 二兆二百万 => 2兆200万 一兆三百二十万五千 => 1兆320万5000 二兆三十 => 2兆30 -二兆一百 => 2兆100 -二十兆一百 => 20兆100 +二兆百 => 2兆100 +二十兆百 => 20兆100 一九二点一六八点零点一 => 192.168.0.1 一二三四五六七八九 => 123456789 \ No newline at end of file diff --git a/itn/japanese/test/data/date.txt b/itn/japanese/test/data/date.txt index 0cddc37..0a3dc46 100644 --- a/itn/japanese/test/data/date.txt +++ b/itn/japanese/test/data/date.txt @@ -1,8 +1,6 @@ 二千二十四年十月一日 => 2024年10月1日 二千二十四年十月 => 2024年10月 -一日 => 1日 五から九日 => 5~9日 -一月 => 1月 三から四月 => 3~4月 一月一日 => 1月1日 二十一世紀 => 21世紀 diff --git a/itn/japanese/test/data/fraction.txt b/itn/japanese/test/data/fraction.txt index 81890bf..2b4ac29 100644 --- a/itn/japanese/test/data/fraction.txt +++ b/itn/japanese/test/data/fraction.txt @@ -1,12 +1,8 @@ -一荷四分の三 => 1荷3/4 -一荷一分の一 => 1荷1/1 四分の三 => 3/4 -二と四分の三 => 2と3/4 +一分の一 => 1/1 二万分の三 => 3/20000 二万点三 => 20000.3 ルート三分の一 => 1/√3 一点六五分の五十 => 50/1.65 二ルート六分の三 => 3/2√6 -二万 => 2万 -三千 => 3000 三千分の三 => 3/3000 \ No newline at end of file diff --git a/itn/japanese/test/data/math.txt b/itn/japanese/test/data/math.txt index 19df416..268eca5 100644 --- a/itn/japanese/test/data/math.txt +++ b/itn/japanese/test/data/math.txt @@ -1,4 +1,4 @@ -四百四万マイナス二万 => 404万-2万 +四百四マイナス二 => 404-2 一マイナス二プラス三十 => 1-2+30 三対二 => 3:2 一プラス一イコール二 => 1+1=2 diff --git a/itn/japanese/test/data/measure.txt b/itn/japanese/test/data/measure.txt index cdfc1d3..f2fd9af 100644 --- a/itn/japanese/test/data/measure.txt +++ b/itn/japanese/test/data/measure.txt @@ -1,7 +1,6 @@ 二千センチメートル每秒 => 2000cm/s 二万センチメートル每秒 => 20000cm/s 二万二千センチメートル每秒 => 22000cm/s -八メガ秒 => 8ms 八百メガ秒 => 800ms 三点五千キロメートル => 3.5km 百人 => 100人 \ No newline at end of file diff --git a/itn/japanese/test/data/money.txt b/itn/japanese/test/data/money.txt new file mode 100644 index 0000000..b1d2547 --- /dev/null +++ b/itn/japanese/test/data/money.txt @@ -0,0 +1 @@ +三千三百八十点五八円 => ¥3380.58 \ No newline at end of file diff --git a/itn/japanese/test/data/normalizer.txt b/itn/japanese/test/data/normalizer.txt deleted file mode 100644 index 470f83d..0000000 --- a/itn/japanese/test/data/normalizer.txt +++ /dev/null @@ -1,127 +0,0 @@ -一 -四 -十 -十四 -四十四 -四十 -百一 -百十二 -四百四 -九千百二十三 -一千二百三十四 -五千六百七十八 -二千二十 -二千二 -二千十 -二千百 -九千 -九千二 -十 -百 -千 -万 -兆 -千百 -千三百 -千三百十 -千十 -千二十 -千二十一 -千一 -千百十 -千百一 -マイナス百十二 -二十万二 -一万二 -二十万二千百 -四百万 -四百四万 -五千万 -二万 -一億五千万 -一億五万 -一億一百万 -一億一千万 -二千億一千万 -二千億 -二兆二億 -二兆二千億 -二兆二千万 -二兆二百万 -一兆三百二十万五千人 -二兆三十 -二兆一百 -二十兆一百 -一九二点一六八点零点一 - -マイナス二万 -プラスマイナス四百四万 -プラスマイナス二 -プラスマイナス千百十 -プラス千百十 - -一二三 -一点五万 - -一日 -五から九日 -一月 -三から四月 -一月一日 -二十一世紀 -七十年代 -七十から八十年代 -二千九年 -二十三年二月二十五日土曜日 -二千二十四年十月一日 -七月五から九日月曜日から金曜日 -今年はR六 - -一荷四分の三 -一荷一分の一 -四分の三 -二と四分の三 -二万分の三 -ルート三分の一 -一点六五分の五十 -二ルート六分の三 - -四百四万マイナス二万 -一マイナス二プラス三十 -三対二 -一プラス一イコール二 -一カケル二マイナス三プラス四ワル五イコール二 -六から七 - -二千センチメートル每秒 -二万センチメートル每秒 -二万二千センチメートル每秒 -八メガ秒 -八百メガ秒 -三点五千キロメートル -百人 -百鸟 -百 千 万 - -第二十三 -二十三番目 - -一時三十分三秒 -五時二十分過ぎ -七分 -七秒 -七時 -八時半頃 -十時五分前 -正午一分前 -正午十分過ぎ - -MNO - -正午一分前,。! - -なんぼやと思う?一万円?なんでやねん。そんな高いわけないやん。2000円やで。ちょっと古いもんやけど、そら別にかまへんわ。ええもんだったら何でもええねん。え、それはちゃう? -焼鳥 -人名用漢字表は随時見直されており、文化的な要請や使用者の要望に応じて、新たに追加されることがあります。例えば、2004年に488字が追加され、2023年には再び改訂されて863字となりました。 -二人 -二十三人 \ No newline at end of file diff --git a/itn/japanese/test/data/normalizer_disable_standalone_number_disable_0_to_9.txt b/itn/japanese/test/data/normalizer_disable_standalone_number_disable_0_to_9.txt new file mode 100644 index 0000000..0cdbc91 --- /dev/null +++ b/itn/japanese/test/data/normalizer_disable_standalone_number_disable_0_to_9.txt @@ -0,0 +1,71 @@ +一 => 一 +四 => 四 +十 => 十 +十四 => 十四 +四十四 => 四十四 +四十 => 四十 +百一 => 百一 +百十二 => 百十二 +四百四 => 四百四 +九千百二十三 => 九千百二十三 +一千二百三十四 => 一千二百三十四 +五千六百七十八 => 五千六百七十八 +二千二十 => 二千二十 +二千二 => 二千二 +二千十 => 二千十 +二千百 => 二千百 +九千 => 九千 +九千二 => 九千二 +十 => 十 +百 => 百 +千 => 千 +万 => 万 +兆 => 兆 +千百 => 千百 +千三百 => 千三百 +千三百十 => 千三百十 +千十 => 千十 +千二十 => 千二十 +千二十一 => 千二十一 +千一 => 千一 +千百十 => 千百十 +千百一 => 千百一 +マイナス百十二 => マイナス百十二 +プラス百十二 => プラス百十二 +二十万二 => 二十万二 +一万二 => 一万二 +二十万二千百 => 二十万二千百 +四百万 => 四百万 +四百四万 => 四百四万 +五千万 => 五千万 +二万 => 二万 +一億五千万 => 一億五千万 +一億五万 => 一億五万 +一億一百万 => 一億一百万 +一億一千万 => 一億一千万 +二千億一千万 => 二千億一千万 +二千億 => 二千億 +二兆二億 => 二兆二億 +二兆二千億 => 二兆二千億 +二兆二千万 => 二兆二千万 +二兆二百万 => 二兆二百万 +一兆三百二十万五千 => 一兆三百二十万五千 +二兆三十 => 二兆三十 +二兆百 => 二兆百 +二十兆百 => 二十兆百 +一九二点一六八点零点一 => 192.168.0.1 +一二三四五六七八九 => 123456789 +四十四平方メートル => 44m² +四十四キログラム => 44kg +四部 => 四部 +四円 => 四円 +四十四部 => 44部 +四十四匹 => 44匹 +四分の三 => 3/4 +四十四分の三 => 3/44 +四十四パーセント => 44% +一時三十分三秒 => 1時30分3秒 +八メガ秒 => 八メガ秒 +一マイナス二プラス三十 => 1-2+30 +一月 => 一月 +一日 => 一日 \ No newline at end of file diff --git a/itn/japanese/test/data/normalizer_disable_standalone_number_enable_0_to_9.txt b/itn/japanese/test/data/normalizer_disable_standalone_number_enable_0_to_9.txt new file mode 100644 index 0000000..14b0dd6 --- /dev/null +++ b/itn/japanese/test/data/normalizer_disable_standalone_number_enable_0_to_9.txt @@ -0,0 +1,71 @@ +一 => 一 +四 => 四 +十 => 十 +十四 => 十四 +四十四 => 四十四 +四十 => 四十 +百一 => 百一 +百十二 => 百十二 +四百四 => 四百四 +九千百二十三 => 九千百二十三 +一千二百三十四 => 一千二百三十四 +五千六百七十八 => 五千六百七十八 +二千二十 => 二千二十 +二千二 => 二千二 +二千十 => 二千十 +二千百 => 二千百 +九千 => 九千 +九千二 => 九千二 +十 => 十 +百 => 百 +千 => 千 +万 => 万 +兆 => 兆 +千百 => 千百 +千三百 => 千三百 +千三百十 => 千三百十 +千十 => 千十 +千二十 => 千二十 +千二十一 => 千二十一 +千一 => 千一 +千百十 => 千百十 +千百一 => 千百一 +マイナス百十二 => マイナス百十二 +プラス百十二 => プラス百十二 +二十万二 => 二十万二 +一万二 => 一万二 +二十万二千百 => 二十万二千百 +四百万 => 四百万 +四百四万 => 四百四万 +五千万 => 五千万 +二万 => 二万 +一億五千万 => 一億五千万 +一億五万 => 一億五万 +一億一百万 => 一億一百万 +一億一千万 => 一億一千万 +二千億一千万 => 二千億一千万 +二千億 => 二千億 +二兆二億 => 二兆二億 +二兆二千億 => 二兆二千億 +二兆二千万 => 二兆二千万 +二兆二百万 => 二兆二百万 +一兆三百二十万五千 => 一兆三百二十万五千 +二兆三十 => 二兆三十 +二兆百 => 二兆百 +二十兆百 => 二十兆百 +一九二点一六八点零点一 => 192.168.0.1 +一二三四五六七八九 => 123456789 +四十四平方メートル => 44m² +四十四キログラム => 44kg +四部 => 4部 +四円 => ¥4 +四十四部 => 44部 +四十四匹 => 44匹 +四分の三 => 3/4 +四十四分の三 => 3/44 +四十四パーセント => 44% +一時三十分三秒 => 1時30分3秒 +八メガ秒 => 8ms +一マイナス二プラス三十 => 1-2+30 +一月 => 1月 +一日 => 1日 \ No newline at end of file diff --git a/itn/japanese/test/data/normalizer_enable_standalone_number_disable_0_to_9.txt b/itn/japanese/test/data/normalizer_enable_standalone_number_disable_0_to_9.txt new file mode 100644 index 0000000..fd36210 --- /dev/null +++ b/itn/japanese/test/data/normalizer_enable_standalone_number_disable_0_to_9.txt @@ -0,0 +1,69 @@ +一 => 一 +四 => 四 +十 => 10 +十四 => 14 +四十四 => 44 +四十 => 40 +百一 => 101 +百十二 => 112 +四百四 => 404 +九千百二十三 => 9123 +一千二百三十四 => 1234 +五千六百七十八 => 5678 +二千二十 => 2020 +二千二 => 2002 +二千十 => 2010 +二千百 => 2100 +九千 => 9000 +九千二 => 9002 +十 => 10 +百 => 100 +千 => 1000 +万 => 万 +兆 => 兆 +千百 => 1100 +千三百 => 1300 +千三百十 => 1310 +千十 => 1010 +千二十 => 1020 +千二十一 => 1021 +千一 => 1001 +千百十 => 1110 +千百一 => 1101 +マイナス百十二 => -112 +プラス百十二 => +112 +二十万二 => 200002 +一万二 => 10002 +二十万二千百 => 202100 +四百万 => 400万 +四百四万 => 404万 +五千万 => 5000万 +二万 => 20000 +一億五千万 => 1億5000万 +一億五万 => 1億5万 +一億一百万 => 1億100万 +一億一千万 => 1億1000万 +二千億一千万 => 2000億1000万 +二千億 => 2000億 +二兆二億 => 2兆2億 +二兆二千億 => 2兆2000億 +二兆二千万 => 2兆2000万 +二兆二百万 => 2兆200万 +一兆三百二十万五千 => 1兆320万5000 +二兆三十 => 2兆30 +二兆百 => 2兆100 +二十兆百 => 20兆100 +一九二点一六八点零点一 => 192.168.0.1 +一二三四五六七八九 => 123456789 +四十四平方メートル => 44m² +四十四キログラム => 44kg +四十四部 => 44部 +四十四匹 => 44匹 +四分の三 => 3/4 +四十四分の三 => 3/44 +四十四パーセント => 44% +一時三十分三秒 => 1時30分3秒 +八メガ秒 => 八メガ秒 +一マイナス二プラス三十 => 1-2+30 +一月 => 一月 +一日 => 一日 \ No newline at end of file diff --git a/itn/japanese/test/data/number.txt b/itn/japanese/test/data/number.txt index d08c0b8..efbc9af 100644 --- a/itn/japanese/test/data/number.txt +++ b/itn/japanese/test/data/number.txt @@ -1,6 +1,11 @@ 三点一四一五九二六 => 3.1415926 マイナス三点一四一五九二六 => -3.1415926 一百万千百十一 => 100万1111 -一万千百十一 => 1万1111 -一万二千三百 => 1万2300 -二万 => 2万 \ No newline at end of file +一万千百十一 => 11111 +一万二千三百 => 12300 +二万 => 20000 +三百万 => 300万 +三兆三万 => 3兆3万 +三千万 => 3000万 +一兆三百二十万五千 => 1兆320万5000 +三百二十万五千 => 320万5000 \ No newline at end of file diff --git a/itn/japanese/test/normalizer_test.py b/itn/japanese/test/normalizer_test.py index 75e4d57..7e8b9ad 100644 --- a/itn/japanese/test/normalizer_test.py +++ b/itn/japanese/test/normalizer_test.py @@ -33,6 +33,7 @@ class TestNormalizer: parse_test_case('data/fraction.txt'), parse_test_case('data/math.txt'), parse_test_case('data/measure.txt'), + parse_test_case('data/money.txt'), parse_test_case('data/number.txt'), parse_test_case('data/time.txt'), parse_test_case('data/whitelist.txt')) @@ -40,3 +41,66 @@ class TestNormalizer: @pytest.mark.parametrize("spoken, written", normalizer_cases) def test_normalizer(self, spoken, written): assert self.normalizer.normalize(spoken) == written + + +class TestNormalizerDisablestandalonenumberEnable0to9: + + normalizer = InverseNormalizer(overwrite_cache=True, + enable_standalone_number=False, + enable_0_to_9=True, + enable_million=False) + + normalizer_cases = chain( + parse_test_case('data/char.txt'), parse_test_case('data/date.txt'), + parse_test_case('data/fraction.txt'), parse_test_case('data/math.txt'), + parse_test_case('data/measure.txt'), parse_test_case('data/money.txt'), + parse_test_case('data/time.txt'), + parse_test_case('data/whitelist.txt'), + parse_test_case( + 'data/normalizer_disable_standalone_number_enable_0_to_9.txt')) + + @pytest.mark.parametrize("spoken, written", normalizer_cases) + def test_normalizer(self, spoken, written): + assert self.normalizer.normalize(spoken) == written + + +class TestNormalizerEnablestandalonenumberDisable0to9: + + normalizer = InverseNormalizer(overwrite_cache=True, + enable_standalone_number=True, + enable_0_to_9=False, + enable_million=False) + + normalizer_cases = chain( + parse_test_case('data/char.txt'), parse_test_case('data/date.txt'), + parse_test_case('data/fraction.txt'), parse_test_case('data/math.txt'), + parse_test_case('data/measure.txt'), parse_test_case('data/money.txt'), + parse_test_case('data/time.txt'), + parse_test_case('data/whitelist.txt'), + parse_test_case( + 'data/normalizer_enable_standalone_number_disable_0_to_9.txt')) + + @pytest.mark.parametrize("spoken, written", normalizer_cases) + def test_normalizer(self, spoken, written): + assert self.normalizer.normalize(spoken) == written + + +class TestNormalizerDisablestandalonenumberDisable0to9: + + normalizer = InverseNormalizer(overwrite_cache=True, + enable_standalone_number=False, + enable_0_to_9=False, + enable_million=False) + + normalizer_cases = chain( + parse_test_case('data/char.txt'), parse_test_case('data/date.txt'), + parse_test_case('data/fraction.txt'), parse_test_case('data/math.txt'), + parse_test_case('data/measure.txt'), parse_test_case('data/money.txt'), + parse_test_case('data/time.txt'), + parse_test_case('data/whitelist.txt'), + parse_test_case( + 'data/normalizer_disable_standalone_number_disable_0_to_9.txt')) + + @pytest.mark.parametrize("spoken, written", normalizer_cases) + def test_normalizer(self, spoken, written): + assert self.normalizer.normalize(spoken) == written From 646fca96ec3a7893cd0d9e47785ed6de9a4f9c38 Mon Sep 17 00:00:00 2001 From: LoganLiu66 <2319277867@qq.com> Date: Mon, 28 Oct 2024 11:16:36 +0800 Subject: [PATCH 5/9] [tn] format code for Japanese TN --- tn/japanese/rules/cardinal.py | 6 +++--- tn/japanese/rules/date.py | 21 --------------------- tn/japanese/rules/sport.py | 6 +++--- tn/japanese/rules/time.py | 10 ++++++---- 4 files changed, 12 insertions(+), 31 deletions(-) diff --git a/tn/japanese/rules/cardinal.py b/tn/japanese/rules/cardinal.py index d2e7898..2ba2103 100644 --- a/tn/japanese/rules/cardinal.py +++ b/tn/japanese/rules/cardinal.py @@ -51,7 +51,7 @@ def build_tagger(self): # 100-999 hundred = (teen + insert('百') + (ten | (rmzero + digit) | rmzero**2)) - # hundred prefix like "1,11" in "1,115,000" + # hundred prefix containing "," like "1,11" in "1,115,000" hundred_prefix = (teen + insert('百') + rmpunct + (ten | (rmzero + digit) | rmzero**2)) @@ -60,7 +60,7 @@ def build_tagger(self): | (rmzero + ten) | (rmzero**2 + digit) | rmzero**3)) - # thousand prefix like "10,00" in "10,000,000" + # thousand prefix containing "," like "10,00" in "10,000,000" thousand_prefix = (digit + insert('千') + (hundred_prefix | (rmzero + rmpunct + ten) @@ -68,7 +68,7 @@ def build_tagger(self): | rmzero + rmpunct + rmzero**2)) self.thousand = thousand - # 10000-99999999 1,115,000 10,000,000 + # 10000-99999999 e.g. 1,115,000 10,000,000 ten_thousand = ((thousand_prefix | hundred_prefix | ten | digit) + insert('万') + (thousand diff --git a/tn/japanese/rules/date.py b/tn/japanese/rules/date.py index ae8fb08..a520299 100644 --- a/tn/japanese/rules/date.py +++ b/tn/japanese/rules/date.py @@ -21,27 +21,6 @@ class Date(Processor): - """ - 1日 -> 一日 - 5~9日 -> 五から九日 - 1月 -> 一月 - 3~4月 -> 三から四月 - 1月1日 -> 一月一日 - 70年代 -> 七十年代 - 70~80年代 -> 七十から八十年代 - 21世紀 -> 二十一世紀 - 2009年 -> 二千九年 - 23年2月25日(土) -> 二十三年二月二十五日土曜日 - 7月5〜9日(月〜金) -> 七月五から九日月曜日から金曜日 - 今年は令和6 -> 今年はR六 - 2019年3月2日 -> 二千十九年三月二日 - 1986年8月18日 -> 千九百八十六年八月十八日 - ---以上都可以把日期做为普通数字进行转换,以下要添加对应规则--- - 2008/08/08 -> 二千八年八月八日 - 1008/08/10 -> 千八年八月十日 - 1108/08/10 -> 千百八年八月十日 - 1000.08.10 -> 千年八月十日 - """ def __init__(self): super().__init__(name='date') diff --git a/tn/japanese/rules/sport.py b/tn/japanese/rules/sport.py index 3a019c0..4595f90 100644 --- a/tn/japanese/rules/sport.py +++ b/tn/japanese/rules/sport.py @@ -36,9 +36,9 @@ def build_tagger(self): number = Cardinal().positive_integer score = rmspace + number + rmsign + insert('対') + number + rmspace only_score = rmspace + number + cross(':', '対') + number + rmspace - tagger = (insert('team: "') + (country | club) + insert('" score: "') + - score + insert('"')) | (insert('score: "') + only_score + - insert('"')) + tagger = ((insert('team: "') + (country | club) + + insert('" score: "') + score + insert('"')) + | (insert('score: "') + only_score + insert('"'))) self.tagger = self.add_tokens(tagger) def build_verbalizer(self): diff --git a/tn/japanese/rules/time.py b/tn/japanese/rules/time.py index 75b4050..f8166c8 100644 --- a/tn/japanese/rules/time.py +++ b/tn/japanese/rules/time.py @@ -31,13 +31,15 @@ def build_tagger(self): m = string_file(get_abs_path('japanese/data/time/minute.tsv')) s = string_file(get_abs_path('japanese/data/time/second.tsv')) noon = string_file(get_abs_path('japanese/data/time/noon.tsv')) + colon = delete(':') | delete(':') + h = insert('hour: "') + h + insert('" ') + m = insert('minute: "') + m + insert('"') + s = insert(' second: "') + s + insert('"') + noon = insert(' noon: "') + noon + insert('"') tagger = ( - (insert('hour: "') + h + insert('" ') + colon + - insert('minute: "') + m + insert('"') + - (colon + insert(' second: "') + s + insert('"')).ques + - delete(' ').ques + (insert(' noon: "') + noon + insert('"')).ques) + (h + colon + m + (colon + s).ques + delete(' ').ques + noon.ques) | (insert('hour: "') + h + insert('" noon: "') + noon + insert('"'))) tagger = self.add_tokens(tagger) From c1264f3be02950fe15295709e964bb680698ce89 Mon Sep 17 00:00:00 2001 From: LoganLiu66 <2319277867@qq.com> Date: Mon, 28 Oct 2024 11:17:40 +0800 Subject: [PATCH 6/9] [itn] format code for Japanese ITN --- itn/japanese/rules/cardinal.py | 58 ++++++++++++++++++----------- itn/japanese/rules/date.py | 12 +++--- itn/japanese/rules/fraction.py | 23 +++++++----- itn/japanese/rules/measure.py | 8 ++-- itn/japanese/rules/postprocessor.py | 3 +- itn/japanese/rules/time.py | 14 +++---- 6 files changed, 70 insertions(+), 48 deletions(-) diff --git a/itn/japanese/rules/cardinal.py b/itn/japanese/rules/cardinal.py index b55040f..71f980f 100644 --- a/itn/japanese/rules/cardinal.py +++ b/itn/japanese/rules/cardinal.py @@ -64,32 +64,46 @@ def build_tagger(self): hundred = (digit + delete("百") + (tens | teen | addzero**1 + digits | addzero**2)) # 百 百十 百二十三 - hundred |= cross("百", - "1") + (tens | teen | addzero + digits | addzero**2) + hundred |= (cross("百", "1") + + (tens | teen | addzero + digits | addzero**2)) # 百一 百二 hundred |= hundred_digit # 二千百 二千三百 二千百一 九千百二十三 九千二十三 九千二十 九千二 thousand = ((hundred | teen | tens | digits) + delete("千") + - (hundred | addzero + tens | addzero + teen - | addzero**2 + digits | addzero**3)) + (hundred + | addzero + tens + | addzero + teen + | addzero**2 + digits + | addzero**3)) # 千百 千三百 千百一 千百二十三 千二十三 千二十 千二 - thousand |= cross('千', '1') + (hundred | addzero + tens | addzero + - teen | addzero**2 + digits | addzero**3) + thousand |= (cross('千', '1') + (hundred + | addzero + tens + | addzero + teen + | addzero**2 + digits + | addzero**3)) # 一万 二万二 二万二千百 二万二千三百 一万二千百一 一万九千百二十三 一万九千二十三 九万九千二十 四万九千二 if self.enable_million: - ten_thousand = ( - (thousand | hundred | teen | tens | digits) + delete("万") + - (thousand | addzero + hundred | addzero**2 + tens - | addzero**2 + teen | addzero**3 + digits | addzero**4)) + ten_thousand = ((thousand | hundred | teen | tens | digits) + + delete("万") + (thousand + | addzero + hundred + | addzero**2 + tens + | addzero**2 + teen + | addzero**3 + digits + | addzero**4)) else: - ten_thousand = ( - (teen | tens | digits) + delete("万") + - (thousand | addzero + hundred | addzero**2 + tens - | addzero**2 + teen | addzero**3 + digits | addzero**4)) - ten_thousand |= (thousand | hundred) + accep("万") + ( - thousand | hundred | tens | teen | digits).ques + # 二万 十万 三十四万 + ten_thousand = ((teen | tens | digits) + delete("万") + + (thousand + | addzero + hundred + | addzero**2 + tens + | addzero**2 + teen + | addzero**3 + digits + | addzero**4)) + # 三百四十万 三千四百万 + ten_thousand |= ((thousand | hundred) + accep("万") + + (thousand | hundred | tens | teen | digits).ques) # 0~9999 ten_thousand_minus = digits | teen | tens | hundred | thousand @@ -111,12 +125,12 @@ def build_tagger(self): # ±100,000,000~∞ e.g. 一兆三百二十万五千 => 1兆320万5000 big_integer = (sign.ques + ( - (ten_thousand_minus + accep("兆")).ques + - (ten_thousand_minus + accep("億")) + - (ten_thousand_minus + accep("万").ques + ten_thousand_minus.ques) - | (ten_thousand_minus + accep("兆")) + - (ten_thousand_minus + accep("億")).ques + - (ten_thousand_minus + accep("万").ques + ten_thousand_minus.ques))) + ((ten_thousand_minus + accep("兆")).ques + ten_thousand_minus + + accep("億") + ten_thousand_minus + accep("万").ques + + ten_thousand_minus.ques) + | (ten_thousand_minus + accep("兆") + + (ten_thousand_minus + accep("億")).ques + ten_thousand_minus + + accep("万").ques + ten_thousand_minus.ques))) number |= big_integer self.big_integer = number diff --git a/itn/japanese/rules/date.py b/itn/japanese/rules/date.py index b03794a..85d23b8 100644 --- a/itn/japanese/rules/date.py +++ b/itn/japanese/rules/date.py @@ -35,12 +35,12 @@ def build_tagger(self): to = cross('から', '〜') # 一月 一日 一年 - year = insert('year: "') + cardinal + ( - to + cardinal).ques + delete('年') + insert('"') - month = insert('month: "') + month + ( - to + month).ques + delete('月') + insert('"') - day = insert('day: "') + day + (to + - day).ques + delete('日') + insert('"') + year = (insert('year: "') + cardinal + (to + cardinal).ques + + delete('年') + insert('"')) + month = (insert('month: "') + month + (to + month).ques + delete('月') + + insert('"')) + day = (insert('day: "') + day + (to + day).ques + delete('日') + + insert('"')) # 二千二十四年十月一日 二千二十四年十月 十月一日 graph_date = (year + insert(" ") + month diff --git a/itn/japanese/rules/fraction.py b/itn/japanese/rules/fraction.py index ac571dd..80ac081 100644 --- a/itn/japanese/rules/fraction.py +++ b/itn/japanese/rules/fraction.py @@ -34,24 +34,29 @@ def build_tagger(self): get_abs_path('../itn/japanese/data/number/sign.tsv')) sign = insert('sign: "') + sign + insert('"') - fraction_word = delete("分の") | delete(" 分 の ") | delete( - "分 の ") | delete("分 の") + fraction_word = (delete("分の") + | delete(" 分 の ") + | delete("分 の ") + | delete("分 の")) root_word = accep("√") | cross("ルート", "√") # denominator - denominator = ((decimal | (cardinal + root_word + cardinal) | - (root_word + cardinal) | cardinal) + delete(' ').ques) + denominator = ((decimal + | (cardinal + root_word + cardinal) + | (root_word + cardinal) + | cardinal) + delete(' ').ques) denominator = insert('denominator: "') + denominator + insert('"') # numerator - numerator = (closure(delete(' ')) + - (decimal | cardinal + root_word + cardinal - | root_word + cardinal | cardinal)) + numerator = (closure(delete(' ')) + (decimal + | cardinal + root_word + cardinal + | root_word + cardinal + | cardinal)) numerator = insert('numerator: "') + numerator + insert('"') # fraction - fraction_sign = sign + insert(" ") + denominator + insert( - " ") + fraction_word + numerator + fraction_sign = (sign + insert(" ") + denominator + insert(" ") + + fraction_word + numerator) fraction_no_sign = denominator + insert( " ") + fraction_word + numerator regular_fractions = fraction_sign | fraction_no_sign diff --git a/itn/japanese/rules/measure.py b/itn/japanese/rules/measure.py index 956cb1a..b058270 100644 --- a/itn/japanese/rules/measure.py +++ b/itn/japanese/rules/measure.py @@ -38,9 +38,11 @@ def build_tagger(self): Cardinal().number_exclude_0_to_9 decimal = Cardinal().decimal - suffix = ( - insert('/') + (delete('每') | delete('毎')) + - (unit_en | cross('時', 'h') | cross('分', 'min') | cross('秒', 's'))) + suffix = (insert('/') + (delete('每') | delete('毎')) + + (unit_en + | cross('時', 'h') + | cross('分', 'min') + | cross('秒', 's'))) measure = ((cardinal | decimal) + unit_en + suffix.ques | (cardinal | decimal) + unit_ja) diff --git a/itn/japanese/rules/postprocessor.py b/itn/japanese/rules/postprocessor.py index 04cd078..4365d8a 100644 --- a/itn/japanese/rules/postprocessor.py +++ b/itn/japanese/rules/postprocessor.py @@ -47,7 +47,8 @@ def __init__(self, processor @= self.build_rule(delete(puncts | self.PUNCT)) if tag_oov: - charset = (ja_charset_std | ja_charset_ext | puncts | self.DIGIT + charset = (ja_charset_std + | ja_charset_ext | puncts | self.DIGIT | self.ALPHA | self.PUNCT | self.SPACE) oov = difference(self.VCHAR, charset) processor @= Tagger('oov', oov, self.VSIGMA)._tagger diff --git a/itn/japanese/rules/time.py b/itn/japanese/rules/time.py index 5b94bcb..d704deb 100644 --- a/itn/japanese/rules/time.py +++ b/itn/japanese/rules/time.py @@ -32,20 +32,20 @@ def build_tagger(self): s = string_file(get_abs_path('../itn/japanese/data/time/second.tsv')) # 一時三十分三秒 一時三十分 三十分三秒 一時 三十分 三秒 - tagger = ((insert('hour: "') + h + insert('" ')).ques + - (insert('minute: "') + m + insert('"')) + - (insert(' second: "') + s + insert('"')).ques + tagger = (((insert('hour: "') + h + insert('" ')).ques + + (insert('minute: "') + m + insert('"')) + + (insert(' second: "') + s + insert('"')).ques) | insert('hour: "') + h + insert('" ') | insert(' second: "') + s + insert('"')) tagger = self.add_tokens(tagger) self.tagger = tagger def build_verbalizer(self): - hour = delete('hour: "') + self.SIGMA + delete('"') + delete( - ' ').ques + insert('時') + hour = (delete('hour: "') + self.SIGMA + delete('"') + + delete(' ').ques + insert('時')) minute = delete('minute: "') + self.SIGMA + delete('"') + insert('分') - second = delete(' ').ques + delete('second: "') + self.SIGMA + delete( - '"') + insert('秒') + second = (delete(' ').ques + delete('second: "') + self.SIGMA + + delete('"') + insert('秒')) verbalizer = hour.ques + minute + second.ques | second | hour self.verbalizer = self.delete_tokens(verbalizer) From db99bddf20e098a9b10e25f8fc4943701fb0822a Mon Sep 17 00:00:00 2001 From: LoganLiu66 <2319277867@qq.com> Date: Mon, 28 Oct 2024 20:29:25 +0800 Subject: [PATCH 7/9] [itn] fix Japanese ITN --- itn/chinese/test/data/money.txt | 1 - itn/japanese/data/default/whitelist.tsv | 22 ++++++++++++++++- itn/japanese/data/math/operator.tsv | 1 + itn/japanese/data/measure/unit_en.tsv | 24 +++++++++++++++---- itn/japanese/data/measure/unit_ja.tsv | 1 + itn/japanese/data/money/symbol.tsv | 2 -- itn/japanese/rules/cardinal.py | 7 +++--- itn/japanese/test/data/money.txt | 2 +- ...sable_standalone_number_disable_0_to_9.txt | 1 + ...isable_standalone_number_enable_0_to_9.txt | 3 ++- ...nable_standalone_number_disable_0_to_9.txt | 1 + 11 files changed, 51 insertions(+), 14 deletions(-) diff --git a/itn/chinese/test/data/money.txt b/itn/chinese/test/data/money.txt index c9e4cc5..2edefba 100644 --- a/itn/chinese/test/data/money.txt +++ b/itn/chinese/test/data/money.txt @@ -7,5 +7,4 @@ 四十五六新台币 => TWD45-6 七百三四十欧元 => €730-40 七百三四十马来西亚令吉 => RM730-40 -三千三百八十元五角八分 => ¥3380.58 二十五元三毛 => ¥25.3 diff --git a/itn/japanese/data/default/whitelist.tsv b/itn/japanese/data/default/whitelist.tsv index 91d7bf0..a1268bd 100644 --- a/itn/japanese/data/default/whitelist.tsv +++ b/itn/japanese/data/default/whitelist.tsv @@ -1,3 +1,23 @@ 十三湖 一月三舟 -一日之長 \ No newline at end of file +一日之長 +十八番 +百人一首 +二百十日 +三度笠 +千円札 +二十面相 +七つの海 +四国八十八箇所 +五箇山 +千本鳥居 +五月雨 +六本木ヒルズ +七つの大罪 +千本格子 +二枚目俳優 +六本木アートナイト +七人の侍 +五月祭 +七人の姉妹 +十八番目の男 \ No newline at end of file diff --git a/itn/japanese/data/math/operator.tsv b/itn/japanese/data/math/operator.tsv index 0534dad..00e7f68 100644 --- a/itn/japanese/data/math/operator.tsv +++ b/itn/japanese/data/math/operator.tsv @@ -1,4 +1,5 @@ カケル × +負 - マイナス - プラス + イコール = diff --git a/itn/japanese/data/measure/unit_en.tsv b/itn/japanese/data/measure/unit_en.tsv index c30c655..4de2ba3 100644 --- a/itn/japanese/data/measure/unit_en.tsv +++ b/itn/japanese/data/measure/unit_en.tsv @@ -3,6 +3,24 @@ キロメートル km 千キロメートル km メートル m +センチ cm +インチ インチ +リットル L +ジュール J +ワット W +アンペア A +ボルト V +オーム Ω +アンペア毎メートル A/m +ビット bit +バイト Byte +メガバイト MB +キロバイト KB +ギガバイト GB +度 ℃ +立方センチメートル cm³ +ドット dpi +ケルビン K センチメートル cm ミリメートル mm ヘクタール ha @@ -33,14 +51,12 @@ ミリボルト mv メガワット mw マイクロメータ μm -インチ " -テラバイト tb -c c cc +テラバイト TB グラム g ダルトン da 雰囲気 atm オーム ω -デシベル db +デシベル dB ペタ秒 ps オンス oz ヘクトリットル hl diff --git a/itn/japanese/data/measure/unit_ja.tsv b/itn/japanese/data/measure/unit_ja.tsv index c214b70..5d9dd78 100644 --- a/itn/japanese/data/measure/unit_ja.tsv +++ b/itn/japanese/data/measure/unit_ja.tsv @@ -8,6 +8,7 @@ 階 個 箇 +円 个 ヶ 面 diff --git a/itn/japanese/data/money/symbol.tsv b/itn/japanese/data/money/symbol.tsv index dc37df0..6755815 100644 --- a/itn/japanese/data/money/symbol.tsv +++ b/itn/japanese/data/money/symbol.tsv @@ -1,8 +1,6 @@ ドル $ ポンド £ ポンド £ -円 ¥ -円 ¥ バーツ ฿ ユーロ € インドルピー ₹ diff --git a/itn/japanese/rules/cardinal.py b/itn/japanese/rules/cardinal.py index 71f980f..386feb6 100644 --- a/itn/japanese/rules/cardinal.py +++ b/itn/japanese/rules/cardinal.py @@ -131,15 +131,14 @@ def build_tagger(self): | (ten_thousand_minus + accep("兆") + (ten_thousand_minus + accep("億")).ques + ten_thousand_minus + accep("万").ques + ten_thousand_minus.ques))) - number |= big_integer - self.big_integer = number + self.big_integer = number | big_integer # cardinal string like 127.0.0.1, used in ID, IP, etc. cardinal = digit.plus + (dot + digits.plus).plus # float number like 1.11 cardinal |= decimal # cardinal string like 110 or 12306 or 13125617878, used in phone - cardinal |= digits**3 | digits**5 | digits**10 | digits**11 | digits**12 + cardinal |= (digits**2 + digits.plus) # % like -27.00% cardinal |= percent @@ -147,7 +146,7 @@ def build_tagger(self): if self.enable_standalone_number: if self.enable_0_to_9: # 一 => 1 四 => 4 一秒 => 1秒 一万二 => 12000 二十三 => 23 - cardinal |= number + cardinal |= number | big_integer else: # 一 => 一 四 => 四 一秒 => 1秒 一万二 => 一万二 二三 => 23 number_two_plus = sign.ques + ((digits + digits.plus) diff --git a/itn/japanese/test/data/money.txt b/itn/japanese/test/data/money.txt index b1d2547..351f757 100644 --- a/itn/japanese/test/data/money.txt +++ b/itn/japanese/test/data/money.txt @@ -1 +1 @@ -三千三百八十点五八円 => ¥3380.58 \ No newline at end of file +三千三百八十点五八ドル => $3380.58 \ No newline at end of file diff --git a/itn/japanese/test/data/normalizer_disable_standalone_number_disable_0_to_9.txt b/itn/japanese/test/data/normalizer_disable_standalone_number_disable_0_to_9.txt index 0cdbc91..ad09f71 100644 --- a/itn/japanese/test/data/normalizer_disable_standalone_number_disable_0_to_9.txt +++ b/itn/japanese/test/data/normalizer_disable_standalone_number_disable_0_to_9.txt @@ -55,6 +55,7 @@ 二十兆百 => 二十兆百 一九二点一六八点零点一 => 192.168.0.1 一二三四五六七八九 => 123456789 +マイナス五百六十七 => マイナス五百六十七 四十四平方メートル => 44m² 四十四キログラム => 44kg 四部 => 四部 diff --git a/itn/japanese/test/data/normalizer_disable_standalone_number_enable_0_to_9.txt b/itn/japanese/test/data/normalizer_disable_standalone_number_enable_0_to_9.txt index 14b0dd6..f079f06 100644 --- a/itn/japanese/test/data/normalizer_disable_standalone_number_enable_0_to_9.txt +++ b/itn/japanese/test/data/normalizer_disable_standalone_number_enable_0_to_9.txt @@ -55,10 +55,11 @@ 二十兆百 => 二十兆百 一九二点一六八点零点一 => 192.168.0.1 一二三四五六七八九 => 123456789 +マイナス五百六十七 => マイナス五百六十七 四十四平方メートル => 44m² 四十四キログラム => 44kg 四部 => 4部 -四円 => ¥4 +四円 => 4円 四十四部 => 44部 四十四匹 => 44匹 四分の三 => 3/4 diff --git a/itn/japanese/test/data/normalizer_enable_standalone_number_disable_0_to_9.txt b/itn/japanese/test/data/normalizer_enable_standalone_number_disable_0_to_9.txt index fd36210..8ea3092 100644 --- a/itn/japanese/test/data/normalizer_enable_standalone_number_disable_0_to_9.txt +++ b/itn/japanese/test/data/normalizer_enable_standalone_number_disable_0_to_9.txt @@ -55,6 +55,7 @@ 二十兆百 => 20兆100 一九二点一六八点零点一 => 192.168.0.1 一二三四五六七八九 => 123456789 +マイナス五百六十七 => -567 四十四平方メートル => 44m² 四十四キログラム => 44kg 四十四部 => 44部 From 72022cee32325fe9de7ba9a3c148fc2060cdb64b Mon Sep 17 00:00:00 2001 From: LoganLiu66 <2319277867@qq.com> Date: Tue, 29 Oct 2024 09:56:14 +0800 Subject: [PATCH 8/9] [tn] fix Japanese TN --- tn/japanese/rules/time.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tn/japanese/rules/time.py b/tn/japanese/rules/time.py index f8166c8..ed277fa 100644 --- a/tn/japanese/rules/time.py +++ b/tn/japanese/rules/time.py @@ -33,15 +33,16 @@ def build_tagger(self): noon = string_file(get_abs_path('japanese/data/time/noon.tsv')) colon = delete(':') | delete(':') + h_noon = (insert('hour: "') + h + insert('" noon: "') + noon + + insert('"')) h = insert('hour: "') + h + insert('" ') m = insert('minute: "') + m + insert('"') s = insert(' second: "') + s + insert('"') noon = insert(' noon: "') + noon + insert('"') - tagger = ( - (h + colon + m + (colon + s).ques + delete(' ').ques + noon.ques) - | - (insert('hour: "') + h + insert('" noon: "') + noon + insert('"'))) + tagger = ((h + colon + m + + (colon + s).ques + delete(' ').ques + noon.ques) + | h_noon) tagger = self.add_tokens(tagger) to = (delete('-') | delete('~')) + insert(' char { value: "から" } ') From 300f717fce849c2871ab7e27fe438214685237a0 Mon Sep 17 00:00:00 2001 From: LoganLiu66 <2319277867@qq.com> Date: Sun, 10 Nov 2024 10:35:30 +0800 Subject: [PATCH 9/9] [itn] fix Japanese ITN --- itn/chinese/test/data/money.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/itn/chinese/test/data/money.txt b/itn/chinese/test/data/money.txt index 2edefba..c9e4cc5 100644 --- a/itn/chinese/test/data/money.txt +++ b/itn/chinese/test/data/money.txt @@ -7,4 +7,5 @@ 四十五六新台币 => TWD45-6 七百三四十欧元 => €730-40 七百三四十马来西亚令吉 => RM730-40 +三千三百八十元五角八分 => ¥3380.58 二十五元三毛 => ¥25.3