日本語フィラー除去をkuromoji.jsで簡易実装

日本語の話し言葉には「えー」「あのー」「その」「なんか」などのフィラー（つなぎ言葉）が頻繁に登場します。
音声認識やテキスト化の現場では、これらフィラーを除去することが、可読性や情報抽出の精度向上に役立ちます。
LLMでも当然ながらフィラー除去は可能ですが、もっと軽快にフィラーのみに特化した軽量なツールは意外と少ないのが現状です。

そこで今回は、JavaScriptで動作する形態素解析ライブラリ「kuromoji.js」を使い、簡易的な日本語フィラー除去ツールを実装してみました。

---

## kuromoji.jsとは？

「kuromoji.js」は、日本語形態素解析器「kuromoji」のJavaScript実装です。Node.js環境はもちろん、フロントエンドでも動作します。形態素解析を通じて、テキストを単語単位に分割し、品詞情報などを取得できます。

---

## 実装のポイント

- **フィラー除去に特化した辞書やAPIは見当たらなかったため、形態素解析の結果からフィラーや感動詞を判定し除去**
- **kuromoji.jsの品詞情報（`pos`）を活用し、フィラーや感動詞に該当するトークンをスキップ**
- **代表的なフィラー語（例：「まあ」「その」「なんか」「あの」「それで」）もリスト指定で除去**
- **除去後、連続する読点や文頭・文末の不要な読点も正規表現で整理**
- **LLMのように重くなく、実用的な速度で動作**

---

## サンプルコード

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>フィラー除去（kuromoji.js）</title>
</head>
<body>
  <h2>日本語フィラー除去（kuromoji.js）</h2>
  <textarea id="inputText" rows="5" cols="60">えー、今日はその、いい天気ですね、あのー、出かけたいです。</textarea><br>
  <button id="runButton" disabled>フィラー除去</button>

  <h3>除去後のテキスト:</h3>
  <pre id="outputText"></pre>

  <!--  kuromoji.jsの読み込み -->
  <script src="./kuromoji.js"></script>

  <!--  kuromoji使用スクリプト（DOMContentLoadedで実行） -->
  <script>
    let tokenizer = null;

    window.addEventListener("DOMContentLoaded", () => {
      // kuromoji.jsが読み込まれた後に初期化
      kuromoji.builder({ dicPath: "./dict/" }).build((err, builtTokenizer) => {
        if (err) {
          console.error("Tokenizer build error:", err);
          return;
        }

        tokenizer = builtTokenizer;
        console.log("Tokenizer ready.");

        // ボタンを有効化
        document.getElementById("runButton").disabled = false;

        document.getElementById("runButton").addEventListener("click", () => {
          const text = document.getElementById("inputText").value;
          const tokens = tokenizer.tokenize(text);
        
          const fillerWords = ["まあ", "その", "なんか", "あの", "それで"];
          let result = [];
          for (let i = 0; i < tokens.length; i++) {
              const token = tokens[i];
              // フィラーや感動詞で、かつ「えっ」以外なら除去
              if (
                (["感動詞", "フィラー"].includes(token.pos) ||
                fillerWords.includes(token.surface_form)) &&
                token.surface_form !== "えっ"
              ) {
                // 直後が読点や句点や空白ならそれもスキップ
                if (
                  tokens[i + 1] &&
                  (tokens[i + 1].surface_form === "、" ||
                   tokens[i + 1].surface_form === "。" ||
                   tokens[i + 1].surface_form === " ")
                ) {
                  i++;
                }
                continue;
              }
              result.push(token.surface_form);
          }
          let filtered = result.join("");
        
          // 連続する読点を1つにまとめる
          filtered = filtered.replace(/、{2,}/g, "、");
          // 文頭・文末の不要な読点を除去
          filtered = filtered.replace(/^、+|、+$/g, "");
        
          document.getElementById("outputText").textContent = filtered;
        });
      });
    });
  </script>
</body>
</html>
```

---

## 実行例

**入力:**
> えー、今日はその、いい天気ですね、あのー、出かけたいです。

**出力:**
> 今日はいい天気ですね、出かけたいです。

---

## 工夫・注意点

- **辞書のパス**  
  CDNではなく、GitHubから入手した辞書を自サーバに配置して利用。
- **フィラー検出の精度**  
  前後の品詞や文脈までは考慮していないため、完全な精度は期待できないが、実用レベルでは十分。
  「えっと」は「えっ」も感動詞として登録されているため、「と」だけ残る。辞書を修正すれば対応可能だが、現状は除外している。
- **多言語対応**  
  kuromoji.jsは日本語専用。他言語の場合は別途対応が必要ですが、現状めぼしい軽量ライブラリは少ない印象。
- **翻訳後のフィラー除去**  
  どちらかが日本語なら、この方式で十分対応可能。

---

## 他言語・他サービスとの比較

- **英語の場合**  
  Microsoft Azureの音声認識APIで「True Text」機能を有効にすると、ある程度フィラーが自動除去されるが、日本語はほぼそのままになる。英語では多少有効な模様。

---

## まとめ

- kuromoji.jsを使えば、軽量かつ手軽に日本語テキストのフィラー除去が可能
- LLMやAIモデルよりも高速・省リソース
- フィラー除去は音声認識後のテキスト整形や、チャットログのクリーンアップなどに役立つ

---

### 参考

- kuromoji.js公式 (https://github.com/takuyaa/kuromoji.js) 
- [Qiita: kuromoji.jsを使って日本語クローズテスト](https://qiita.com/pppp403/items/59d90a4483ba86826e63)
- [note: kuromoji.js による 日本語形態素解析 を試す](https://note.com/npaka/n/n7d8eaab45a77)
- [Qiita: Microsoft Cognitive Services Speech ServiceでZoomの字幕ツールを ...](https://qiita.com/mayfair/items/2b3c9e1087ff2bca7424)

---

### おわりに

「フィラー除去」処理の需要は今後も高まるはずです。より高精度な除去や多言語対応も今後の課題ですが、まずはkuromoji.jsでのシンプルな実装から始めてみてはいかがでしょうか。