ChatGPTを利用してタイピング解析アプリをつくってみた

ちまたで話題のChatGPTを使って自分も遊んでみるかと思い、何をしようかと考えていたのですが、以前タイピングデータを取得・解析するソフトが欲しかったのを思い出しました。ChatGPTとプログラミングの相性はとても良さそうなので、この助けを借りて自作してみることにしました。今回はそのことについて。

タイピングデータの統計が欲しい

最近ChatGPTが注目され、話題となっている。自分もこれで何かして遊ぼうかなと考えていたら、ふとタイピングの統計を取るアプリが欲しかったことを思い出す。以前キー配列の最適化についてブログを書いていた時に、キー配列の最適化は人に依存するだろうから自分のタイピングデータの統計が欲しい、と思ったのだった。

kgnwsknt-chef.hatenablog.com

既存のツール

タイピングの統計を見ることのできるツールはいくつかある。自分がこれまで使用していたのは、このウィンドウズアプリ。

www.vector.co.jp

キーボードを自作し始めた頃にお世話になった。使わないキーを排除するという方針でフルサイズキーボードからテンキーレス、自作キーボードの独自配列とキーボードが移り変わっていった。 自作キーボードの配列を決める際、どのキーの頻度が低くて除けるかを知ることができたのでとても助かった。ありがたやありがたや。

ちなみに自分の統計はこんな感じ。

タイプ数カウンターの統計

このアプリはシンプルで良いのだけれど、タイピングデータの複雑な解析はできない。

これ以外にも、タイピングテストのwebサイトが複数あり、タイピング速度などを表示してくれる。でもこれだとタイピングテストのデータに限定されてしまう。普段の文章打ちのデータも取得したい。

もっとあれこれ分析してみたい

既存のツールではできないもう少し凝った分析をしたい。 なぜならキー配列の最適化について考えていた時に自分が重要ではないかと思ったのが連続打鍵したときのキーの組み合わせだからだ。 連接(英語だと連続する文字列はbigram, ... n-gramらしい)と呼ばれるこの連続打鍵のデータの取得・解析ができれば自分が納得できる答えに辿り着けそうな気がしている。 ただ、連接の統計をとれるアプリを見たことが無かったし(知らないだけかもしれない)、自分で作ろうとすると何から手を付けていいかちょっとわからなかったので放置していた。

そこでChatGPTである。(1)タイピングデータの統計を取るアプリが欲しい、(2)ChatGPTで遊んでみたい、という2つの目的を達成できる気がしたので、アプリ開発を始めることにした。

自分の家のPCはWindowsなのでWindows上で動くGUIのアプリにする。ChatGPTを学習に利用することがどれくらい有効なのか興味があったので、目的(2)は「ChatGPTを学習ツールとして試してみる」と捉えなおし、使用するプログラミング言語はあえて名前しか知らないC#にすることにした。

これに加え、よく目にするけど使ったことが無かったVSCodeも初めて利用してみることにした。ただし開発している途中でWindowsアプリのインストーラーやチャートについてChatGPTに相談してみると、Visual Studioのほうが親和性が良さそうに見えたので、途中からVisual Studio(これも初体験)を使って開発した。

アプリの仕様

取得するデータ

連接の統計を見ようとすると、入力されたキーとその入力時間を取得する必要がある。データは以下のようにした。

  • 入力キー(キーコード)
  • 入力した日時、時間
  • カテゴリー(日本語入力、英語入力など)

入力キーは文字列にするとEnter or Return?とかで悩んでしまうのでキーコード(整数)をデータとする。対応はここに一覧がある。

加えてカテゴリという項目も入れておく。入力している文章の言語(日本語、英語、プログラミング言語)や種類(タイピングテスト、ブログ執筆など)によっても傾向が違うだろうから、あとで分類するために用いる。

データ量はたかが知れているので、これらをいったんファイルに保存し、そのデータを解析して統計を表示することにする。そうすればデータを取得しなおすことなく後から解析の追加が可能となる。データはSQLを利用してファイルに保存する。

機能

せっかくなので自分が欲しいなと思った機能を全部のせ。

ヒートマップ

各キーのタイプ数の頻度を色で表示する。

ヒートマップ表示

自分の使っているキーボードの配列上に表示させたいので、Keyboard Layout Editorが出力するjsonファイルからキー配列を描画するようにした。

入力ミス頻度

Backspaceから誤入力を推定し、エラー率をヒートマップ表示と同じように色で表示する。 これこそ人や入力言語によって違うはず。これがわかると自分のタイピングを改善するのに役立つかも?

ミスタイプの分布、=の苦手具合がひどい

ミスタイプの検知方法

Backspaceの入力からミスタイプを検知している。その判定方法を自分のメモ代わりに書いておく。

  1. アルファベット、記号、数字、スペースのどれかが入力されたらBackspace入力の監視をスタート
  2. 監視中の入力にBackspaceが現れたら、連続で何回入力されたかをカウント

    • EnterやModifierが入力されたら1に戻る
  3. その後Backspace以外が押されたら、数えたBackspaceの入力回数だけ履歴を遡ってどのキーを間違えたかを判定

  4. キー入力間の時間差が一定(今は1.5sとしている)以上になっている場合は1に戻る

日本語入力時ではほとんど正しくない。また今はミスした物理キーでカウントしている。たとえば「!」は1としてカウントされている。これは区別したほうが良いかもしれない。

連接打鍵の入力速度

2連接、3連接の入力時間と回数を表示する。アルファベット26文字の連接を考えると、2連接は26x26=676通り、3連接は17576通りにもなる。4連接以上も見ることはできるけど、3連接でも全てのパターンについて十分な統計を得られる気がしないし分析も大変。3連接までにしておく。

連接のデータ(頻度の多い順に表示)。

ミスタイプで2つ以上のキーの同時押しされたりすると3連接でも10ms以内になったりする。今はこれを上手くこれを除くことはできていない。もう少し何とかしたいところ。

キーチェッカー

入力されたキーが色付けされていってキーが反応するかどうかをチェックできる。PCBをチェックするときに利用するviaの機能の真似です。自分はこれまでviaをちゃんと動かすことができていないのでこの機能も入れることにした。これすごい便利ですね。

キーチェッカー

タイプ数のチャート

タイプ数カウンタ―のようにタイプ数のトレンドをグラフ表示。横軸の範囲の調整がまだ未実装。

タイプ数のチャート

表示するデータの選択

キーチェッカーを除く以上の表示は、カテゴリやキーの種類、またデータのタイムスタンプの期間を選べるようにした。

その他

テキストファイルをインプットして、データベースに変換する。このデータベースから入力した文章について、ヒートマップ表示や連接の登場回数を表示させることができる。ただし英文のみ。

ChatGPTを利用してコーディング

最初はアプリのコードを全部ChatGPTさんに書いてもらえないかとあれこれやってみた(おい、学習はどうした!)。 でもちょっとできそうにない。自分の指示の仕方が上手くないのか、そもそも無謀なのかもしれない。そこで部分ごとにコードを生成、あるいは例を示してもらう、というやり方で進めた。

プログラミングで何か新しいことにチャレンジするときには、これまでであれば入門的なことが書いてあるネットの記事を探すことから始めていた。 ChatGPTを利用すると「C#VSCodeでウィンドウズアプリを作成しています。XXXを行うためにはどのようにすればいいか教えてください。」みたいな質問をするだけで自分が求める情報に行き着くことができる。これはかなりありがたい。

1週間くらいで動くものができた

作業を初めてだいたい1週間(といっても平日は1,2時間程度)でキー入力を取得し、それをSQLでファイルに保存、キーレイアウトのjsonファイルを読み込んでヒートマップを表示するところまでできた。これには自分でも驚いた。プログラミングの経験はあるけれど、ChatGPTを利用せずにネット検索で調べながら進めた場合にはおそらく1か月くらいはかかっていたと思う。なるほど、ChatGPTは確かに作業時間を桁違いに減らしていて、世の中がこれだけ騒ぐのもうなずける。

自分的に助かったのはSQLのコマンド文。タイプミスやちょっとした打ち間違いで以前苦労した記憶があり、すごい苦手意識があった。今回はChatGPTがコマンド文ごとコード生成してくれるのでSQL部分の実装でハマることはなかった。これはありがたい。

ヒートマップ表示は1週間くらいでできたが、ここから他の機能を実装したり、そのためにコードを整理したりして、最終的にまあこんなもんかな、と思えるものができるのには結局1か月くらいかかった。これは自分にWindowsGUIの実装についての知識・経験が不足していて、ChatGPTが例を示してくれても自分がすぐに文脈を理解できていなかったのが主な原因だと思う。特にWindowsでのGUIの実装にはWPFWindows Formがあり、とっても紛らわしい。この2つの違いを認識せずに混在させると、型が合わずにコンパイルできなくて混乱する。

ChatGPTが一瞬のうちにプログラムを示してくれても、自分が理解していなければ組み込んでコンパイルすらできない。結局自分が理解する時間が最終的な作業時間の律速となる気がする。

入力時間の精度

どれくらいの精度で入力時間を測定できているものなのか調べてみた。下記はキーを長押ししたときの入力時間。

キーを長押しして計測された入力時間。一番右の数字が前の入力との時間差(ms)。

大体30msくらい。これはシステムが決めている時間かな?時々15-20msくらいバラつく。入力時間の間隔が変化するのはPCの処理が原因だろうか。まあこれくらいの時間の精度で測定できていれば問題ないでしょう。

ちなみにjを人差し指で連打すると100msくらいであるのに対し、890を右手の人指し指、中指、薬指で連打した場合はだいぶ速い。

jを人差し指で連打した場合と、890を人差し指、中指、薬指で打鍵した場合の入力時間

同じ指の連続打鍵はそれほど速くならないという自分の感覚をはっきりと確認することができて嬉しい。ただしホームポジションから移動する時間は測れていないので、公平な比較かどうかは何とも言えない。

セキュリティ的にはイマイチ

このアプリの欠点はセキュリティ的に危ういところ。はじめは常駐ソフトにして常時データ取得することを考えていたが、そうするとパスワードなども記録されてしまう。どういう統計を取るのか、どういう分析をするのか決めてしまえば入力文字をすべてファイルに保存する必要はないけど、そうするとあとから別の解析をしようとしてもできなくなってしまう。

このジレンマを解決したくてChatGPT先生に相談してみたらこのような示唆をいただいた。

ChatGPT先生に相談してみる

これ、PCにインストールされている何十もあるアプリケーションをすべて把握しないといけないということだろうか…。 やってられんので結局手動で記録の開始・停止をするようにした。それでもうっかり記録していることを忘れると、パスワードや個人情報がファイルに保存されてしまう。取扱注意。

2023年4月22日に開催されたKeybaord Input Hackathon (KIH) 2023の配信を見ていたら、偶然にも連接について調べるアプリを開発されている方がいた。連接データを得るならこちらの方が安全かもしれない。

ChatGPTを使ってみた感想

今回のテーマは(1)タイピングデータを取得・解析するアプリを作る、(2)ChatGPTを学習ツールとして試してみる、ということだった。(1)についてはとても有効であったと思う。(2)についてもう少し考えてみる。

最初はChatGPTを利用して使ったことのないプログラミング言語を学ぶというような漠然とした捉え方をしていた。ただ振り返ってみると、学ぶとはちょっと違う気がする。 プログラミングの学習は

  • プログラムの文法
  • アルゴリズムやモデル
  • コードの設計
  • ライブラリの使い方

等の項目がある。このうち、C#の文法について新たに学んだことは少なかった。これは、他の言語のfor, if文などを知っていることや、クラスの知識もあったから。クラスの設計のやり方を学ぶという点では少し参考になったかもしれない。ChatGPTに要求を伝えるとコードを示してくれるが、この例によって典型的なクラスのメンバ・メソッドの書き方を学んでいる気がする。ただ今回のChatGPTの主たる使い方は、Windowsアプリ開発用のライブラリの使い方を調べる、ということになっていたと思う。これはコードの設計とも関係するけれど、やっていることはweb検索とたいして変わらない。

学習という点でChatGPTがウェブ検索よりも優れている点の1つは言葉を教えてくれるところだと思う。プログラムにXXXをさせたいんだけど、それをどう実装すればいいかがわからないというのがよくある。ネット検索で調べる場合、キーワードがわからないとほしい情報に辿り着くのに苦労する。これは外国語で会話しているときに語彙が不足していて言葉が出てこず、全然しゃべれなくなってしまうのと似ている。ChatGPTに質問すると、キーワードを含んだ実装例を示してくれるのでとても捗る。プログラムを言語の一種であると捉えれば、大規模言語モデルのChatGPTはプログラミング言語の語彙を増やすために有用であるということだろうか。

アプリ開発でChatGPTにはとても助けられたが、一方で一筋縄ではいかないことも。

  • 何回か質問をすると、最初に前提としていた「VSCode」が無視されて、Visual Studioでのやり方を示される。これはネット上にある情報がこちらの方が多く、回答にバイアスがかかっているということだろうか?なんだかこっちの言っていることには聞く耳を持たず、「みんなやってるから」と都合良くそそのかされているような気になる。
  • GUIの実装はWindows FormとWPFという2通りの方法があり、最初WPFで作ろうとした。ChatGPTにWPFでという条件を指定しているのに、しばらくやり取りしているとそのことを忘れてWindows Formでの例を示す。これもWindows FormのほうがWEB上に情報が多いということだろうか?あまりにも煩わしくなったので、途中からWPF固執せずにどっちも混ぜこぜのコードになった。
  • ビット演算は苦手らしく、間違った演算結果を示す。"^="の意味が分からなくてChatGPTに聞くとXOR演算だとわかる。これはいいのだが、示された例の演算結果が間違っていた。これでだいぶ混乱させられた。
  • 英文の文章の各文字が登場した回数を表示させたときも間違っていた。

まあ以上の問題はフリー版を使っているのも原因かもしれない。

ChatGPTを利用した学習

ChatGPTを学習に利用すべきかという議論をしばしば耳にするが、間違いをあたかも本当のことのように説明してしまうのは困ったものだ。本当と嘘が混じっていると人は騙されやすい。こうしたツールはまだ黎明期で自分が疑いを持って使用していること、自分がある程度年齢を重ねていることから誤りに気づけていると思う(騙されていることに気づかないだけかも?)。でも、例えば小学生が学習に利用したときにこうした誤りに気づくことができるだろうか?

こういうネガティブな見方をすることができるが、一方で、AI研究で有名な東大の松尾豊教授がテレビで言っていた言葉がとても印象に残っている。

「僕が小学生なら、チャットGPTにいろんなことを聞きたい。空はなぜ青いのか。光の屈折のためだと答えてくれる。屈折とは何か教えてくれる。波長というものがあるとか、人間の目がどう色を認識するか、など広がっていく。その可能性を閉じないで欲しい。」 (Yahooニュースの記事からの引用)

確かになぁ。好奇心無限大の子供の疑問に親が答えられることには限りがある。AI技術があれば、親が教えるよりも遥かに豊かな知識を得ることができるだろう。

ChatGPTで学ぶとは?

とまぁ、こんなことを思っていると、あらためて学ぶとは何だろうかと考え始めてしまう。あっ、それ知っている、という雑学レベルの知を得るのにはChatGPTはうってつけのツールだ。質問して返ってきた文を読むというインプットをすればいい。

今回自分はChatGPTが生成するコードを継ぎはぎして欲しかった機能を持つアプリを手に入れたという感じ。 ChatGPTで学んだかと問われれば、Windowsアプリ製作を体験したとは言えるけど、これは「あっ、それ知っている」というレベルに毛が生えた程度。 理解は浅く、そのためにまだWindowsアプリを自在に作ることはできない。

プログラミングは算術と似ている。かけ算の概念は複数回の足し算としてすぐに理解できるが、それを使いこなせるようになるためには九九を覚えたり算数ドリルでの訓練が必要になる。同様にプログラミングも何度もコードを書くというアウトプットが無ければ使いこなせるようにはならない。最近見たツイートで、反復練習をすることで文法にかかる認知コストを下げることができ、そうすると脳のリソースを応用にまわせるようになる、というような趣旨の記述を見た(だいぶ勝手な解釈をしているかも)。ChatGPTは新しいことを学ぶ入り口としてはかなり良いと思うが、それだけでは深い理解はできないような気がしている。

今後さらに生成AI技術が発達していろんな場面で活用されるだろう。作文やコーディングを自分でしないのが当たり前の生成AIネイティブ世代と呼ばれる人たちがそのうち現れそうだが、生成AIを使うだけで深く理解したと錯覚してしまわないかと想像して心配になる。

もしかしたら自作キーボード界隈でときどき目にする「手を動かせ」というのがこれから重要なキーワードになるかもしれない。

あとがき

というわけでChatGPTさんのおかげで自分が欲しかった機能をもつタイピングデータ取得・解析アプリを手に入れました。まだ色々修正したい箇所はありますが、とりあえずデータの蓄積はできるのでしばらく自分のデータを取っていこうと思います。

Keybaord Input Hackathon (KIH) 2023で、データがあれば最適な配列を導けるという話(YouTubeのリンク)がちょこっとだけあった。まだ調べていないけれど、データをためて試してみたら面白そうです。

しかし、フォースカーブ測定機つくったり打鍵音録音したり、タイピング速度測ったり、なんだか自分は測定してばっかりだな…。

この記事は自作したオリジナルのキーボードunity69で書きました。