$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

BM法による文字列マッチング学習メモ

grepで文字列マッチングしている時の仕組みを学ぶために、BM法などの文字列マッチングについて調べていた。調べたことをメモしておく。特にまとまってはいない。

参考になった文献は以下。

すごく雑にイメージすると、

  • パターンの方に前処理を加えて、ある文字がパターンの中のどの位置にあるかを保存しておく
  • パターンマッチングしていきマッチしなかった場合に、前処理で作った位置情報を使っていい感じにスキップする

という感じ。雑すぎる。

BM法関連のアルゴリズムでは前処理はパターンの方に加え、検索をかける。このためSuffix Treeとか転置インデックスみたいなアルゴリズムと比べ、検索は効率が低下するものの、前処理のコストは少なくなる。そのため一回きりの検索を行うようなgrepのようなものに利用されることが多いようだった。

問題解決のための質問群を学んだ - 「考える技術・書く技術」を読んだ

最近、自分は問題をうまく分割して解決する能力や、他の人に分かりやすく伝える能力がまだ足りていないと感じていた。そのあたりを強化するために、おすすめと言われた「考える技術・書く技術」を読んだ。

この本は、わかりやすい文章を作るために、ピラミッド構造で論理構造を作るという技術を教えてくれる本だ。この本を読み終わって、ピラミッド構造を作るという考え方は、問題を分割するということにも、文章を他の人に伝わるように分かりやすく書くということにも応用できる、非常に有用な考え方であると感じた。



まず最初にぱらぱら読んでいた感想は、非常に良いことが書かれてそうなのだけど、なぜか頭に入ってこないということだった。このためあまり面白くないなと思いながら、気になるところを付箋はったりメモしたりしながら読んでいた。

読み終わった後、気になるところメモをまとめなおしてみたら、読書メモが思ったよりも膨大になった。読書メモが膨大になる = 学ぶことが多かったということなので、これを見て、結果的に良い本だったのだなと思った。

この経験から、この本はいい本なのだけど頭に入ってこないこともあるので、最初は頭に入ってこないのを無視してメモしながら読み進めて、後からそれをまとめるという使い方をすると良さそうだと思った。



さて、この本で一番印象に残ったのは、「問題解決の技術」の章の、問題解決は以下の質問群に対して答えを見つけるという作業であると書かれていた部分だ。問題解決には、問題定義・原因の発見・解決の発見という三つのステップがあり、以下の質問に答えていくことでそのステップを自然になぞっていくことができる。

  • (1) 問題がありそうか、もしくは改善の機会がありそうか(問題定義)
  • (2) 問題はどこにあるのか(問題定義)
  • (3) 問題はなぜ存在するのか(原因の発見)
  • (4) 問題に対し何ができるか(解決の発見)
  • (5) 問題に対し何をすべきか(解決の発見)

この質問を意識しておくと、表面的な問題に囚われず問題の本質を正しく理解することができ、しかも解決手法の中で効果的なものだけ行うという取捨選択も正しくできそうである。

こういう手順を踏まない場合、よくやってしまいがちな失敗がある。それは「問題を発見したと感じる」 -> 「とりあえずこの解決策が効きそうだからやってみよう」という解決手順を行い、問題の本質を捉えていないために全く解決されないということだ。しかも、最悪な場合、やってみたことが正しいんだと自分に思い込ませたくて、そのやり方をずっとやり続けてしまう場合すらある。

問題解決の質問が具体的にあると、自分が問題を発見した時のやり方を定式化できる。そこで、今後は問題を発見したら順にこの質問を辿っていき、上記のよくやってしまいがちな失敗を起こさないようにしていきたい。



問題解決の技術以外にも、書く技術に関して有用なトピックが含まれているように感じた。しかし、自分の経験不足もあってか、まだ言語化できるほど理解が深まっていないと感じた。そこで、この後はこの本のワークブックというのをやってみてから、また自分の理解をブログに書きたいと思う。

読書メモ

書く技術

  • 自分の考えをピラミッド型に構成し、それをそのルールに従ってチェックすることで分かりやすい文書が書けるようになる ⅰ
  • 読み手にとって最もわかりやすいのは、まず主たる大きな考えを受け取り、そのあとにその大きな考えを構成する小さな考えを受け取るという並べ方 3
  • 主たる考えをまず述べ、読み手になぜそういう考えになるか疑問を持たせ、そこでピラミッドを一段下りて疑問に答える 4
  • 頭のなかでは、情報は自動的にいくつかのピラミッドグループに並び替えながら理解するので、伝えるべき考えを事前にピラミッド型に構成したほうが理解しやすい 5
  • マジックナンバー7でストップする。人間の頭は7つしか覚えられない。箇条書きで7つ以上となったら疑え 7
  • 最も分かりやすい順序は、全体を要約する考えを述べ、その後に個々の考えをひとつひとつ説明していくこと 10
  • ひとつの段落にまとめるなら、ひとつの要約文として表現できるはず 14
  • 正しいピラミッド型になっているか 15 ☆
    • どのレベルであれ、メッセージはその下位グループ群を要約するものであること
    • 各グループ内のメッセージは、常に同じ種類のものであること
    • 各グループ内のメッセージは、常に論理的に順序付けられていること
  • 論理的な並べ方には4つしかない 17 ☆
    • 演繹の順序(大前提、小前提、結論)
    • 時間の順序(1番目、2番目、3番目)
    • 構造の順序(北から南、東から西、等)
    • 比較の順序(1番重要、2番目に重要)
  • 自分の考えをピラミッド型に素早くまとめるための構造フレーム 19
    • 主ポイントと補助ポイント間の縦の関係(多分ピラミッドの縦)
    • 補助ポイント同士の横の関係(ピラミッドの横)
    • 導入部のストーリー展開(大前提)
  • 縦の関係を通して、Q&Aの対話形式で答えを出していくと、興味を引きつけられる 20
    • ピラミッド構造の図 22、23
  • トップダウン型のアプローチでのピラミッド構成手順 30 ☆
    • 分かりやすい図表は31
    • 1. 箱を一つ書き、その中に伝えようとする主題を入れる
    • 2. 主題に対しての疑問を書く
    • 3. 疑問に対しての答えを書く
    • 4. 主題に対する状況を明確にする
    • 5. 複雑化へ発展させる(???) -> これよく分からん
    • 6. 疑問と答えを再チェックする
  • ボトムアップ型でのピラミッド構成ステップ 37 ☆
    • 1. 言いたいポイントをすべてリストアップする
    • 2. ポイント同士にどんな関係があるか考える
    • 3. そこで結論を導く
    • こっちのほうがしっくりくる
  • 導入部には以下をストーリ形式で 47
    • 状況を記述し、その中で発生する複雑化を記述し、それから生じる疑問を記述する
    • そしてその疑問に対し、答えを与える。
  • 読み手の疑問の共通パターン 67
    • 1. 我々は何をすべきか?
    • 2. 我々はそれをどのように実行すべきか?
    • 3. 我々はそれを実行すべきか?
    • 4. なぜそのようなことが起きたのか?

考える技術

  • グループ分けの分析活動は3つだけ 106、図表23 ☆
    • ある結果の原因を特定する
    • 全体を部分に分ける
    • 類似のもので分類する
  • グループ化の種類を文章の順序に反映する 107
    • 結果と原因なら時間の順序
    • 全体を部分に分けるなら、構造の順序
    • 類似の分類なら、重要度の順序

問題解決の技術

  • 「問題」とは、自分がある結果(R1)を好ましいと思っておらず、他の結果(R2)がほしいということ。「解決」とはR1からR2にどうやって到達できるかを考え実行すること 171
  • 問題解決は以下の質問群に対して答えを見つけるという作業 171 ☆
    • 1. 問題がありそうか、もしくは改善の機会がありそうか(問題定義)
    • 2. 問題はどこにあるのか(問題定義)
    • 3. 問題はなぜ存在するのか(原因の発見)
    • 4. 問題に対し何ができるか(解決の発見)
    • 5. 問題に対し何をすべきか(解決の発見)
  • 「問題」とは、現在の結果と期待していたことの間のギャップ 174
  • 問題を定義するには、以下の三つの質問に答える 174
    • 今何が起きているのか
    • 今の何が好ましくないのか
    • 代わりに何を望んでいるのか

表現の技術

  • 見出しはピラミッド内の考えのグループ化を反映しなければならない 237
  • ヒエラルキー型見出しの注意点 238
    • それぞれのレベルで、見出しがひとつだけで終わってはならない
    • 類似の考えはパラレルに表現する
    • 見出しは、考えの本質を表現するに留め、完結にする
    • 見出しを文脈の一部としない
    • 見出しの各グループを事前に紹介する

その他

  • 本書で述べた重要ポイントの一覧 279

ゴールを決め目標を決める・解決案ではなく質問する - コーチングの学習で学んだこと

半年前から会社でシニアエンジニアという役職で、エンジニアのメンターの役割を担っている。その役割を出来るだけうまく演じられるように、半年間はコーチングの学習を進めてきた。

また、半年間、目標・1on1・評価と一通りの業務をこなし、コーチングの実践が出来た。

そこで今回はコーチングの学習と一通りの実践を通して学んだことで、特に役に立ったと思うことについて一旦まとめてみる。特に役に立ったと思った知識は以下の二つである。

  • ゴールを決め、現在位置とのギャップを考え、目標を決める
  • 解決案を与えるのではなく質問する

ゴールを決め、現在位置とのギャップを考え、目標を決める

初めて自分がメンターしている人(メンティー)の目標設定をするにあたり、どのように目標設定をすればよいか悩んでいた。その答えとして、僕は「ザ・コーチ」に書かれていた内容がしっくり来ている。それは、「ゴールを決め、現在位置とのギャップを考え、目標を決める」ということだ。


目標設定する時、まずはメンティーが思うゴールを決めることから始める。ゴールとは、今目指したい場所だ。ゴールは非常に長い目線で考えても良いし、長い目線が難しかったら短くとっても良い。例えばエンジニアであれば、

  • 5年後にこのエンジニアのようになりたい
  • 3年後にチームのエンジニアをまとめる役割につきたい
  • 1年後に機械学習を使った仕事をしていたい

などと言ったことが考えられる。

次にメンティーの現在位置とのギャップを考える。例えば「1年後に機械学習を使った仕事をしていたい」を例にギャップを考えてみると

  • 自身の機械学習の知識を発揮するための最低限のアプリケーション構築能力がない
  • 課題を解決するための一つの手段に機械学習を使えることを上司にうまくアピール出来ていない
  • 機械学習の基礎知識はあるが、今担当しているサービスに適応できそうな応用技術の学習が進んでいない

などといったことが考えられるかもしれない。

最後に目標を決める。目標は、現在位置からゴールに向かうための1ステップと考える。そうすると、先程のギャップからピックアップして、それを目標にしたら良い。例えば先程の例で、今年は「自身の機械学習の知識を発揮するための最低限のアプリケーション構築能力がない」「課題を解決するための一つの手段に機械学習を使えることを上司にうまくアピール出来ていない」をなんとかしたいと思ったら

  • 1つの機能を上から下まで(裏側よりからフロントエンドまで)自分一人で作れるようにする
  • 機械学習というエンジニアリング分野を、それを知らない人にも分かるよう説明できる能力を付ける

などといったことが考えられる。

「ゴールを決め、現在位置とのギャップを考え、目標を決める」のイメージは以下の通り。

f:id:shiba_yu36:20161023134206j:plain


このように、「ゴールを決め、現在位置とのギャップを考え、目標を決める」としていくことで、目標は何のためのものかを意識しながら立てることができる。目標がなんのためかはっきりしていれば、それを達成しようというモチベーションも保てる。これにより、実現可能であり、納得できて、ゴールに向かって効率的である良い目標を立てることができると考えている。

この内容は 目標設定の仕方を学ぶ - 「ザ・コーチ」読んだ - $shibayu36->blog; にも詳しく書いているので、こちらも参考に。

解決案を与えるのではなく質問する

もう一つ1on1に役に立ったと思うことは、「解決案を与えるのではなく質問する」というコーチングの考え方だ。1on1でメンティーから相談を受けた時などに効果的に利用できる。

どういうことかというと、メンティーから相談された時に、自分の経験からすぐに答えを教えてあげるのではなく、その相談について質問をしていき、メンティー自身に解決案を思いついてもらうという方法を取ったほうが良いということだ。

例えば、チームでコミュニケーションがうまくいっていないと相談されたとする。この時、こうやってコミュニケーションしたら良いよとすぐに教えるのではなく、質問をして掘り下げていく。質問としては以下のようなものがありうるだろう。

  • コミュニケーションがうまくいっていないことで、どういう問題が起きているのか
  • 何が原因で、コミュニケーションがうまくいっていないと感じるか
  • 自分の思う理想的なチームコミュニケーションの状態はどういうものか
  • 現在でもうまくいっているコミュニケーションはあるか
  • 理想的なチームコミュニケーションにするためにどうしたら良いか

このような質問を繰り返していくと、メンティーの頭の中が整理されていって、メンティー自身が「こうしたらいいんですね」と気づいてくれるということが多い。


個人的にこのやり方は非常に効果的であったと感じる。なぜなら

  • 1. メンティー自身が自分よりその問題について詳しく、精度の高い解決策を思いつくため
  • 2. 自分の専門外のことでも解決案を得られるため
  • 3. 自分で気づくと実行するモチベーションが上がるため

まず1つ目について。1on1をしていると、自分の昔の状況と、メンティーの今の状況は違うことが多い。そのため、自分でアドバイスしても、それが効果的でないこともある。それよりメンティーに今の状況を鑑みて、自分で解決案を思いついてもらったほうが今の課題に対する解決案の精度が高い。

2つ目について。アドバイスをするということは、自分がそのことについて知っていなければいけない。しかし、知識の幅は膨大であり、全ての相談について自分が知識を持っているとは限らない。特にエンジニアにとって、裏側よりのエンジニアがフロントエンドのことを聞かれても答えられないということが多い。しかし、その場合でも、質問してメンティーに考えてもらうことで、解決案を得られることがある。

3つ目について。誰かに指摘されても、特に実行するモチベーションが湧かないということはよくあると思う。これは指摘されたことが自分の中で納得できていない時によく起こる。しかし、自分で解決案を思いついたときは、その段階で自分は納得できている。そのため、その解決案を実行するモチベーションを持てるようになる。

以上3点において、1on1では「解決案を与えるのではなく質問する」ということが効果的であると思った。

まとめ

今回はこれまでのコーチングの学習と、半年間の目標設定・1on1・評価の経験から、自分自身が特に役に立った二つのことについてまとめてみた。メンターを始める時に、まず手始めにコーチングを勉強したことは非常に良かったと感じる。

まだまだ自分自身がシニアエンジニアとしては未熟なところが多い。これからもどんどん学習していきたいと思う。エンジニアリングとマネジメント両方の勉強をしようとすると時間が足りないという課題を最近感じるけど、まあこれは頑張っていくしかないと思っている。

他にコーチングの話は過去のブログにも書いたので、こちらも参考に。