気づくとGWがおわっていました。何を言っているか(ry
さて、今回は題名にもあるとおり、ようやく使えそうになったかな配列について書こうかなと思います。
まず配列のスペック
まずはなにはともあれ、配列の仕様について記載しておきましょう。
- 中指同時シフト
- 基本的には1打鍵1モーラ
- 清濁拗音小書き同置
- 濁音と半濁音、小書きは専用のシフトキーが存在しています
- 拗音拡張あり
- Q/P/Y/Tは文字領域としては利用しない
- トータル26キーしか使いません。もうちょっと制約を追加することで、24キーも視野には入っているのですが、効率の悪化とのトレードオフなので、現状では重要視してません
- また、24キーとなると、そもそもひらがなだけでシフト面すらも埋まってしまうなど、いろいろと制約が強くなります
実際の配列面は以下のようになっています。
無シフト面:
┏━┳━┳━┳━┳━┳━┳━┳━┳━┳━┓
┃ ┃は┃し┃っ┃ ┃ ┃こ┃て┃く┃ ┃
┣━╋━╋━╋━╋━╋━╋━╋━╋━╋━┫
┃た┃ん┃う┃の┃に┃き┃か┃な┃い┃と┃
┣━╋━╋━╋━╋━╋━╋━╋━╋━╋━┫
┃ら┃る┃り┃を┃お┃も┃ま┃す┃あ┃つ┃
┗━┻━┻━┻━┻━┻━┻━┻━┻━┻━┛
シフト面:
┏━┳━┳━┳━┳━┳━┳━┳━┳━┳━┓
┃ ┃ゆ┃え┃ほ┃ ┃ ┃ろ┃よ┃れ┃ ┃
┣━╋━╋━╋━╋━╋━╋━╋━╋━╋━┫
┃み┃そ┃む┃わ┃さ┃ ┃ ┃む┃ふ┃ぬ┃
┣━╋━╋━╋━╋━╋━╋━╋━╋━╋━┫
┃け┃ち┃せ┃ー┃ひ┃め┃へ┃ね┃ ┃や┃
┗━┻━┻━┻━┻━┻━┻━┻━┻━┻━┛
濁音シフト:
┏━┳━┳━┳━┳━┳━┳━┳━┳━┳━┓
┃ ┃ば┃じ┃ぼ┃ ┃ ┃ご┃で┃ぐ┃ ┃
┣━╋━╋━╋━╋━╋━╋━╋━╋━╋━┫
┃だ┃ぞ┃ ┃ ┃ざ┃ぎ┃が┃ ┃ぶ┃ど┃
┣━╋━╋━╋━╋━╋━╋━╋━╋━╋━┫
┃げ┃ぢ┃ぜ┃ ┃び┃ ┃べ┃ず┃ ┃づ┃
┗━┻━┻━┻━┻━┻━┻━┻━┻━┻━┛
半濁音シフト:
┏━┳━┳━┳━┳━┳━┳━┳━┳━┳━┓
┃ ┃ぱ┃ ┃ぽ┃ ┃ ┃ ┃ ┃ ┃ ┃
┣━╋━╋━╋━╋━╋━╋━╋━╋━╋━┫
┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ぷ┃ ┃
┣━╋━╋━╋━╋━╋━╋━╋━╋━╋━┫
┃ ┃ ┃ ┃ ┃ぴ┃ ┃ぺ┃ ┃ ┃ ┃
┗━┻━┻━┻━┻━┻━┻━┻━┻━┻━┛
純粋な最適化計算のみで構築しました。ただし、拗音拡張と小書き文字については、次のルールに従って構成しています。
「しょ」の場合、
E + I = 「しょ」
E + O = 「しゅ」
E + ; = 「しゃ」
「じょ」の場合、
E + J + I = 「じょ」
E + J + O = 「じゅ」
E + J + ; = 「じゃ」
小書きは「q」「p」と対応するカナが書いているキーとの組み合わせです。
つまり、逆手の IO; / EWAに、yo/yu/yaを割り当てています。配列の生成時に、ここが重ならないように制約を追加しているので、無シフト・シフトの区別なく拗音拡張を適用できるようになっています。濁音シフトのキーを追加すると、濁音込みの拗音を入力できるようになっています。
いくつかの記号は、特殊な組み合わせにて提供するようにしています。
D + F = 「、」
J + K = 「。」
J + K + E = 「・」
J + K + D = 「?」
J + K + C = 「!」
配列の性能評価
実際、あまり数値での比較には意味がないと言う主張もありますが、一定の絶対評価というか参考値にはなります。評価は https://github.com/mobitan/chutoro を利用させてもらいました。
配列 濁音 シフトキー 同手シフト 打鍵数 (打鍵効率) 交互打鍵 同手同段異指 同指異鍵 同指跳躍
ローマ字 2,986,212 (1.68) 1,114,123 (37.3%) 179,939 (6.2%) 186,757 (6.4%) 45,737 (1.5%)
新JIS配列 (X 6004) 後置 小|小 なし 2,194,808 (1.23) 893,773 (45.5%) 85,859 (4.0%) 64,439 (3.3%) 5,960 (0.3%)
TRON 同位置 親|親 あり 2,159,353 (1.21) 767,030 (43.0%) 58,248 (2.7%) 72,446 (4.1%) 11,496 (0.6%)
蜂蜜小梅配列 同位置 親|親 あり 2,289,154 (1.29) 769,380 (42.5%) 65,992 (2.9%) 62,118 (3.5%) 10,016 (0.6%)
月配列 2-263 後置 中|中 なし 2,279,282 (1.28) 1,187,864 (52.1%) 122,720 (5.4%) 61,313 (2.7%) 8,520 (0.4%)
月配列 T 後置 中|中 なし 2,344,714 (1.32) 1,269,518 (54.1%) 120,888 (5.2%) 70,943 (3.1%) 8,438 (0.4%)
○配列 後置 中|中 なし 2,312,427 (1.30) 1,217,905 (52.7%) 135,010 (5.9%) 54,494 (2.4%) 4,923 (0.2%)
月配列 U9M2 同位置 薬中|中薬 なし 2,309,899 (1.30) 1,207,920 (52.3%) 128,762 (5.6%) 59,765 (2.6%) 12,905 (0.6%)
月配列 U9 同位置 薬中|中薬 なし 2,361,111 (1.33) 1,239,191 (52.5%) 132,478 (5.7%) 60,252 (2.6%) 12,491 (0.5%)
月配列 3-154改 ほぼ同位置 中|中薬小 なし 2,262,676 (1.27) 1,197,064 (52.9%) 94,425 (4.2%) 62,463 (2.8%) 8,873 (0.4%)
月配列 3-196 ほぼ同位置 薬中|中薬 なし 2,300,221 (1.29) 1,220,472 (53.1%) 104,718 (4.6%) 65,659 (2.9%) 6,637 (0.3%)
星配列 別位置 薬中|中薬 なし 2,343,346 (1.32) 1,244,620 (53.1%) 145,515 (6.3%) 42,078 (1.8%) 8,024 (0.3%)
月配列 5-315 別位置 中|中 あり 2,214,382 (1.24) 990,177 (44.7%) 267,834 (12.2%) 50,555 (2.3%) 10,080 (0.5%)
月配列 E-X 別位置 中|中薬 あり 2,337,024 (1.31) 1,060,632 (45.4%) 291,499 (12.7%) 61,713 (2.7%) 11,550 (0.5%)
ハイブリッド月配列 別位置 小中|中 あり 2,152,030 (1.21) 882,234 (41.0%) 270,390 (12.8%) 82,801 (3.9%) 17,441 (0.8%)
ブリ中トロ配列 2021/10/23 同位置 中|中 あり 2,177,508 (1.22) 1,001,449 (46.0%) 226,228 (10.5%) 64,915 (3.0%) 6,091 (0.3%)
ブリ中トロ配列 2022/10/15 同位置 中|中 あり 2,177,508 (1.22) 1,007,133 (46.3%) 217,394 (10.1%) 65,120 (3.0%) 5,726 (0.3%)
test 同位置 中|中 なし 2,363,146 (1.33) 1,086,774 (46.0%) 282,534 (12.1%) 66,617 (2.9%) 8,325 (0.4%)
(余裕があったら整えます・・・)
交互打鍵自体は重視していないのですが、基本的に打鍵数は単打で打てるキーの数が多い=キー数が多い配列であれば下がりやすくなっています。この配列では、そもそも利用できるキー数自体が少ないので、どうしても打鍵数は悪化します。
計算配列は特徴がないのが特徴、と言われることもあるようなので、まぁこの数値は参考程度に見てもらえればよいかと。
配列のコンセプト
今までいろいろな配列を使ってきましたが、以下のような特徴を持っている配列はありませんでした。コレがそのままコンセプトとなっています。
- 格子型配列、左右分離キーボードに特化している
- 清濁同置
- 拗音拡張があり、清音と同一の配置である
- 同時打鍵方式
- 親指でシフトしない
- QTYPなどを利用しない
- 30キー以内での実装
特に、親指でシフトしない、30キー以内、清濁同置、となるとほぼ存在しなかったため、自作と相成りました。実際にやってみて痛感したのですが、この制約を導入すると、 非常に作りづらい ということがよくわかりました・・・。
制約を設計する上で、参考にしたのは以下の配列です。
- 中指同時打鍵シフトのコンセプトは新下駄配列から
- 清濁拗音同置は薙刀式配列から
- QTYPを利用しない方針は薙刀式配列から
- 計算配列の方針についてはぶな配列・月見草配列から
また、計算配列の最も重要であるデータは 月見草配列 の作者様が公開されているものを利用させていただきました。ここで謝辞を述べさせていただきます。
なぜ親指シフトを嫌ったのか?
大抵の左右分離キーボードにおいては、親指に負荷を分散する、というのが一般的かと思います。私自身も、SandSを長年利用しているというのもあり、それ自体には異論はありません。
しかし、もともと利用していた SKK 、また、この後blogで書く予定の日本語入力方式との相性がかなり悪い、という事実があります。特にSKKは、qwertyに特化しすぎているため、NICOLAなどのかな入力ではほぼ使い物にならない、というのが実態です。
もともと使っていた薙刀式でも、作者により、相性は悪いと明言されています。(http://oookaworks.seesaa.net/article/502016567.html#gsc.tab=0)
ここをなんとかしようとしたら、もはや自作するしかなかった、というのが実態です。最終的には、どっちでもあまり変らないような形式にすることはできたので、次着は生成しなくてもよかったのではないか、という葛藤もあるのですが。
配列の計算方法
まだ使い始めたばかりなので、使用感みたいなのはまだ語ることはないので、どのようにして計算したのか?を書き連ねてみます。
実際に計算するプログラムは以下のリポジトリにあります。
https://github.com/derui/keymap-generator
アルゴリズム
Compact GAの亜種と山登り法を組み合わせて、以下のように計算を進めています。
- ランダムな配列を2つ生成する
- 評価関数を適用し、低い方がよりよいものとして、確率を更新する
- 2.で更新した確率から配列を2つ生成する
- 2-3を1000回繰り返す
- 一回前に生成した配列のうち、良い方をベースとして、山登り法を適用する
- 2.から繰り返す
今回の配列は、だいたいこのプロセスを100回ほど実行した中でのベストスコアを記録した配列です。内部的には20,000,000くらいの配列を評価したことになっています。これらを実際に打鍵して評価する、というのはほぼ不可能なので、ここについては生成しなければわからないものだとは思います。
確率の持ち方
配列を生成するときの元になる確率ですが、次のような持ち方をしています。
- 各キーの無シフト面とシフト面のそれぞれに、割当可能な50文字の出現回数
- ↑を26キー分
もちろん、これだけだと制約を構成できないキーマップが普通に生成されてしまいます。そのため、生成や変更時には、常に以下の制約が満たされていることを確認しています。
- 1キーの中で濁音になりうるキーは排他
- シフトキー自体のシフト面は左右で同じ
- シフトキーは両面ともに濁音または半濁音になりうる文字は割り当てられない
- 左右の濁音シフトキー間では、濁音になりうる文字は一つまでしか設定できない
- 左右の半濁音シフトキー間では、半濁音になりうる文字は一つまでしか設定できない
- 拗音拡張対象の文字は1キーの中で排他
実際にここの判定をしている箇所は以下になります。
だいぶ処理としては複雑なのですが、評価関数のほうがよっぽど時間がかかるので、これくらいの負荷はほぼ誤差レベルとなっています。
評価関数
さて、最適化計算においては、評価関数がとても重要になります。今回の評価関数は、以下を評価値として利用しています。
- 各キーごとのweight = 負荷係数
- 2つのキーを連続で入力するときの時間
- https://github.com/esrille/keyboard-layout-comparison?tab=readme-ov-file
- 上のリポジトリで公開されているツールを利用しています
- 各連接における特有のペナルティ
- 同じ指で連打する、行のスキップ、などを3連接まで随時追加しています
この関数を、4-gramの連接に対して適用したものをscoreとして利用しました。4-gramの連接と頻度については、月見草配列の作者が公開されているものを利用させていただきました(https://w.atwiki.jp/keylay/pages/16.html)。
ここが一番実装が厄介だったところで、4-gramの連接データ(実際に有効なデータとして利用したのは240,000ほどでした)分、評価関数を適用しなければならないのですが、単純に計算量が多すぎるという課題があります。大分最適化をしていますが、20スレッドで動かしても、 1000配列 / 秒
くらいが上限となっているのが現状です。山登り法で近傍の配列を生成するだけで、約1300個くらいの配列が出来あがるのですが、この速度だと1ループで1秒ほどかかるため、一回の評価に大体30秒前後かかります。今回の配列だと、途中の休憩を含めると、大体8時間くらいかかっています。
引き続きある課題
さて、現在はそれなりに使える配列を作れたものの、まだまだ課題は残っています。
- 各々の指の使用率があまりよくない
- 計算の収束が遅いので、なんらかのスコア計算を変えると、再生成に時間がかかってしまう
また、ある程度使い込んでみないとわからないものもあるので、しばらくは頑張って使っていこうと思います。