sudachipyを使って文章をひらがなに変換する

初めに

TTSの学習のひとつで、文字列をすべてひらがなにしたい場合があります。その際に簡単に使える sudachiを使って処理をしてみます

以下にサンプルリポジトリを公開しています

github.com

開発環境

セットアップ

uv pip install sudachipy sudachidict-core

ひらながに変換

今回は、つくよみちゃんコーパス│声優統計コーパス(JVSコーパス準拠)の内容で実行をしてみます

sudachiを使ったファイル読み込みおよび変換コードは以下です

from sudachipy import dictionary, tokenizer

def katakana_to_hiragana(text):
    """カタカナをひらがなに変換する関数"""
    hiragana = ''
    for char in text:
        code = ord(char)
        # カタカナの範囲内の文字をひらがなに変換
        if 0x30A1 <= code <= 0x30FA:
            hiragana += chr(code - 0x60)
        else:
            hiragana += char
    return hiragana

# Sudachiの辞書をロード
tokenizer_obj = dictionary.Dictionary().create()
mode = tokenizer.Tokenizer.SplitMode.C  # 分割モードを指定

# 結果を保存するファイルを開く
with open('sudachi-result.txt', 'w', encoding='utf-8') as f_output:
    # sample.txtを読み込んで処理
    with open('sample.txt', 'r', encoding='utf-8') as f_input:
        for line in f_input:
            line = line.strip()
            if not line:
                continue
            if ':' in line:
                identifier, script = line.split(':', 1)
                readings = []
                for token in tokenizer_obj.tokenize(script, mode):
                    yomi = token.reading_form()
                    readings.append(yomi)
                katakana_text = ''.join(readings)
                hiragana_text = katakana_to_hiragana(katakana_text)
                output_line = f"{identifier}:{hiragana_text}\n"
                f_output.write(output_line)
            else:
                f_output.write(line + '\n')

以下のようなフォーマットの sample.txt がルートパスにあることを想定しています

VOICEACTRESS100_001:また、東寺のように、五大明王と呼ばれる、主要な明王の中央に配されることも多い。
VOICEACTRESS100_002:ニューイングランド風は、牛乳をベースとした、白いクリームスープであり、ボストンクラムチャウダーとも呼ばれる。
VOICEACTRESS100_003:コンピュータゲームのメーカーや、業界団体などに関連する人物のカテゴリ。

こちらを処理をすることで以下のような結果になります

VOICEACTRESS100_001:また、とうじのように、ごだいみょうおうとよばれる、しゅようなみょうおうのちゅうおうにはいされることもおおい。
VOICEACTRESS100_002:にゅーいんぐらんどふうは、ぎゅうにゅうをべーすとした、しろいくりーむすーぷであり、ぼすとんくらむちゃうだーともよばれる。
VOICEACTRESS100_003:こんぴゅーたげーむのめーかーや、ぎょうかいだんたいなどにかんれんするじんぶつのかてごり。

辞書の変更

sudachiの辞書は3つあります。

  • core
  • small
  • full

今回は 一番語彙が多い full を使ってみます

まずはインストールをします

uv pip install sudachidict_full

モードを指定する際に辞書を指定します

# Sudachiの辞書をロードし、full辞書を使用するように指定
tokenizer_obj = dictionary.Dictionary(dict="full").create()
mode = tokenizer.Tokenizer.SplitMode.C  # 分割モードを指定

github.com

ここで corefull での精度の比較を行います。今回は、以下のようなdiffコードを作って実行しました。

import difflib

def compare_results(core_file, full_file, diff_output_file):
    # ファイルを読み込みます
    with open(core_file, 'r', encoding='utf-8') as f_core:
        core_lines = f_core.readlines()
    with open(full_file, 'r', encoding='utf-8') as f_full:
        full_lines = f_full.readlines()
    
    # 結果を保存するファイルを開く
    with open(diff_output_file, 'w', encoding='utf-8') as f_output:
        # 行数のチェック
        max_lines = max(len(core_lines), len(full_lines))
        
        for i in range(max_lines):
            core_line = core_lines[i].strip() if i < len(core_lines) else ''
            full_line = full_lines[i].strip() if i < len(full_lines) else ''
            
            # 識別子と台本部分を分離
            core_identifier, core_script = (core_line.split(':', 1) + [''])[:2]
            full_identifier, full_script = (full_line.split(':', 1) + [''])[:2]
            
            # 台本部分を比較
            if core_script != full_script:
                f_output.write(f"--- 差分が見つかりました(行 {i+1}) ---\n")
                f_output.write(f"識別子: {core_identifier}\n")
                f_output.write(f"【Core辞書の結果】\n")
                f_output.write(core_script + '\n')
                f_output.write(f"【Full辞書の結果】\n")
                f_output.write(full_script + '\n')
                f_output.write(f"【差分】\n")
                # 差分を表示(文字単位での比較)
                diff = difflib.ndiff(core_script, full_script)
                f_output.write(''.join(diff) + '\n\n')
            else:
                pass
                # f_output.write(f"行 {i+1}({core_identifier}): 差分はありません。\n")

# 比較するファイルのパス
core_file = 'sudachi-result.txt'
full_file = 'sudachi-full-result.txt'
diff_output_file = 'diff_results.txt'

compare_results(core_file, full_file, diff_output_file)

差分は以下です

--- 差分が見つかりました(行 9) ---
識別子: VOICEACTRESS100_009
【Core辞書の結果】
またねじめしは、なかやまおうのおさめる、りゅうきゅうおうこくとのこうえきにもさんかした。
【Full辞書の結果】
またねじめしは、ちゅうざんおうのおさめる、りゅうきゅうおうこくとのこうえきにもさんかした。
【差分】
  ま  た  ね  じ  め  し  は  、- な- か- や- ま+ ち+ ゅ+ う+ ざ+ ん  お  う  の  お  さ  め  る  、  り  ゅ  う  き  ゅ  う  お  う  こ  く  と  の  こ  う  え  き  に  も  さ  ん  か  し  た  。

--- 差分が見つかりました(行 27) ---
識別子: VOICEACTRESS100_027
【Core辞書の結果】
ちょういきにあった、みねやまはんは、ながおかはんに、べいひゃくひょうをおくったことでゆうめい。
【Full辞書の結果】
ちょういきにあった、みねやまはんは、ながおかはんに、こめひゃっぴょうをおくったことでゆうめい。
【差分】
  ち  ょ  う  い  き  に  あ  っ  た  、  み  ね  や  ま  は  ん  は  、  な  が  お  か  は  ん  に  、- べ- い+ こ+ め  ひ  ゃ- く- ひ+ っ+ ぴ  ょ  う  を  お  く  っ  た  こ  と  で  ゆ  う  め  い  。