Neinvalli

研究テーマは ”IT 環境でのリソース最適化” です

日本語 / 英語 両方に最適化した IT エンジニア向けキー配列 Astarte を作りました


キー配列 Astarte

キー配列 Astarte

Keyboard Layout Analyzer にて英語/日本語で解析した際のヒートマップです。
青から赤になるにつれて使用頻度が高くなります。

アルファベット以外のキーは無視してください。
(特にホームポジション付近の記号については仮で配置してあるだけです)

ヒートマップではないほうの画像も貼っておきます。

キー配列 Astarte


メジャーな配列とのスコア比較 (英語 / 日本語 混在)

Keyboard Layout Analyzer にてメジャーな配列とのスコア比較した結果です。

  • 対象テキストは 20-30 ほどのサイトから 10-15 種類程度の分野からピックアップしました。
  • 英語はそのまま使用、日本語はヘボン式ローマ字へ変換して使用しています。
  • 割合はほぼ半分で合計 36 万文字程度。

The optimal layout score is based on a weighed calculation that factors in the distance your fingers moved (33%), how often you use particular fingers (33%), and how often you switch fingers and hands while typing (34%).

スコアの詳細については上記のとおりです。

  • 指の移動量
  • 特定の指の使用頻度
  • タイプ中の指や手のスイッチ具合

でスコアが決まるようです。

詳細は下記の記事が詳しいです。

Keyboard Layout Analyzerを使ったキー配列12種類の比較


Astarte 配列の特徴

  • 日本語/ 英語 両方に最適化
  • プログラミングのキーワードやサーバーでのコマンド等の文字列に対しても最適化
  • 指の移動距離を最小化
  • 同じ指の連続使用頻度を最小化
  • 左右の手の交互打鍵頻度を最大化
  • ls が打ちづらくない

Astarte 配列を作成した経緯

1. Dvorak 配列への移行の挫折

おそらくこのページを見ている人は一度は Qwerty から Dvorak や Colemak に乗り換えることを考えたことがあるのではないでしょうか?
乗り換えがうまくいった人や何らかの理由で Qwerty に引き返した人がいるかと思います。 私も 8年ほど前に一度 Dvorak へ乗り換えようと試したことがあり、後者のパターンで Qwerty に引き返して来ました。
仕事で IT エンジニアをしており、仕事上 Linux のサーバーの操作やプログラミングをする機会が多かったため、年末年始の休みを利用して Dvorak 配列に慣れておき年明けに一気に乗り換える作戦でした。
ただ、これはうまくいかず、結局 Qwerty に引き返すことにしました。 直接の引き金は「MySQL で急ぎの作業があった時に "show processlist" とすぐにタイプ出来なかった」ことです。
他にも下記のような不安要素もあり、直感的に Qwerty に戻ることを決めました。

  • Dvorak は英語には最適化されているが日本語に対してはどこまで有効か判断出来なかった
  • 使っているソフトのキーバインド(特にテキストエディタ)をうまく変更できる確信がなかった
  • コピー&ペーストのようないろんなソフトで使われるキーバインドが変わることに対しての対応方法の見込みがなかった
  • シェルコマンド等は Qwerty でそれほで打ちづらくないような名前が選ばれる傾向がある気がしていた

なんとも苦い経験ですが似たような理由で Dvorak への移行を見送った人は他にもいるのではないかと思っています(特に "ls" が打ちづらい、というのはよく言われる話かと思います)

2. Keyboard Layout Analyzer, MTGAP 配列との出会い

Dvorak への移行の挫折から 8年ほどたった去年の秋、下記の記事で Keyboard Layout Analyzer, MTGAP 配列 のことを知りました。

https://qiita.com/ZeptByteS/items/6e6a3e46552dcb105948

MTGAP についてはプログラムで自動生成されたもので、Dvorak, Colemak 等のメジャーな配列に対して圧倒的なスコアを出していたことがとても印象的だったのを覚えています。

3. どうせなら確信を持って新しい配列を試したい

MTGAP でも Dvorak の時のような不安がつきまとうことに変わりはありません。 どうせなら移行するなら、確信を持って移行ができる自分で作成した配列にしようと思い立ち、私自身、AI 関連のプログラムを作った経験があったため、英語と日本語両方に最適化されたキー配列を作成することを決意しました。
Dvorak の ls のようにならないように、プログラミング言語SQL 等で出てくるキーワードもある程度重視するようにしました。

※ Astarte 以外だと ゆかり さんによる Eucalyn配列 があります。Astarte と同様の特徴と「ZXCV のキーはそのまま」「HJKL のキーはあまり動かさない」が特徴です。


キー配列の移行についての注意点

Astarte 配列のアルファベット部分は去年末に完成していたのですが、他にも考慮点が複数あったため Astarte への移行に時間がかかってしまいましたがようやく私自身 Astarte への移行が終わりました。
現状、キー配列は Astarte のみで過ごしています。
キー配列を移行した経験から、注意点がいくつか見えて来ましたので今後の記事で注意点やキー配列について言及していきたいと考えています。


最後に英語・日本語それぞれ単体の時のスコア比較とヒートマップを載せておきます。

メジャーな配列とのスコア比較とヒートマップ (英語)


メジャーな配列とのスコア比較とヒートマップ (日本語)


Keyboard Layout Analyzer で使える Astarte の json ファイルです。 気になる方は Keyboard Layout Analyzer にていろいろ配列やいろいろなテキストでスコア比較してみてください。

Astarte の json (クリックで開く)

{
    "label": "Astarte",
    "fingerStart": {
        "1": 29,
        "2": 30,
        "3": 31,
        "4": 32,
        "5": 56,
        "6": 56,
        "7": 35,
        "8": 36,
        "9": 37,
        "10": 38,
        "11": 56
    },
    "keyboardType": "standard",
    "author": "Neinvalli",
    "authorUrl": "http://neinvalli.hatenablog.com/",
    "moreInfoUrl": "http://neinvalli.hatenablog.com/",
    "moreInfoText": "A keylayout optimized for both of English and Japanese, and some of programming keywords",
    "keys": [
        {
            "primary": 96,
            "shift": 126,
            "finger": 1,
            "id": 0
        },
        {
            "primary": 49,
            "shift": 33,
            "finger": 1,
            "id": 1
        },
        {
            "primary": 50,
            "shift": 64,
            "finger": 2,
            "id": 2
        },
        {
            "primary": 51,
            "shift": 35,
            "finger": 3,
            "id": 3
        },
        {
            "primary": 52,
            "shift": 36,
            "finger": 4,
            "id": 4
        },
        {
            "primary": 53,
            "shift": 37,
            "finger": 4,
            "id": 5
        },
        {
            "primary": 54,
            "shift": 94,
            "finger": 7,
            "id": 6
        },
        {
            "primary": 55,
            "shift": 38,
            "finger": 7,
            "id": 7
        },
        {
            "primary": 56,
            "shift": 42,
            "finger": 8,
            "id": 8
        },
        {
            "primary": 57,
            "shift": 40,
            "finger": 9,
            "id": 9
        },
        {
            "primary": 48,
            "shift": 41,
            "finger": 10,
            "id": 10
        },
        {
            "primary": 59,
            "shift": 58,
            "finger": 10,
            "id": 11,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 61,
            "shift": 43,
            "finger": 10,
            "id": 12
        },
        {
            "primary": 8,
            "finger": 10,
            "id": 13
        },
        {
            "primary": 9,
            "finger": 1,
            "id": 14
        },
        {
            "primary": 113,
            "shift": 81,
            "finger": 1,
            "id": 15,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 112,
            "shift": 80,
            "finger": 2,
            "id": 16,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 117,
            "shift": 85,
            "finger": 3,
            "id": 17,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 121,
            "shift": 89,
            "finger": 4,
            "id": 18,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 44,
            "shift": 60,
            "finger": 4,
            "id": 19,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 106,
            "shift": 74,
            "finger": 7,
            "id": 20,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 100,
            "shift": 68,
            "finger": 7,
            "id": 21,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 104,
            "shift": 72,
            "finger": 8,
            "id": 22,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 103,
            "shift": 71,
            "finger": 9,
            "id": 23,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 119,
            "shift": 87,
            "finger": 10,
            "id": 24,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 91,
            "shift": 123,
            "finger": 10,
            "id": 25
        },
        {
            "primary": 93,
            "shift": 125,
            "finger": 10,
            "id": 26
        },
        {
            "primary": 92,
            "shift": 124,
            "finger": 10,
            "id": 27
        },
        {
            "primary": 20,
            "finger": 1,
            "id": 28
        },
        {
            "primary": 105,
            "shift": 73,
            "finger": 1,
            "id": 29,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 111,
            "shift": 79,
            "finger": 2,
            "id": 30,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 101,
            "shift": 69,
            "finger": 3,
            "id": 31,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 97,
            "shift": 65,
            "finger": 4,
            "id": 32,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 46,
            "shift": 62,
            "finger": 4,
            "id": 33,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 107,
            "shift": 75,
            "finger": 7,
            "id": 34,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 116,
            "shift": 84,
            "finger": 7,
            "id": 35,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 110,
            "shift": 78,
            "finger": 8,
            "id": 36,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 115,
            "shift": 83,
            "finger": 9,
            "id": 37,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 114,
            "shift": 82,
            "finger": 10,
            "id": 38,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 39,
            "shift": 34,
            "finger": 10,
            "id": 39
        },
        {
            "primary": 13,
            "finger": 10,
            "id": 40
        },
        {
            "primary": 16,
            "finger": 1,
            "id": 41
        },
        {
            "primary": 122,
            "shift": 90,
            "finger": 1,
            "id": 42,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 120,
            "shift": 88,
            "finger": 2,
            "id": 43,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 45,
            "shift": 95,
            "finger": 3,
            "id": 44,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 99,
            "shift": 67,
            "finger": 4,
            "id": 45,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 47,
            "shift": 63,
            "finger": 4,
            "id": 46,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 109,
            "shift": 77,
            "finger": 7,
            "id": 47,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 108,
            "shift": 76,
            "finger": 7,
            "id": 48,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 102,
            "shift": 70,
            "finger": 8,
            "id": 49,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 98,
            "shift": 66,
            "finger": 9,
            "id": 50,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": 118,
            "shift": 86,
            "finger": 10,
            "id": 51,
            "altGr": -1,
            "shiftAltGr": -1
        },
        {
            "primary": -16,
            "finger": 10,
            "id": 52
        },
        {
            "primary": 17,
            "finger": 5,
            "id": 53
        },
        {
            "primary": -91,
            "finger": 5,
            "id": 54
        },
        {
            "primary": 18,
            "finger": 5,
            "id": 55
        },
        {
            "primary": 32,
            "finger": 5,
            "id": 56
        },
        {
            "primary": -18,
            "finger": 6,
            "id": 57
        },
        {
            "primary": -91,
            "finger": 6,
            "id": 58
        },
        {
            "primary": -93,
            "finger": 6,
            "id": 59
        },
        {
            "primary": 17,
            "finger": 6,
            "id": 60
        }
    ]
}