Skip to main content

Lightweight offline Japanese input completion library

Project description

ja-complete

LLMやデータベースを使わない、軽量なオフライン日本語入力補完ライブラリ

概要

ja-completeは日本語テキスト補完・予測のための純粋なPython OSSライブラリです。異なるユースケースに対応する複数の独立した補完メソッドを提供します:

  • フレーズベース補完: 自動プレフィックス生成を伴うカスタムフレーズリスト
  • N-gramモデル: 日本語テキストコーパスに基づく統計的予測
  • 単純辞書: プレフィックスから候補への直接マッピング
  • カスタムJSONL: 柔軟なカスタムデータフォーマットサポート

主な特徴:

  • LLMやデータベース不要: 完全オフラインで軽量
  • 複数の独立した補完API
  • Janomeによる形態素解析
  • CLIツール、エディタ、Webアプリケーションへの簡単な統合

インストール

pip install ja-complete
# または uv を使用
uv add ja-complete

クイックスタート

フレーズベース補完

from ja_complete import JaCompleter

completer = JaCompleter()

# カスタムフレーズを追加
phrases = [
    "スマホの買い換えと合わせて一式揃えたい",
    "新生活に備えた準備を始めたい",
    "夏を爽やかに過ごしたい",
]
completer.add_phrases(phrases)

# 補完を取得(フレーズマッチがない場合、自動的にN-gramにフォールバック)
results = completer.suggest_from_phrases("ス", top_k=5)
print(results)  # [{'text': 'スマホの買い換えと合わせて一式揃えたい', 'score': 0.82}, ...]

# 厳密なフレーズマッチングのためN-gramフォールバックを無効化
results = completer.suggest_from_phrases("未登録の入力", fallback_to_ngram=False)
print(results)  # [] (フレーズマッチがない場合は空)

N-gram補完

from ja_complete import JaCompleter

completer = JaCompleter()

# デフォルトのN-gramモデルを使用
results = completer.suggest_from_ngram("今日は", top_k=5)
print(results)  # [{'text': '今日はいい天気', 'score': 0.85}, ...]

# 助詞拡張を無効化
results = completer.suggest_from_ngram("今日は", top_k=5, extend_particles=False)
print(results)  # 助詞で終わる候補のみ

単純辞書補完

from ja_complete import JaCompleter

completer = JaCompleter()

# 単純なプレフィックスマッピングを追加
suggestions = {
    "お": ["おはよう", "おやすみ", "お疲れ様"],
    "あり": ["ありがとう", "ありがとうございます"],
}
completer.add_simple_suggestions(suggestions)

# 補完を取得(マッチがない場合、自動的にN-gramにフォールバック)
results = completer.suggest_from_simple("あり", top_k=3)
print(results)  # [{'text': 'ありがとう', 'score': 1.0}, ...]

# フォールバックを無効化
results = completer.suggest_from_simple("未登録", fallback_to_ngram=False)
print(results)  # [] (マッチがない場合は空)

フレーズから補完データを生成

文字ベースのプレフィックス生成

from ja_complete import JaCompleter

# フレーズから文字ベースのプレフィックスマッピングを生成
phrases = ["今日はいい天気", "今日は雨", "明日は晴れ"]
suggestions = JaCompleter.phrases_to_simple_suggestions(phrases)

# SimpleSuggestions型で返される
print(suggestions.data["今"])
# ['今日はいい天気', '今日は雨']

# 補完器に直接追加可能
completer = JaCompleter()
completer.add_simple_suggestions(suggestions)
results = completer.suggest_from_simple("今", fallback_to_ngram=False)
print(results)  # 2件の候補が返される

N-gramデータの抽出とモデルへの追加

from ja_complete import JaCompleter

# フレーズからN-gramデータを抽出(形態素情報含む)
phrases = [
    "今日はいい天気ですね",
    "明日は雨が降りそうです",
    "週末は晴れるといいな",
]
ngram_data = JaCompleter.phrases_to_ngram_data(phrases)

# NgramData型で返される
print(ngram_data.unigrams["今日"])  # カウント数
print(ngram_data.morphology["今日"].pos)  # 品詞情報

# デフォルトモデルに追加してカスタマイズ
completer = JaCompleter()
completer._ngram_model.add_ngram_data(ngram_data)

# カスタマイズしたモデルで補完
results = completer.suggest_from_ngram("今日は", top_k=5)
print(results)

CLI使用方法

# フレーズベース補完
ja-complete phrase "新生活" --phrases phrases.txt

# N-gram補完
ja-complete ngram "今日は"

# 単純辞書補完
ja-complete simple "あり" --dict suggestions.json

APIリファレンス

JaCompleter

複数の補完メソッドを提供するメインクラス。

コンストラクタ

  • JaCompleter(enable_ngram_fallback: bool = True)
    • オプションのN-gramフォールバック付きで補完器を初期化
    • enable_ngram_fallback=Trueの場合、フレーズおよび単純辞書メソッドはマッチが見つからない場合に自動的にN-gram補完を使用

メソッド

フレーズベース補完:

  • add_phrases(phrases: List[str]) -> None

    • フレーズベース補完用のフレーズを追加
    • 形態素解析を使用して自動的にプレフィックスを生成
  • suggest_from_phrases(input_text: str, top_k: int = 10, fallback_to_ngram: bool | None = None, extend_particles: bool = True) -> List[Dict[str, Any]]

    • 追加されたフレーズから補完を取得
    • マッチがなくfallback_to_ngram=True(またはインスタンスデフォルト)の場合、N-gram補完を返す
    • スコア付きのランク付けされた結果を返す

N-gram補完:

  • suggest_from_ngram(input_text: str, top_k: int = 10, extend_particles: bool = True) -> List[Dict[str, Any]]

    • N-gramモデルを使用して補完を取得
    • デフォルトモデルまたはロードされたカスタムモデルを使用
    • extend_particles=Trueの場合、助詞で終わる候補に次の語を自動追加
  • load_ngram_model(model_path: str) -> None

    • ファイルからカスタムN-gramモデルを読み込む

単純辞書補完:

  • add_simple_suggestions(suggestions: Dict[str, List[str]] | SimpleSuggestions) -> None

    • プレフィックスから候補へのマッピングを追加
    • 辞書形式またはSimpleSuggestions値オブジェクトを受け入れ
  • suggest_from_simple(input_text: str, top_k: int = 10, fallback_to_ngram: bool | None = None, extend_particles: bool = True) -> List[Dict[str, Any]]

    • 単純辞書から補完を取得
    • マッチがなくfallback_to_ngram=True(またはインスタンスデフォルト)の場合、N-gram補完を返す
    • 直接プレフィックスマッチング

データ変換メソッド:

  • phrases_to_simple_suggestions(phrases: List[str], min_prefix_length: int = 1, max_prefix_length: int = 10) -> SimpleSuggestions (静的メソッド)

    • フレーズから文字ベースのプレフィックスマッピングを生成
    • 各フレーズから1文字〜max_prefix_length文字までのプレフィックスを抽出
    • SimpleSuggestions値オブジェクトを返す
  • phrases_to_ngram_data(phrases: List[str]) -> NgramData (静的メソッド)

    • フレーズをN-gramデータに変換(形態素情報含む)
    • unigram/bigram/trigramのカウントと形態素情報を抽出
    • NgramData値オブジェクトを返す

値オブジェクト型

SimpleSuggestions

  • プレフィックス -> 補完候補リストのマッピングを保持する値クラス
  • data: Dict[str, List[str]] - プレフィックスから候補へのマッピング
  • to_dict() -> Dict[str, List[str]] - 通常の辞書に変換
  • イミュータブル(frozen)
  • バリデーション付き(空文字列キー禁止、空リスト禁止)

MorphToken

  • 形態素トークン情報を保持する値クラス
  • surface: str - 表層形
  • pos: str - 品詞
  • base_form: str - 基本形
  • イミュータブル(frozen)

NgramData

  • N-gramカウントと形態素情報を保持する値クラス
  • unigrams: Dict[str, int] - unigramカウント
  • bigrams: Dict[str, Dict[str, int]] - bigramカウント
  • trigrams: Dict[Tuple[str, str], Dict[str, int]] - trigramカウント
  • morphology: Dict[str, MorphToken] - 形態素情報
  • バリデーション付き(正の整数カウントのみ)

NgramModel

メソッド:

  • add_ngram_data(data: NgramData) -> None
    • N-gramデータをモデルにマージ(破壊的更新)
    • 既存のカウントに新しいカウントを加算
    • 形態素情報を追加(既存のトークンは上書きしない)
    • vocabulary_sizeを自動更新

スコアリングの仕組み

フレーズベース補完のスコアリング

フレーズベース補完は、プレフィックスマッチングと意味的類似性の両方を考慮したハイブリッドスコアリングアルゴリズムを使用します:

スコア構成要素:

  1. プレフィックスマッチ品質(60%): 入力がフレーズの先頭とどれだけよくマッチするか
  2. 形態素オーバーラップ(40%): 入力からの形態素(単語単位)がフレーズにいくつ現れるか

例:

# 完全な形態素オーバーラップを持つ長い入力
入力: "スマホの買い換え"
フレーズ: "スマホの買い換えと合わせて一式揃えたい"
スコア: 0.82 ( - 良好なプレフィックスマッチ + すべての形態素が存在)

# 短い入力
入力: "スマホ"
フレーズ: "スマホの買い換えと合わせて一式揃えたい"
スコア: 0.75 (良好 - 短いプレフィックスだが形態素は存在)

# 完全一致
入力: "夏を爽やかに過ごしたい"
フレーズ: "夏を爽やかに過ごしたい"
スコア: 1.0 (完全一致)

このハイブリッドアプローチにより:

  • 入力と正確に始まる補完が優先される
  • 意味的に関連するフレーズ(キーワードを含む)がより高くランク付けされる
  • より短く関連性の高い補完が不当にペナルティを受けない

N-gram補完の助詞拡張機能

N-gram補完は助詞で終わる候補を自動的に拡張する機能を持っています:

動作:

  • 「今日は」のような助詞で終わる入力に対し、次に来る可能性の高い1〜3語を予測
  • 元のスコアと次のトークンの確率を掛け合わせて総合スコアを算出
  • 元の助詞終わりの候補と拡張された候補の両方を返す

例:

入力: "今日は"
結果extend_particles=True:
  - "今日は " (元の候補)
  - "今日は晴れ" (拡張された候補)
  - "今日は雨" (拡張された候補)
  - "今日は良い天気" (拡張された候補)

結果extend_particles=False:
  - "今日は " (元の候補のみ)

セキュリティに関する考慮事項

重要: Pickleセキュリティ警告

N-gramモデルはPythonのpickleモジュールを使用してシリアライズされています。Pickleファイルは読み込み時に任意のコードを実行できます。

  • ⚠️ 信頼できるソースからのモデルファイルのみを読み込んでください
  • ⚠️ 不明または信頼できない出所の.pklファイルを読み込まないでください
  • ⚠️ カスタムモデルを読み込むとセキュリティ警告が表示されます
# 安全: デフォルトモデルの使用(パッケージに含まれる)
completer = JaCompleter()

# 警告: カスタムモデルの読み込み(信頼できるファイルのみ使用!)
completer.load_ngram_model("custom_model.pkl")  # セキュリティ警告が表示されます

詳細については、DEVELOPING.mdを参照してください。

カスタムN-gramモデルの構築

独自のN-gramモデルを構築したい上級ユーザー向け:

# Wikipedia抽出用にgensimをインストール
pip install gensim

# 日本語Wikipediaダンプをダウンロード
wget https://dumps.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2

# gensimを使用してテキストを抽出(Python 3.13+推奨)
python extract_wiki_text.py

# またはWikiExtractorを使用(Python 3.12以前)
# python -m wikiextractor.WikiExtractor jawiki-latest-pages-articles.xml.bz2 -o wiki_text/

# N-gramモデルを構築
python scripts/build_ngram_model.py --input training_data/ --output my_model.pkl --verbose

Git LFS(Large File Storage)

このプロジェクトでは、モデルファイル(*.pkl)をGit LFSで管理しています。

開発者向け

リポジトリをクローンまたはプルする際に、Git LFSがインストールされていることを確認してください:

# Git LFSのインストール確認
git lfs version

# インストールされていない場合
# macOS:
brew install git-lfs

# Ubuntu/Debian:
sudo apt-get install git-lfs

# リポジトリでGit LFSを有効化
git lfs install

詳細なセットアップ手順については、docs/GIT_LFS_SETUP.mdを参照してください。

ユーザー向け

通常のpip install ja-completeまたはuv add ja-completeでは、PyPIから自動的にパッケージがインストールされます。Git LFSは不要です。

コントリビューション

コントリビューションを歓迎します!開発セットアップとガイドラインについては、DEVELOPING.mdを参照してください。

ライセンス

このプロジェクトはデュアルライセンス方式を採用しています:

ソースコード - MITライセンス

ソースコードはMITライセンスの下でライセンスされています。

Copyright (c) 2025 Taketo Yoda

N-gramモデルデータ - CC BY-SA 3.0

N-gramモデルファイル(*.pkl)はCC BY-SA 3.0の下でライセンスされています。

デフォルトモデルは日本語Wikipediaデータでトレーニングされています:

  • ソース: 日本語Wikipedia
  • ライセンス: CC BY-SA 3.0
  • 著作権: © Wikipediaコントリビューター
  • データセット: 約10万記事のサブセット

重要: N-gramモデルを配布または修正する場合、以下を行う必要があります:

  1. Wikipediaへの帰属表示を提供
  2. 行われた変更を示す
  3. CC BY-SA 3.0または互換性のあるライセンスの下で配布

詳細については、LICENSE-CC-BY-SA.txtを参照してください。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ja_complete-0.1.0.tar.gz (4.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ja_complete-0.1.0-py3-none-any.whl (4.3 MB view details)

Uploaded Python 3

File details

Details for the file ja_complete-0.1.0.tar.gz.

File metadata

  • Download URL: ja_complete-0.1.0.tar.gz
  • Upload date:
  • Size: 4.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.20 {"installer":{"name":"uv","version":"0.9.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ja_complete-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a5b3294671957017f8ccf32283bb4dd6bcf5884307d20771282ece2b289ffbfc
MD5 93d240e0d4cba393a081a69a090d332f
BLAKE2b-256 f3ed027ad7f5d6095cf0218713527da53142c70cd605d8df9f8a653a5cfb7eba

See more details on using hashes here.

File details

Details for the file ja_complete-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ja_complete-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 4.3 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.20 {"installer":{"name":"uv","version":"0.9.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ja_complete-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 79093da6df0648c3bd49877396160dc99b14d576277fbe40a8c207d090430bc9
MD5 e2872462376347b31bae4f2437acc077
BLAKE2b-256 84683f6b45c3706be1caa9516bfedaff3e4fdc23ce7e5705d688b4b938af1990

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page