豪鬼メモ

一瞬千撃

重要英単語を自動分類して単語集を作成する

意味が似た単語はまとめて覚えた方が記憶の定着が良い。よって、重要英単語を抽出して、類似語を自動分類して単語集を作ってみた。自動分類にはk-meansというクラスタリングアルゴリズムを用いる。個々の語の特徴量は主に関連語と共起語から抽出する。
f:id:fridaynight:20220124205906p:plain


記憶は神経細胞のネットワークの産物であり、連想という行為と相性がよいそうな。よって、闇雲に無作為な語を覚えるよりは、似た語をまとめて覚えた方が効率が良い。そのためには、覚えるべき語の集合から、似た語の部分集合を抽出する必要がある。また、学習量の管理を容易にするために、個々の部分集合はだいたい同じ数の要素からなることが望ましい。そのために、単語の自動分類を行った。

結論としては、そこそこそれっぽい分類が抽出てきた。このTSVデータが結果である。いくつかを抜粋するとこんな感じだ。

  • get, take, obtain, acquire, garner, inherit, receive, borrow, poll, ...
  • serve, service, persuade, wreak, output, work, captivate, operate, ...
  • exert, use, apply, employ, misuse, application, usage, reuse, recycle, ...
  • papa, daddy, dad, father, daughter, stepmother, stepfather, stepson, ...

最重要語10000語を500クラスタに分類している。つまり、個々のクラスタには20語が収録されている。毎日3クラスタを学習して60語を習得するとして、それを167日続ければ、10000語を習得できることになる。もちろん、覚えたものはどんどん忘れていくので、定期的に復習することも必要だ。諸々を勘定して、半年くらい根気強く続ければ、10000語を習得できるという皮算用だ。

似た意味の単語が並んでいるので、それらに連続して取り組めば、学習時のストレスが少ないことが期待される。前後の語がヒントになっているので、訳語を思い出しやすい。意味だけでなく用法が似たものも並ぶので、ストーリー仕立て頭を働かせる記憶術の手法も適用しやすい。ヒントありで思い出しても意味がないと思う人もいるかもしれないが、そんなことはない。該当の記憶回路を活性化させられればそれでよい。その作業ができるだけ少ない心理的負荷で達成できるならば、学習時間が短く済む。そうすれば、気軽に取り組めるし、効率よく反復できる。

なお、100クラスタ200クラスタ400クラスタに分類するのもやってみた。個人的には500の方が使いやすいと思う。当然ながら、クラスタ数を増やした方がクラスタ内の語同士の関連性は高くなる。増やしすぎると、大きい集合が拾えなくなってしまうので、500クラスタで個々の要素を20個くらいにするのは妥当だと思う。

個々の語の特徴量を保存したのがこのTSVファイルである。任意のクラスタリングアルゴリズムを試すのにはこのデータが有用だろう。第1列が単語で、第2列が派生語の派生元で、第3列以降は特徴量ラベルとその値が交互に並べられている。私の自動分類の実装では派生語や複合語や固有名詞や機能語は取り除いている。


クラスタリングをどうやって行うかの解説をする。まず、処理対象である語の選定を行う必要がある。それには、以前の記事で述べたように、獲得年齢と頻度を使った。幼くして覚える語や文書中によく出てくる言葉は重要であり、そうでない語はあまり重要ではないと考えられる。その基準で辞書の収録語の約30万語を整列させておく。

クラスタリングの対象からは、派生語は取り除く。例えば、climaticはclimaxの派生語なので、取り除く。climaxは対象になる。climaxを単語帳に記載する際に、climactic、climaxless、anticlimactic、anticlimacticallyなどの派生語も同時に記載することになる。熟語も同じ理由で取り除く。熟語の核となる語を記載する際に、それを含む熟語も記載すればよい。

上位10000語の基本語を使ってクラスタリングを行うわけだが、その個々の語に特徴量を付与する必要がある。特徴量は、関連語と共起語と訳語から算出する。関連語はWordNetの同義語や類義語から取得し、共起語はWebコーパスにおける同文中の共起確率が高いものを取得する。この方法だと、スパースな特徴量になるので、ラベルと数値の連想配列として特徴量を表現する。それを予めTSVファイルとして保存しておく。例えば、swordの特徴量は以下のようになる。

steel=1.000, brand=0.907, blade=0.847, sword=0.828, weapon=0.790,
arm=0.735, sabre=0.525, saber=0.497, tuck=0.320, weapon system=0.292,
excalibur=0.289, cavalry sword=0.234, short sword=0.232, long sword=0.220,
剣=0.174, drawn sword=0.164, 刀=0.160, ...

クラスタリングにはk-means法をベースにしていくつかヒューリスティックを入れた実装を用いる。具体的には、以下の手順を行う。

  • 1 : 所定の数のクラスタを作り、各要素をIDの剰余で均等にクラスタに割り当てる
  • 2 : 個々のクラスタの要素の特徴量を合算し、上位100個のラベルとその値のみを抽出して重心とする。
  • 3 : 全ての要素を、自らの特徴量と最も近いクラスタに再配置する。距離にはコサイン距離を用いる。
  • 4 : 2と3を100回繰り返す。処理が遅いし次元も多いので完全に収束するのは期待しない。
  • 5 : 個々のクラスタで、各要素を重心からの距離で並び替える。
  • 6 : 個々のクラスタで、一定数以降の要素を、別クラスタの一定数以下のもので最も近いものに再配置する。

k-means法では、クラスタ内に外れ値があるとクラスタの重心が偏って精度が悪化する問題がある。外れ値の混入は避けられないので、外れ値の影響を下げたくなる。そこで、重心の計算に重み付きの平均を用いることにした。前のラウンドの重心から近い順に要素を並べて、その順位が中間以下のものは少しずつ重みが軽くなるようにした。

結果として、各クラスタが確実に同数の要素を持ち、かつクラスタの重心に近い要素同士は互いにかなり類似した内容のものになる。クラスタの重心から遠い要素同士の類似性は必ずしも高くないことにはなるが、それでも何となく共通性を感じる程度にはなっている。文字通り、全ての語を500個のスロットに分けたなら同じところに入っててもおかしくはないよね、ってくらいの納得度はある。

クラスタ内で要素を並べる際に、もうひと工夫する。まず、全ての要素を重心からの距離で並び替える。そして、自分の次の要素を、自分より下位の要素の中で、自分との距離とクラスタ重心からの距離の合算値が最も低いものに入れ替える。この連想ゲーム的なアルゴリズムによって、クラスタ内の単語の並びの全体の印象を保ちつつも、微妙に似た単語が並んで出てくるようになる。例えば、red, blue, pink, purple, orangeというクラスタがあったとする。重心に最も近いのがblueだとしたら、それが最初に来る。そして、blueは、自分に近いpurpleを隣に呼び寄せ、purpleは自分に近いredを隣に呼び寄せ、といった一連の処理を行い。結果としてblue, purple, red, pink, orangeといった並びが得られる。個々のクラスタ内でさらにクラスタリングを行うとかも考えたが、どのみち正解があってないようなものなので、適当なヒューリスティックお茶を濁す

500個のクラスタを順に学んでいくとして、クラスタ同士も似たものが並んでいた方が復習の際に楽そうだ。よって、クラスタ内の語の並び替えと同じアルゴリズムを適用した。すなわち、2番目以降のクラスタに関しては、前のクラスタに最も類似するものを選択して置くようにする。例えば、「shelter, warehouse, storehouse」のクラスタの直後に「mansion, castle, palace」のクラスタが来る。

具体的な実装のソースコードはこちらである。とりあえずPythonで書いて、遅ければC++で書き直せばいいやと思っていたが、このままでも実用になった。10000語程度であれば2時間ほどで完了する。


こんな寓話を考えた。私立k-means高校は、仲良しグループでクラス分けするという大胆な教育方針を採用している。趣味が合う生徒同士は仲良くなる可能性が高いため、各生徒には事前に趣味のリストを提出させている。結果として、サッカー好きのクラス、野球好きのクラス、音楽好きのクラスなどなどが作られる。例年問題となるのは、いわゆるサブカルな趣向を持つ生徒たちである。鉄道、銃火器、カメラ、SF、アイドルなどなど多岐にわたるが、それらの愛好者はクラスを作るほどの規模にはならないし、互いに共通の話題があるわけでもない。それでも、彼らもどこかのクラスに入れねばならない。そうして、彼らは何となく書いた読書や映画鑑賞などを根拠にして、大して気の合わないグループと強制的に組み合わされてしまうのだ。しかも、クラス定員から溢れた際には、遠いが最も近いというクラスからも切り離されて、全く共通点のないクラスに入れられてしまうことすらある。彼らはどのクラスに入れられても外れ値とみなされ、クラス全体の趣向を決める際にも彼らの趣向は無視される。そうすることで、メインカルチャーのみに着目した安定したクラス分けが実現されるのだ。

そういうわけで、クラス分けは決まったが、多くのクラスにはボッチが混じってしまっている。さて、クラスの中で、席決めを行うことになった。この高校の教室は特殊で、横一列に全員が並ぶ形状になっている。この状態でコミュニケーションを活発化させるには、気の合う生徒同士を隣接させるのがよい。クラスの中心人物ほど左に並べるという方法を採れば、少なくとも左側は活発になるだろう。しかし、右側に行くほど隣同士の共通点が乏しくなって、寒くなっていく。最も右に置かれるだろうボッチ達の寒さといったらない。しかし、ボッチはどこに置いてもボッチであり、真ん中に置くと左右のコミュニケーションを阻害する壁になってしまうので、ボッチを端に置くのは合理的とも言える。よって、基本的にはクラスの中心カーストから左に詰めつつ、その中の誰かと会話が成立しそうなボッチがいれば、適宜混ぜるということに落ち着いた。それでも右側に残る者こそ、真のボッチだ。孤高のボッチはどこにも混ぜない方がお互いに幸せになれる。文字通り比類がなく替えのきかないこのボッチたちこそ、実は重要な存在だったりもする。


そんなこんなで、それっぽい単語集ができあがった。初学者には10000語は多いと感じるかもしれないが、日常会話には十分であっても、普通に英語の新聞や小説が読みこなす程度の語彙力にはこれでも届かない。とはいえこれより多いとロングテイルの罠にハマって語彙学習がいつまでも終わらない。よって、中級者は10000語くらいを目安にするのが妥当な気がする。そしてその10000語を効率良く覚えるために、k-means法で500個のクラスタに分けた。似た単語を20個ずつ覚えるなら、短気な人でもなんとか頑張れるだろう。次回は、この分類データを使ってEPUBKindle電子書籍の単語帳を作る。