gimei icon indicating copy to clipboard operation
gimei copied to clipboard

字種の拡張

Open scivola opened this issue 2 years ago • 2 comments

素晴らしい gem をありがとうございます。

さて,現状,人名も地名も文字種が JIS X 0208 の範囲に収まっていると思います。 目的によると思うのですが,システムの動作を確認するためのテストデータを作るうえで,

  • (シフト JIS を経由するシステムで)JIS X 0208 に含まれないが,Windows 31J(= CP932)に含まれる文字(髙〔ハシゴダカ〕,﨑〔タチサキ〕など)が正しく扱えるか
  • Windows 31J に含まれないが Unicode の基本多言語面(BMP: Basic Multilingual Plane)に含まれる文字(鷗,嵓など)が正しく扱えるか
  • Unicode の基本多言語面に含まれない文字(UTF-8 で 4 バイトになる文字;𡈽 など)が正しく扱えるか

といったことを確かめたいこともあると思いますので,ぜひデータの中に

  • 髙橋,山﨑
  • 鷗外
  • 嵓上(和歌山県西牟婁郡白浜町の地名)
  • 𡈽田

のようなものも含めていただければと思います。 (システムの動作を保証するうえでは,ランダムに発生させるデータではなく,上記のような文字列をあらわに記述したテストコードを書いて確認すべきですが,人手で動作を見たりデモンストレーションが目的の場合,やはりランダムにでも上記のような文字列が含まれていてほしいということです)

また,現状では人名に「島」(を含むもの)はあっても「嶋」(を含むもの)はありませんが,検索システムが異体字の揺れに対応していることを確認する(デモする)うえで,やはりあってほしいので,

  • 島/嶋(あるいは嶌なども)
  • 斉/齊/斎/齋
  • 龍/竜
  • 鉄/鐡/鐵

といった異体字のバリエーションも含まれているとよさそうです。

scivola avatar Sep 20 '21 05:09 scivola

@scivola

大筋問題ないと思うので lib/data/names.ymlやlib/data/addresses.ymlに追加したい文字を入れてPRもらえると嬉しいです!

少し気になっている点

  • 逆にはしご高などの文字が含まれていないほうがうれしいユースケース、というのがあるかどうか気になっています
  • なければ単に文字を増やしてしまえばよいのですが、ある場合はなにかしらのオプションで扱う文字の集合を切り替えられるとうれしいのかな…と思っています
  • もしこのIssueをみていてユースケースが思いつく人はコメントもらえると嬉しいです
  • とくにコメントなければエイヤでPRマージして様子見るつもりでいます

willnet avatar Sep 20 '21 05:09 willnet

はい,この手の文字が「含まれていないほうが嬉しい」ケースはあると思います。

たとえば,システムが MySQL の(utf8mb4 ではなく)utf8 を採用していた場合,BMP 内の文字しか扱えませんから,「𡈽田」さん「𠮷田」とか,地名の「𩸕網代」(長崎県)などが扱えません(保存時に吹き飛んだりする)。

また,システムが Unicode 系の文字コードを用いていても,CSV 出力の際にシフト JIS 化する場合,シフト JIS で表せない文字が入っていると,代替文字に置き換えられたりエラーが出たりします。

※UTF-8 の CSV を Excel がうまく扱えないために,「CSV はシフト JIS で」というオシゴトは少なくない。残念ながら。

その「シフト JIS」も,CP932 と,Ruby でのエンコーディング名「Shift_JIS」(文字集合としては JIS X 0208 の範囲)とでは文字集合の大きさが違い,後者だと「髙」「﨑」が扱えません。

なので,やはり目的に応じて使う文字集合の大きさが変えられるのが理想ですね。 もしそのようにできるなら,文字集合としては

  • JIS X 0208
  • CP932
  • BMP
  • 制限なし(Unicode 全体)

の四つを考えれば十分かと思います。 この四つは単純に,下の文字集合が上の文字集合を包含する関係にあります。

ただ,文字列生成のパラメーターとして,この四つの文字集合のどれかが指定できるだけでなく,可能ならば差集合に属す文字を含んだ文字列という指定もできれば嬉しいですね。 どういうことかというと,例えば 100 人の人名を生成するとして,その中に BMP 外の文字も少しはあってほしいとします。 しかし,names.yml の多数の人名の中で,「𡈽」などを含むデータは僅かしか含められないので,100 人程度生成しても該当のものが一つもない,ということが高確率で起こりえます。 そこで,たとえば 97 人ぶんは「制限なし」で生成し(BMP 外の文字はあるかもしれないし無いかもしれない),念のため 3 人ぶんを「BMP 外の文字を必ず含む人名集合」から生成する,としたいわけです。 「いや,そうしたいんなら,その 3 人ぶんは Gimei 使わずに直に書けばいいじゃん」という考えもありうるので,この機能は必須とまでは思いません。

もしこれを実装するなら,(API をどうするかはともかくとして)こんな感じになると思います:

まず,文字の集合を

  • C1: JIS X 0208 の文字集合
  • C2: CP932 に含まれ,JIS X 0208 に含まれない文字集合
  • C3: BMP に含まれ,CP932 に含まれない文字集合
  • C4: BMP に含まれない文字集合

に分解して考えます(C1, C2, C3, C4 は互いに共通部分をもたず,C1 ∪ C2 ∪ C3 ∪ C4 は Unicode 全体)。

次に,人名集合を

  • N1: C1 のみからなる人名の集合
  • N2: C2 ∪ C1 のみからなり,少なくとも 1 字は C2 − C1(差集合)の文字を含む人名の集合
  • N3: C3 ∪ C2 のみからなり,少なくとも 1 字は C3 − C2 の文字を含む人名の集合
  • N4: C4 ∪ C3 のみからなり,少なくとも 1 字は C4 − C3 の文字を含む人名の集合

の四つ用意します。 N1 は現在のデータですね。 N2 は「山﨑」など,N3 は「鷗外」など,N4 は「𡈽田」などです。

そして,人名を生成するときにパラメーターとして,「BMP 内の文字限定」とした場合,N1 ∪ N2 ∪ N3 の人名からランダムに返す,といった具合です。 ここまでは差集合に対応するか否かに関わらず同じ。

差集合に対応する場合は,たとえば N3 の人名から返す,といった具合ですね。 ただ,姓はいいとして,名は戸籍法の縛りがあるため N4 の例がそう簡単に作れるか分かりません(お年寄りの名はこの縛りが無いはずですが,そもそもレアな字なので)。

ところで,JIS X 0208 の範囲で異体字を豊富に,というほうは難しいことを考える必要がないので,まずはこちらの PR を作ってみようかと思います。

scivola avatar Sep 20 '21 14:09 scivola