辞書管理

Lindera PHP は、形態素解析で使用する辞書の読み込み、ビルド、管理のためのクラスを提供します。

辞書の読み込み

システム辞書

Lindera\Dictionary::load($uri) を使用してシステム辞書を読み込みます。GitHub Releases からビルド済み辞書をダウンロードし、展開したディレクトリのパスを指定してください:

<?php

$dictionary = Lindera\Dictionary::load('/path/to/ipadic');

埋め込み辞書(上級者向け) -- embed-* feature フラグ付きでビルドした場合、埋め込み辞書を使用できます:

<?php

$dictionary = Lindera\Dictionary::load('embedded://ipadic');

ユーザー辞書

ユーザー辞書はシステム辞書にカスタム語彙を追加します。Lindera\Dictionary::loadUserFor() を使用して、組み合わせるシステム辞書に合わせて読み込みます。

<?php

$dictionary = Lindera\Dictionary::load('/path/to/ipadic');
$userDictionary = Lindera\Dictionary::loadUserFor('/path/to/user_dictionary.csv', $dictionary);

.csv はシステム辞書のメタデータでビルドし、ビルドしながら接続コスト行列と 照らして確認します。文脈 ID が行列の範囲外にある行は、その CSV の行番号と表層形を 示す ValueError になります(文脈 ID を参照)。.bin はビルドされたとおりに読み込みます。

Lindera\Dictionary::loadUser($uri, $metadata) は、メタデータだけでユーザー辞書を 読み込みます。この方法で読み込んだ .csv はシステム辞書と組み合わせるときに 確認し、エラーは見出し語をその単語 ID で示します:

<?php

$dictionary = Lindera\Dictionary::load('/path/to/ipadic');
$metadata = $dictionary->metadata();
$userDictionary = Lindera\Dictionary::loadUser('/path/to/user_dictionary.csv', $metadata);

トークナイザーの作成時にユーザー辞書を渡します:

<?php

$dictionary = Lindera\Dictionary::load('/path/to/ipadic');
$userDictionary = Lindera\Dictionary::loadUserFor('/path/to/user_dictionary.csv', $dictionary);

$tokenizer = new Lindera\Tokenizer($dictionary, 'normal', $userDictionary);

または、ビルダー経由で設定します:

<?php

$builder = new Lindera\TokenizerBuilder();
$builder->setDictionary('/path/to/ipadic');
$builder->setUserDictionary('/path/to/user_dictionary.csv');
$tokenizer = $builder->build();

Dictionary メソッド

メソッド戻り値説明
Dictionary::load($uri)Dictionaryシステム辞書を読み込む
Dictionary::loadUser($path, $metadata)UserDictionaryユーザー辞書を読み込む
Dictionary::loadUserFor($path, $dictionary)UserDictionaryシステム辞書に合わせてユーザー辞書を読み込む
Dictionary::version()stringLindera のバージョン文字列を返す
Dictionary::build($source, $dest, $metadata)void辞書をビルドする
Dictionary::buildUser($kind, $source, $dest, $metadata)voidユーザー辞書をビルドする
Dictionary::buildUserFor($source, $dest, $dictionary)voidシステム辞書に合わせてユーザー辞書をビルドする
$dictionary->metadata()Metadata辞書のメタデータを返す
$dictionary->metadataName()string辞書名を返す
$dictionary->metadataEncoding()string辞書のエンコーディングを返す

辞書のビルド

システム辞書のビルド

ソースファイルからシステム辞書をビルドします:

<?php

$metadata = Lindera\Metadata::fromJsonFile('/path/to/metadata.json');
Lindera\Dictionary::build('/path/to/input_dir', '/path/to/output_dir', $metadata);

入力ディレクトリには辞書のソースファイル(CSV レキシコン、matrix.def など)が含まれている必要があります。

Lindera\Metadata::fromJsonFile で読み込んだメタデータは metadata.json の space_penalty ルールを保持し、ビルドした辞書にもそのルールが同梱されます。そのため ko-dic をビルドした場合も、左側空白ペナルティはデフォルトでオンのままです。トークナイザーごとにオフにするには TokenizerBuilder::setSpacePenalty(false) を使います(Tokenizer API を参照)。コンストラクタで作成した Metadata はルールを持ちません。

以下は IPADIC 辞書をダウンロードしてビルドする例です:

<?php

$url = 'https://lindera.dev/mecab-ipadic-2.7.0-20070801.tar.gz';
$filename = '/tmp/mecab-ipadic-2.7.0-20070801.tar.gz';

// Download and extract dictionary source
file_put_contents($filename, file_get_contents($url));
$phar = new PharData($filename);
$phar->extractTo('/tmp/', null, true);

// Load metadata and build
$metadata = Lindera\Metadata::fromJsonFile('resources/ipadic_metadata.json');
Lindera\Dictionary::build(
    '/tmp/mecab-ipadic-2.7.0-20070801',
    '/tmp/lindera-ipadic',
    $metadata
);

ユーザー辞書のビルド

組み合わせるシステム辞書に合わせて、CSV ファイルからユーザー辞書をビルドします:

<?php

$dictionary = Lindera\Dictionary::load('/path/to/ipadic');
Lindera\Dictionary::buildUserFor('user_words.csv', '/path/to/user_dictionary.bin', $dictionary);
$userDict = Lindera\Dictionary::loadUserFor('/path/to/user_dictionary.bin', $dictionary);

CSV はシステム辞書のメタデータでビルドし、接続コスト行列と照らして確認します。 文脈 ID が行列の範囲外にある行は、その CSV の行番号と表層形を示す ValueError になり、ファイルは書き出しません(文脈 ID を参照)。2 番目の引数は書き出すファイルのパスです。ローダーは拡張子で ユーザー辞書の読み込み方を決めるので、.bin で終えてください。

Lindera\Dictionary::buildUser($kind, $input_file, $output_dir, $metadata) は、 メタデータだけでユーザー辞書をビルドします。$output_dir も、名前に反して ディレクトリではなく、書き出すファイルのパスです。各行はシステム辞書と 組み合わせるときに確認し、エラーは見出し語をその単語 ID で示します:

<?php

$metadata = new Lindera\Metadata();
Lindera\Dictionary::buildUser('ipadic', 'user_words.csv', '/path/to/user_dictionary.bin', $metadata);

第一引数($kind、上の例では 'ipadic')は現時点では未使用で、将来のために 予約されています。システム辞書に合わせてビルドするには Lindera\Dictionary::buildUserFor を使います。

Metadata

Metadata クラスは辞書のパラメータを設定します。

Metadata の作成

<?php

// デフォルトのメタデータ
$metadata = Lindera\Metadata::createDefault();

// カスタムメタデータ
$metadata = new Lindera\Metadata('my_dictionary', 'UTF-8', -10000);

JSON からの読み込み

$metadata = Lindera\Metadata::fromJsonFile('metadata.json');

プロパティ

プロパティ型デフォルト説明
namestring"default"辞書名
encodingstring"UTF-8"文字エンコーディング
default_word_costint-10000未知語のデフォルトコスト

toArray()

メタデータを連想配列(値はすべて文字列)で返します。ko-dic のようにメタデータが左側空白ペナルティのルールを持つ場合は、そのルールを JSON 文字列で保持する space_penalty エントリも含まれます。ルールがなければこのキーはありません:

<?php

$metadata = Lindera\Metadata::fromJsonFile('/path/to/ko-dic/metadata.json');
$rules = json_decode($metadata->toArray()['space_penalty'], true);
// ['rules' => [['pos' => ['EC', 'EF', ...], 'cost' => 3000], ...]]

Schema

Schema クラスは辞書のフィールド構造を定義します。

Schema の作成

<?php

// デフォルトスキーマ(IPADIC 互換)
$schema = Lindera\Schema::createDefault();

// カスタムスキーマ
$schema = new Lindera\Schema(['surface', 'pos']);

メソッド

メソッド戻り値説明
fieldCount()intフィールド数を返す
getFieldIndex($name)intフィールドのインデックスを返す(見つからない場合は -1)
getFieldByName($name)FieldDefinition または nullフィールド情報を返す
getCustomFields()array<string>カスタムフィールド名の配列を返す
validateRecord($record)voidレコードがスキーマに適合するか検証する

Schema プロパティ

プロパティ型説明
fieldsarray<string>フィールド名の配列