初心者データサイエンティストの備忘録

調べたことは全部ここに書いて自分の辞書を作る

【読書記録】なぜ「つい買ってしまう」のか?ー「人を動かす隠れた心理」の見つけ方ー

ヒット本でした。

マーケティング業界では、よく「顧客目線で考える」とか「顧客が求めていることを知るべき」と言われることがあります。しかし、実際の業務においては、顧客目線で考えることは困難です。その理由の一つに顧客目線で考えるためのとっかかりが見つからないということがあります。

そんな状況の中で、株式会社デコムは顧客が持つ「人を動かす隠れた心理」を見つけ、マーケティングに活用しているようです。本書は、その「人を動かす隠れた心理」を見つけるためのデコム流の方法論が惜しげもなく紹介されています。

※本記事は自分が後から見直して活用できるように、論点をあまり絞らずダラダラ書いています。 一言書評を知りたい方は読書メータをご覧ください。

bookmeter.com

「人を動かす心理」を見つけなければならない理由

サービスの存在意義の一つに、消費者の不満解消があると思います。この不満に気付けるかがサービス開発に重要なのですが、顧客からアンケートなどを取っても、なかなかイノベーションを起こせるような不満に出会うことはできません。 本書では、スマートロックを例にして次のように説明されています。

大事なのは「何かお困り事はありますか?」と聞いて「カバンから鍵をいちいち取り出すのが面倒」「財布から小銭をチマチマ出すのが面倒」と答える人はいない、ということです。もともとそうした不満はあるのに、なぜか気付けないのです。

不満を解消したいのに、肝心の不満を見つけることができないということがマーケティングの難しさの一つだと思います。

本書の構成

本書の構成について、図1にまとめました。「数値A-(数値B)」となっているのは、数値Aの章の数値Bの節にその内容が書いてあるという意味です。また、図中の用語(「インサイト」など)についてはこの後で説明していきます。

図1:本書の構成

図1中の矢印、A→Bの意味は、「良いAが良いBを生み出す」です。つまり、良い新奇事象と良い価値年表が良いオポチュニティを生み出し、良いオポチュニティが良い価値事象を生み出し...とつながっていきます。

この後は、各用語の意味を説明していきます。

新奇事象

図2:新奇事象のsummary

図2に新規事象のsumamryを記載しました。下記で補足していきます。

定義

新奇事象を収集する上でのポイントは、ユニークな行動を収集することです。本書には、顧客視点で物事を考える際には違和感を持ったポイントを抑えると良いという主張があります。その点、新奇事象は違和感の塊なので、違和感を通じて価値を発見しやすいという利点があります。

関連するフォーマット

新奇事象に関連するフォーマットを4個挙げました。

  • 生活14カテゴリ
    生活14カテゴリとは、図3のように人間の興味・関心を14個のカテゴリに分けたものです。人々の興味・関心はこの14カテゴリに収まるだろうというのがデコムの考え方です。 このカテゴリを使うことで、自社が提供している価値以外の価値に、価値を感じているユーザを探すことに役立ちます。ここで探した自社が提供している価値以外の価値を感じている新奇事象を収集することが、新規顧客開拓に役立ちます。

図3:生活14カテゴリ

  • LIV
    Layer+Issue+Valueの略です。意味と例を下記にまとめました。本書ではデパートを例にしています。
項目 説明
Layer ブランドを抽象・概念化したカテゴリ 日帰り旅行
Issue ブランドが抱える課題 若年層の利用が少ない
Value ブランドの価値 自分をラグジュアリーな存在だと錯覚させる空間、人

これらを整理することで、例えばデパートであれば日帰り旅行が好きな若年層を新規顧客のターゲットとする発想が浮かびます。

  • 事象を表すためのタイトル+事象の世界観を表す画像+事象内容+個人のデモグラ
    これは収集した新奇事象を整理するためのフォーマットです。図4に例を記載します。

図4:新奇事象のまとめ方

  • 新奇事象から意味を抽出するための質問群
    これが一番大切です。というのも、新奇事象から消費者が満たされていない不満や、消費者が感じる価値を見つけることで、次のオポチュニティにつなげるからです。本書では、この質問群は次のようにまとめられています。

①自社ブランド/当該カテゴリが提供していない価値領域がありそうな行動を起こしているか?
②自社ビジネスで解決できそうか?
③人間の潜在的な不満、満足、未充足が隠れているか?

この質問群に答えることによって、新奇事象から消費者が感じている不満・価値を炙りだしていきます。

図4に記載した新奇事象を基に、上記の質問群に答えてみます。

①自社ブランド/当該カテゴリが提供していない価値領域がありそうな行動を起こしているか?
弊社で提供しているサブスクサービスは、クーポンや書籍などのエンタメ作品を提供しています。それに対して、図4の新奇事象では「巫女装束」というモノを通じて、男性はリラックスしています。また、本物の巫女装束というのもポイントで、弊社で提供しているある意味バーチャルな経験ができるエンタメとは異なるところに価値があります。 そのため、この質問に対する答えを「本物の巫女装束を着ることでリラックスできる。巫女装束はスイッチをOFFするための道具」としようと思います。

②自社ビジネスで解決できそうか?
弊社で提供しているサブスクサービスを通じて、どうすればリラックスタイムを提供できるか考えてみます。 ポイントの一つは、本物のモノを通じてリラックスすることにあるのでコーヒーやお酒など嗜好品の通販クーポンなどが思い浮かびます。 また、エンタメサービスはもともとリラックスタイムを提供できるサービスだと思います。 そこで、自社ビジネスでは「家にコーヒーやお酒などの嗜好品を届けるサービスのクーポン券とエンタメサービスを抱き合わせてユーザに提案する」などが考えられます。

③人間の潜在的な不満、満足、未充足が隠れているか?
今回の場合は、介護という仕事からくるストレスが不満にあたると思います。

おまけ

ここでは、新奇事象を考える上での注意点を2点説明します。

  • 注意点1:既存価値年表の枠外は全て受け入れる
    既存価値年表については、この後詳しく説明しますが、要するに過去に自社ブランド、もしくは自社ブランドが所属するカテゴリが提供してきた価値を年表にしたものです。この既存価値年表に載っている価値以外の価値は全て新しい価値です。新奇事象から価値を抽出する段階では、この新しい価値を全て受け入れて、この後の作業で取捨選択していけば良いと本書に書いてあります。

  • 注意点2:エンジェルインサイトとデビルインサイトの両面を理解する
    人間の欲望には、良い面と悪い面と両方あります。本書では、欲望の良い面と悪い面について以下のように指摘しています。

優れたアイデアやクリエイティブは、エンジェルインサイトとデビルインサイトの双方を押さえていると言えるでしょう。(中略) エンジェルインサイトとデビルインサイトのどちらか片方のみで成り立つアイデアは、成功する可能性が極めて低いと考えています。

デコムはエンジェルインサイトとデビルインサイトをまとめた欲望マンダラを作成しているようです。

図5:欲望マンダラ

既存価値年表

図6:既存価値のsummary

図6に既存価値年表のsumamryを記載しました。下記で補足していきます。

定義

既存価値年表を作成する目的は、サービスを開発するメンバー間で既に提供してきた価値を共有することです。これにより、新奇事象で抽出した価値を既に提供してしまったものなのか、まだ未提供なのかを判別することができます。

関連フォーマット・例

縦軸にPEST、データ、価値定義、4P、3CのうちのCustomerを並べ、横軸に年代を並べます。年代は10年ごとくらいがちょうどよいとのことです。*1

図7は、本書記載の居酒屋チェーンの既存価値年表です。

図7:居酒屋チェーンの既存価値年表

おまけ

  • 「事象→価値」のルールで矢印が書かれている
    既存価値年表中では、発生した事象がどのような価値を生み出したかを矢印で表現します。この矢印を書いておくことで、新奇事象がどのような価値を生み出すかの参考になるのではないかと私は考えています。

  • 2~3年は続いた価値を記載する
    あまりにも短い価値は「一発屋」で定着しなかったとして既存価値年表に載せる必要はないとのことでした。あくまでトレンドを捉えることが重要とのことです。

  • CMを参考にすると良い
    過去のCMには、そのサービスが提供・訴求しようとした価値が詰め込まれています。なので、Youtube等に載っているCMを見て、既存価値年表作成に役立てると良いそうです。

オポチュニティ

図8:オポチュニティ

定義

オポチュニティの定義のポイントは、「十分に充たされていない」「新しい価値」「仮説」の3つだと私は考えています。

十分に充たされていないから、新しくサービスを提供する、新しい価値としてサービスを訴求することに意味があるということが考えられます。
また、既存の価値ではなく新しい価値だからこそ(二番煎じでないからこそ)、集客力があると考えられます。
最後に仮説についてですが、オポチュニティはあくまで「この価値は十分に充たされてないだろう」と帰納的に導き出された価値です。なので、テストマーケティングなどを実施し、正しいかどうかを検証する必要があります。

関連するフォーマット・例

デコムが開発したフォーマットを図9に載せます。記載内容は海外旅行に関するものです。

図9:海外旅行のオポチュニティ例

フォーマット内の「気づき」は新奇事象に触れて得られた気づきです。また、この後作られるインサイトから生み出すアイデアについても、オポチュニティを整理しだしたくらいから考え始めるべきなのだと思います。それがこのフォーマットに「新路線の例えばアイデア」が載っている理由だと考えています。

価値事象

定義

ここまでも少し触れてきましたが、顧客の不満を炙りだすことがインサイト発見には必要です。本書では、不満を炙りだすためのテクニックとして、価値に照らし合わせて顧客調査することが提案されています。

例えば、缶コーヒーに「部下とコミュニケーションをとるきっかけを作ってくれる」という価値を見つけたとします。このとき、顧客には「部下とコミュニケーションを取るために缶コーヒーを購入するあなたにとって、缶コーヒーの不満は?」と質問するのです。そうすることで、具体的な不満、例えば「5、6人で休憩したいときには向いていない」などを炙りだせるとのことです。私としては、実際にはこんなにうまくいくことは少ないかもしれませんが、納得感はあるなと思いました。

以上のような顧客調査をするためには、オポチュニティ作成の際に手に入れた「新しい価値」を感じているユーザを集めてきて不満を聞く必要があります。この、新しい価値を感じている顧客の行動を「価値事象」と本書では定義されています。

関連するフォーマット・例

シーン・ドライバー・エモーション・バックグラウンドの4点をセットにして価値事象を整理します。これにより、客観的事実であるシーン・ドライバー・バックグラウンドと、主観的事実であるエモーションをセットにして整理することができます。

インサイトが「隠れた心理」である以上、主観的事実であるエモーションが一番重要なのではないかと私は考えています。 図10に本書記載の例を載せておきます。

図10:居酒屋の価値事象例

おまけ

価値事象も顧客調査等で集めてくる事象です。これについて、新奇事象のための顧客調査と混乱してしまったのですが、目的が異なります。 新奇事象のための顧客調査の目的は、ユニークな行動を集めることで、その人しか感じていない価値を探すことです。一方で、価値事象は新奇事象から抽出した価値を感じている人を集めてきて、サービスへの不満を炙りだすことにあります。関係性を図11にまとめました。

図11:顧客調査

インサイト

図12:インサイトのsummary

定義

インサイトとは「人を動かす隠れた心理」のことです。本書では、インサイトが次の様に説明されています。

この書籍ではインサイトを「人を動かす隠れた心理」と定義します。
ポイントが2つあります。1つ目は「隠れている」点、2つ目は「動かす」点です。
隠れていなければ、つまり露出していれば、それは単なる「ニーズ」に過ぎません。(中略)隠れているからこそ、「何かお困りごとはありますか?」と聞いても分からないのです。
また、人が動かなければ、残念ながらビジネスには使えません。最終的には消費者に商品・サービスを購入してもらわなければならないので、人が動かない心理を発見しても仕方がないのです。

関連するフォーマット・例

価値事象の分析結果を基に不満を炙りだします。そのためのフォーマットが図13です。

図13:居酒屋チェーンのインサイト

おまけ

インサイトは「隠れた心理」である以上、エモーション(情緒)までしっかり考えきることが重要です。むしろ、情緒までしっかり考えきれていないと意味がないと言えます。

イデア

図14:アイデアのsummary

定義

ここまで整理してきたインサイトによって、消費者の不満を掴むことはできました。なので、今度はその不満を解消するためにサービスを開発しなければなりません。ここでは、一般的なアイデアという言葉の意味を狭めて「消費者の不満を解消するための提案」としています。

関連するフォーマット・例

インサイトを一言でまとめたものと、それに対する提案(=バリュープロポジション)をセットにしてアイデアを出していきます。

図15:バリュープロポジション

おまけ

本書で著者はアイデアについて以下の様に述べています*2

『アイデアのつくりかた』を読めば誰もが簡単にアイデアを大量生産できるかと問われれば、私は首をかしげます。万人ではないよなぁ......という感想を抱いているからです。どうすれば閃くのか、なぜ閃くのかが上手く説明できていません。「ある日突然閃く」というくだりが、どうしても個人の感覚や感性、偶然に依存しているように思えるのです。

つまり、『アイデアのつくりかた』を読んだところで、アイデアを生み出すことは一部の天才にしかできないというわけです。しかし、インサイトが手に入っていればアイデアを生み出すことは大分難易度が下がります。

最後に

本書は「顧客視点で考える」方法について述べた本です。本書を実践することで、マーケティング力の向上が見込めます。一方で、自分が所属している会社の場合そのまま本書の内容を活かすことは難しいぞという感覚があります。 今思いつく範囲でその理由を考えてみると、主に3点あります。

  • 既に引いてある分析スケジュールや分析内容と合わない
  • 顧客調査できない
  • イノベーションを起こそうという気がなく、小さな改善しかできない

これらの課題は一朝一夕に解決できるものではありません。なので、明日から私が取り組むべきことは、これらの課題と共存させる方法を考えることです。 本書で学んだことが業務に活かせるよう頑張っていきたいと思います。

*1:PESTとは、Political(政治的)、Economic(経済的)、Social(社会的)、Technological(技術的)の頭文字です。

*2:引用中の『アイデアのつくりかた』は ja.wikipedia.org のこと

bubbleチュートリアル1

ノーコードツールbubbleの勉強を始めた。 自分の備忘録のため、チュートリアルの解説記事を書こうと思う。

作成するもの

今回作成するものは、Google Mapに住所を入れるとピンを打ってくれるアプリ。

図1:作成するアプリの画面遷移イメージ

各部品の解説

「bubble チュートリアル」で調べると、チュートリアルの解説記事はたくさんみつかる。しかし、各部品の設定の仕方がイマイチよくわからなかった。 そこで、ここでは各部品の設定の仕方でわかったことを書いていく。

図2:searchbox

Searchboxと呼ばれる部品についてのメモ。各部品の編集画面(?)を開くと、上からPlaceholder、Choices style...と色々な設定項目が出てくる。*1

各項目の意味を図3にまとめた。

図3:searchboxの設定

Visual elements -> Button

Buttonについてのメモ。

図4:buttonの各項目の意味

workflow

図4内の「Start/Edit workflow」をクリックするとボタンを押したときの動作(=ワークフロー)を設定できる。 ここでは、下記のワークフローを設定する。

  1. Searchbox内に書かれた住所をデータフレームに保存する
  2. Searchbox内に書かれた住所を消す

ワークフロー全体の設定

上記で書いたワークフローを設定するため、ワークフロー全体の設定を行う(図5)。

図5:ワークフロー全体の設定方法

Searchbox内に書かれた住所をデータフレームに保存する

まずは、住所を保存するためのデータフレームを作成する。

図6:データフレームを作成

次に、searchbox内に入力された値をデータフレーム(=先ほど作成したLocation)に入れるための処理を設定する。

図7:searchbox内に記入された値をデータフレームLocationに入れる

Searchbox内に書かれた住所を消す

次に、Searchbox内に書かれた住所を消す操作をワークフローに組み込む。

図8:searchbox内の値を消す

Visual elements -> Map

次に地図を設定する。Visual elements内のMapを選択する。ここでは、下記の設定をする。

図9:mapの設定

図10:Data Sourceの設定

Google API

ここまで設定して、Previewを押したがエラーを吐いてしまった。どうもGoogle APIの設定ができていないらしい。 そこで、下記の記事を参考にしてGoogle APIを設定したらアプリが動くようになった*2

blog.nocodelab.jp

おまけ

ここまでで、地図上に入力した住所のピンを立てられるようになった。チュートリアル自体はここで終了だが、私は全てのピンを消してやり直すボタンを作成したくなった。

そこで、Buttonをもう一個作成し、下記の設定を行った。

図11:おまけのbutton設定

図12:おまけのworkflow設定

これで、全てのピンを消して最初からやり直すこともできるようになった。

*1:編集画面は、各部品を左クリックして一番上の「Edit」を選択すると出てくる

*2:APIのことはよくわかっていない...

オブジェクト指向設計実践ガイド【第4章】まとめ

オブジェクト指向の設計方法を学んでいる。 今回は、「オブジェクト指向設計実践ガイド」の「第4章:柔軟なインターフェースをつくる」を読んだ。 なお、使用する言語はPython

(過去記事)

aisinkakura-datascientist.hatenablog.com

aisinkakura-datascientist.hatenablog.com

aisinkakura-datascientist.hatenablog.com

4.1 インターフェースを理解する

この節に書いてあることは、クラス間で任意のメッセージをお互いに送れるようにするなということ。クラス間で送れるメッセージを制限し、クラスが外部に晒すメソッドやアトリビュートと内部でしか利用しないものとをしっかり分けておくべき、と書かれている。

4.2 インターフェースを理解する

クラス内のメソッドやアトリビュートのうち、外部から使われることを想定されているものはパブリックインターフェースと呼ばれる。また、パブリックインターフェース以外のメソッドやアトリビュートをプライベートインターフェースと呼ぶ。

パブリック・プライベートインタフェースの特徴は以下の通りである。

パブリック プライベート
クラスの責任を表す 実装の詳細に関わる
クラスの外から利用される クラスの中でしか使われない
気まぐれに変更されない 変更しても大丈夫
他のクラスがそこに依存しても安全 他の」クラスがそこに依存したら危険
テストで完全に文章化されている テストでは実行されないこともある

なお、Pythonの場合アンダーバー(_)が先頭に2個並んだメソッド・アトリビュートはプライベートとなる。 下記スクリプトを見ると、__をつけたprivateなメソッドの外からの実行や、アトリビュートを外から呼び出そうとするとエラーを出力してしまうことがわかる。

4.3 パブリックインターフェースを見つける

本書では、シーケンス図を用いてパブリックインターフェースを見つける方法が推奨されている。シーケンス図を用いることでクラス間のメッセージを明確にできるからだ。

ここで、ちょっとシーケンス図について説明したい。上記で述べたようにシーケンス図には、「メッセージ」という概念がある。例えば、「クラスAがクラスBにfというメッセージを送る」とは、「AがBのfメソッドを呼び出す」という意味である。

これをシーケンス図にしたのが図1である。

図1:シーケンス図とメッセージ

また、図1のシーケンス図をスクリプトにすると下記のようになる。

スクリプトを見るとわかるが、シーケンス図上で左にあるクラス(今回はclass A)は、右にあるクラス(今回はclass B)のインスタンスを持つことになる。私自身は、このメッセージとスクリプトの関係性がよくわからず理解に時間がかかってしまった。

この後は本書記載の図4.5~図4.8を実際にスクリプトに落とし込んでいこうと思う。

図4.5のスクリプト

図4.5は比較的単純である。イメージとしては、Tripクラスが自転車の用意の仕方まで完璧に把握していて、Mechanicクラスに手取り足取り指示しているイメージである。

図4.6のスクリプト

図4.5だと、Tripクラスが自転車の用意の細かい手順まで把握していないといけない。したがって、自転車の準備の仕方が変更になった場合、MechanicクラスだけではなくTripクラスにも変更が生じる。 これは良くないということで、Mechanicクラスに「自転車を準備しろ!」と命令を出せば、自転車の準備の各作業はMechanicがやってくれるようにしたのが、図4.6である。

図4.7のスクリプト

図4.6でMechanicに自転車の細かい準備をすることを任せることができた。しかし、依然としてTripは自転車を用意する命令を出す必要がある。これをただ単に旅行の準備をする命令に変えたい。その理由としては、Tripが必要な旅行の準備が自転車の準備ではなくなってしまった場合や、自転車の準備以外もしなければいけなくなったときのために拡張しやすくするためである。ここでのポイントは、Tripは自分の情報を全てMechanicに提供し、Mechanicはその中から必要な情報だけを取得してよしなにやる状態を目指すことである。

図4.8のスクリプト

図4.8はCustomerクラスとTripクラスの間にTripFinderクラスを入れて、旅行の依頼、旅行の準備、条件に合う旅行を見つける役割を全て分解した。

4.4 一番良い面(インターフェース)を表に出すコードを書く

本節に書いてあることは、ここまでのまとめである。重要なことは3点と考えた。

  • パブリック・プライベートインターフェースが明示的にわかるように/_をつけたり、命名規則を作るなどすべき
  • 過去に作成されたコードのプライベートインターフェースを外のクラスから使うようなことがあってはならない。使わざるを得ないときも、徹底的に代案を考える
  • パブリックインターフェースを作る際は、メッセージを送信するクラスが「どのように」ではなく「何を」要求しているのかを意識する

デメテルの法則

デメテルの法則は、クラス間をつなぐドットは一つだけにしようという法則である。 例えば、コード中に下記のようなスクリプトが出てきたら、デメテルの法則違反である。

trip.mechanic.prepare_bicycle

このようなスクリプトが良くない理由、下記2点によるものである。

  • 変更に弱い
  • 再利用しにくい

1点目の「変更に弱い」について。上記のスクリプトがずっと使えるためには、mechanicとprepare_bicycleの名前が変わらない必要がある。逆に言えば、mechanicとprepare_bicycleの片方でも名前が変われば、このスクリプトをは動かなくなる。そのため、変更に弱い。

2点目の「再利用しにくい」について。上記のようなスクリプトは、「tripがmechanicを持っている」「mechanicがprepare_bicycleを持っている」こと2点を要求している。したがって、tripを再利用しようとしたら、mechanicとmechanicが持つprepare_bicycleも併せて再利用する必要がある。これはしんどい。

以上のことから、ドットは一つにすべきというのが「デメテルの法則」である。なお、変更がほとんど生じないであろうオブジェクトやメソッドに依存する場合(基幹的なパッケージなど)は、多少デメテルの法則を違反しても良いと本書には書いてあった。

まとめ

本章の学びは以下の通り。

  • パブリック・プライベートインターフェースを明示的に分けるべき
  • パブリックインターフェースは変更が少ないインターフェースであるべき
  • パブリックインターフェースを利用するクラスは、「どのように」ではなく「何を」要求しているかを意識し、その「何を」に応えられるようなインターフェースを作るべき
  • デメテルの法則は、ドットを2つ以上使わないという法則。デメテルの法則に違反すると「変更に弱い」「再利用しにくい」という課題が生じる

【読書記録】図解論語

論語と算盤」を読み論語の原典を読んでみたいと思うようになりました。しかし、原典を読んで砕けるのも嫌で、ついつい解説本から読んでしまいました。

論語と算盤についての記事はこちら) aisinkakura-datascientist.hatenablog.com

本書は明治大学教授の齋藤孝による、論語の解説書です。正確には論語の言葉を基に、齋藤の考えが書かれた本です。 したがって、論語そのものを学びたい人には向いていません。また、齋藤の考え方に納得できない人にとっては面白くない本だと思います。実際、私も「この考え方は正しくないだろう!」と思う箇所もありました。 その一方で「なるほど!」と思うことも多々あったため、書評を書いて自分の血肉にしたいと思います。

知者と仁者

知者と仁者は人の気質を表す言葉だそうです。知者は行動量が多く、たくさん働く人を指します。一方で、仁者は落ち着いており、ゆったりした人を指します。

知者と仁者はどちらが良いというものではなく、人を分ける基準です。そのため「どちらになるべきか」ではなく、「どちらであれば自分が善い生き方をできるか」という観点から知者と仁者を見るべきだと本書には書かれています。

話は逸れますが、平野啓一郎が書いた「私とは何か 「個人」から「分人」へ」という本があります。この本で提唱されている「分人」という概念を平たく言えば、人間は時と場合、相手によって気質がコロコロ変わるということです。

自分の場合、「この足りない要素」を自分が持っている分人に当てはめていこうと思いました。つまり、自分に勢いがあって周りが見えなくなるときは、(知者側に傾いているとき)仁者の要素を、落ち着いて行動が鈍くなる時には知者の要素を足していきたいと思っています。これにより、調和の取れた人間になれるのではと思っています。

理解していることとできていないことの明確化

ドキッとしました。仕事を曖昧な状態で進めてしまうことが多々あるからです。斎藤孝は曖昧な状態で仕事を進める人は「一番伸びない」とまで言っています。

私の場合、理解しているつもりになっていることが多々あります。そのため、資料を作成した後に、認識齟齬が発生してやり直しということもよくあります*1

本書で斎藤は下記のように述べています。

境界線を引くことを、ワザ化するー。(中略) これができる人は、自分の能力を常に意識化できるので、自分に不向きなことがあったとき、無理に踏み入ることをしません。そのかわりに得意なところをググっと押し出し、「ここの範囲なら大丈夫です」と、自信を持って請け負うことができます。

ああ、なるほどと思いました。分かっている部分は、自信を持つことができるし、分かっていないことから不安が生まれるのだと思います。 それを自分の仕事に当てはめてみます。自分は仕事をする上で、漠然とした不安を抱えて仕事を進めることが多いです。その原因は曖昧なところを残したままであるからだと気がつきました。

以上のことから、理解できていることと、いないことを峻別することの重要性は理解できました。 しかし、どうやってその峻別を行えば良いのか?それに私は非常に悩みました。

その方法として、仕事を要素分解し、理解できていることと、いないことをリスト化することにしました。 例えば、スケジュールを立てるという一事についても、次の要素分解が必要です。

  • 顧客が成果物を必要とする時期はいつか?
  • 顧客が必要とする機能・性能・品質は何か?
  • 弊社が必要な工数はどの程度か?
  • 弊社が提供できるリソースはどの程度か?

これらの各要素に対する答えを自分は持っているのか、いないのかをまず最初に考え、わからないことについては仮説を立てて上司や顧客に相談することが非常に重要です。

今後は以上のような要素分解と、どの要素を私は理解できていて、どの要素を理解できていないのかを明確化することで仕事のクオリティを上げていきたいと思います。

述べて作らず

私の課題の一つに情報収集力の弱さがあります。情報収集力といっても色々あると思いますが、私の場合会議で話されたことなどがすぐに抜けてしまうのです。 また、過去資料を読んでも、読んだそばから忘れてしまいます。 そのため、自分の中に情報が蓄積されず、仮説構築などに活用しきれないということが起こります。

孔子が言う「述べて作らず」は本書いわく、

自分は、クリエイティブなことを言っているのではない。古のよき言い伝えをもう一度語っているだけなのだ

ということだそうです。私の仕事の場合、古⇒上司・顧客・過去資料、言い伝え⇒上司・顧客の主張・過去資料に記載されている提案や分析示唆になると考えています。

この文章の中で私にとって最も大事なことは「もう一度語っている」の部分だと感じています。 この語るの部分を自分はできていなかったと反省しました。*2

となれば、何をすれば良いかは明確。上司や顧客が言ったこと、資料に書かれていることを語れば良いのです。 実際は、語る相手が毎日はいないので、その日の夜に文章にして書き出すということをしようと思います。

まとめ

本書を読んで取り組もうと思ったことは3点です。

  • 知者と仁者を意識する。知者が足りないときは仁者を、仁者が足りないときは知者を足す
  • 仕事に取り組むときは、要素分解して理解していることと、いないことを明確化する
  • 顧客・上司が話したこと、過去資料に書かれたことを書き出す。また、語る相手を見つけてできるだけ語るようにする

これらの取り組みをできているか日に3回振り返ろうと思います*3

*1:そんな自分の特性を理解しているので、しつこいくらい上司に確認するようになりました。嫌われないか心配です

*2:ちなみに、インプットしたことを人に語ることの重要性は「アウトプット大全」という本にも書かれていました

*3:日に3回振り返るというのも孔子論語に書いてあるようです

【読書記録】未来を変える目標~SDGsアイデアブック~

本書を読んだ理由

会社でSDGs推進委員に入りました。具体的には、会社全体にSDGsについての教育を行ったり、SDGsに関する会社としてのアクションを企画したりなどの活動を行っています。

そんな中、私はどんな活動をすればSDGsにつながるのか何も思いつかないという状況に陥りました。そこで、既に行われている世界中のSDGsに関する活動を参考にするため、本書を手に取りました。 その結果、SDGsの活動を具体化していく方法について、有用な考え方を学ぶことができました。本記事では、その考え方について紹介したいと思います。

課題を深掘ることと、目標間のつながりを意識することが大事!

本書で得られた考え方、それは「課題を深掘ることと、目標間のつながりを意識することが大事!」です。

まず、課題を深堀ることについて例を挙げて説明します。

SDGsの目標4「質の高い教育をみんなに」を達成するための活動を検討しているとします。このとき、まず最初に取り組むべきは、「なぜ質の高い教育を受けられていない人がいるのだろう?」とか、「どんな人が質の高い教育を受けられていないのだろう?」と深堀して考えていくことです。その際に、5W1Hなどのフレームワークを使ったり、仮説を立ててデータから検証していくなどの思考法が有効だと思います。とにかく、アクションにつなげられるまで深堀していくことが必要です。

次に、目標間のつながりを意識することについて説明します。

SDGsには17個の目標があり、これらは互いに関連があります。そのため、ある目標を達成しようと行ったアクションが、別の目標の達成を阻害してしまうこともありえます。そのことをしっかり意識しておかないと、せっかく行ったアクションが逆効果になります。

一方、目標間のつながりを考え、ドミノ倒し的に複数の目標に働きかけられるアクションを考えることで、新たなアイデアにつながることもあります。 このような考え方をリンケージ思考というらしく、下記の本で詳しく解説されていました。

以上のことから、課題を深堀したアクション案が出たときに、それがSDGs全体に与える影響を検討することが重要です。

みんなの学校プロジェクト

ここでは、例として目標4「質の高い教育をみんなに」について深堀していきます。

まず最初に、どの地域の教育が進んでいないのか調べてみます。今回は、識字率の高さを教育が発展しているとみなします。

すると図1のようにアフリカに識字率が低い国が集まっていることがわかります。

図1:世界の識字率

そこで、なぜアフリカで教育が発展していないかを調べると、次のことがわかりました。(本書に書いてあることをそのまま書いています)

  • 教員の知識・技術不足
  • 学習環境が未整備
  • 教育行政が弱い

さらに、これらの要素によって、親が教育に対して不信感を持っており、子どもを学校に通わせないという状態になっていました。これが、教育が遅れている理由の一つになっています。

このような状態を打破しようと始まったのが、「みんなの学校プロジェクト」です。このプロジェクトは、親や地域の人々を巻き込んで教育を良くしていくという活動を仕組み化しました。

www.jica.go.jp

これらの活動により、補習の実施などの教育機会の拡大や、教室・トイレを整備するなどの学習環境の改善につながったそうです。

ここまでの考え方を図2にまとめました。

図2:みんなの学校プロジェクトが生まれるまで

さて、ここからは深堀をやめて他の目標との関連性について考えていきます。

先ほど挙げた進化する「みんなの学校」プロジェクト:アフリカ8ヵ国5万3000校に拡大、学校給食や手洗い啓発にも発展 | 2021年度 | トピックス | ニュース - JICAを見てみると、

各地でその地域ならではのニーズに基づいた地域住民たちの自発的な活動も生まれ、教育にとどまらず、栄養改善や衛生管理といった分野に活動はおよび、プロジェクトは大きな進化を遂げています。


2017年に地域の「みんな」に支えられるコミュニティ協働型の学校給食が始まりました。

との記載がありました。ここから目標4だけでなく、目標2「飢餓をゼロに」の解決に寄与していると考えられます。他にも、

みんなの学校の取り組みを始める際、しばしば障壁となるのが伝統的な慣習です。例えば、組織の代表者には年長者や男性を、という暗黙の掟があります。しかし、子どもの学習環境の改善に向け、委員会が現地の『みんな』を巻き込んで活動を実施するために必要なのは、男女問わず、やる気のある代表の力。代表を投票で選ぶ方法がなぜ必要なのか、実行の先に何が得られるのかといったことを地域住民たちに粘り強く説明し、議論しながら共通認識を持つようにしました。

からは、目標5「ジェンダー平等を実現しよう」や目標17「パートナーシップで目標を達成しよう」などの目標への寄与がうかがわれます。

このように、「みんなの学校プロジェクト」から始まった活動は、教育にとどまらず様々な目標に影響を与えています。一つのアクションによってドミノ倒し的に他の目標の達成に寄与していく良い例だと思いました。

要するにコンサルタントが普段やっていること

ここまで偉そうに書いてきましたが、ここまで書いてきた思考法は、コンサルタントたちが日常的にやっている思考法です。そういった意味で、コンサル企業がSDGsを推進することは、他の企業より優位な面もあるはずだと思いました。 また、SDGsの取り組みを元々非常に遠いものに感じていましたが、本書を読むことで親近感がわきました。本書に載っているような魅力的な取り組みをできるように、色々考えていきたいと思います。

オブジェクト指向設計実践ガイド【第3章】まとめ

オブジェクト指向の設計方法を学んでいます。 今回は、「オブジェクト指向設計実践ガイド」の「第3章:依存関係を管理する」を読んでまとめていきます。 なお、使用する言語はPythonです。

(過去記事) aisinkakura-datascientist.hatenablog.com aisinkakura-datascientist.hatenablog.com

3.1 依存関係を理解する

本章は、クラス間の依存関係についての解説です。テキストは、まず最初にいくつかの問題が含まれているスクリプトを例示し、その問題を解決する手法を説明していくという流れで進んでいきます。
テキスト記載のスクリプトPythonに書き換えたものが下記です。

class Gear:
    def __init__(self, chainring, cog, rim, tire):
        self._chainring = chainring
        self._cog = cog
        self._rim = rim
        self._tire = tire
        
    @property
    def chainring(self):
        return self._chainring
    
    @property
    def cog(self):
        return self._com
    
    @property
    def rim(self):
        return self._rim
    
    @property
    def tire(self):
        return self._tire
    
    def ratio(self):
        return self.chainring/self.cog
    
    def gear_inches(self):
        return self.ratio()*Wheel(self.rim, self.tire).diameter() # ここに問題あり!!!
    
class Wheel:
    def __init__(self, rim, tire):
        self._rim = rim
        self._tire = tire
        
    @property
    def rim(self):
        return self._rim
    
    @property
    def tire(self):
        return self._tire
    
    def diameter(self):
        return self.rim + (self.tire*2)
    
    def circumference(self):
        from math import pi
        return self.diameter()*pi

テキストによると、上記で「ここに問題あり!!」と記載した箇所、

    def gear_inches(self):
        return self.ratio()*Wheel(self.rim, self.tire).diameter() 

に含まれる問題は4つです。

  1. Gearは、Wheelという名前のクラスが存在することを予想している。
  2. Gearは、Wheelのインスタンスがdiameterに応答することを予想している
  3. Gearは、Wheelにrimとtireが必要なことを知っている
  4. Gearは、Wheelの最初の引数がrimで、2番目がtireである必要があることを知っている。

このうち、Pythonであれば4についてはあまり気にする必要がないかもしれません。Pythonの場合、引数の名前を指定すれば順番関係なく正しく動いてくれるからです。
なので、1~3に記載した問題をどのように解消していくのか見ていきます。

3.2 疎結合なコードを書く

「Gearは、Wheelという名前のクラスが存在することを予想している」を解消する方法

ここでは、元のスクリプトから離れて問題設定がより分かりやすいスクリプトを用いて勉強していきます。
まずは、こちらのスクリプトを見てください。

class BaseClass:
    def __init__(self, x):
        self._x = x
        
    @property
    def x(self):
        return self._x
    
    def func1(self):
        return ExampleClass(self.x).example_func()+1
    
    def func2(self):
        return ExampleClass(self.x).example_func()+2

    def func3(self):
        return ExampleClass(self.x).example_func()+3

class ExampleClass:
    def __init__(self, y):
        self._y = y
    
    @property
    def y(self):
        return self._y
    
    def example_func(self):
        return self.y

このスクリプトでは、func1~func3の中でExampleClassのインスタンスを作成しています。
これにより、BaseClassはExampleClassという名前のクラスを参照することを知っていなければならない状態になっています。
このとき、発生するトラブルは下記の2個です。

  1. ExampleClassの名前が変更されたときに、func1~func3まで全て書き換える必要がある
  2. ExampleClass以外のクラスのインスタンスを使ってfunc1~func3と同じような挙動をするメソッドを作る際に、func1~func3を再利用できない

実際に、どのようなトラブルが発生してしまうのか見てみます。

#ExampleClassの名前が変更されたときに、func1~func3まで全て書き換える必要がある
# ExampleClassがExampleClass2になったとする
class BaseClass:
    def __init__(self, x):
        self._x = x
        
    @property
    def x(self):
        return self._x
    
    def func1(self):
        return ExampleClass2(self.x).example_func()+1 # 変更した!
    
    def func2(self):
        return ExampleClass2(self.x).example_func()+2 # 変更した!

    def func3(self):
        return ExampleClass2(self.x).example_func()+3 # 変更した!

class ExampleClass2:
    def __init__(self, y):
        self._y = y
    
    @property
    def y(self):
        return self._y
    
    def example_func(self):
        return self.y

上記のスクリプトを見るとわかるように、func1~func3の中身全てを書き換える必要が生じています。これは面倒ですね。
次に、「ExampleClass以外のクラスのインスタンスを使ってfunc1~func3と同じような挙動をするメソッドを作る際に、func1~func3を再利用できない」についてもスクリプトを見てみます。

# ExampleClass以外のクラスのインスタンスを使ってfunc1~func3と同じような挙動をするメソッドを作る際に、func1~func3を再利用できない
# example_funcを持つ別のクラスにおいても、Baseクラスのfunc1、func2、func3と同様の挙動をするメソッドが必要になった
class BaseClass:
    def __init__(self, x):
        self._x = x
        
    @property
    def x(self):
        return self._x
    
    def func1(self):
        return ExampleClass(self.x).example_func()+1
    
    def func2(self):
        return ExampleClass(self.x).example_func()+2

    def func3(self):
        return ExampleClass(self.x).example_func()+3
    
    def func4(self):
        return ExampleClass3(self.x).example_func()+1 # 追加した!
    
    def func5(self):
        return ExampleClass3(self.x).example_func()+2 # 追加した!

    def func6(self):
        return ExampleClass3(self.x).example_func()+3 # 追加した!

class ExampleClass:
    def __init__(self, y):
        self._y = y
    
    @property
    def y(self):
        return self._y
    
    def example_func(self):
        return self.y

class ExampleClass3:
    def __init__(self, z):
        self._z = z
    
    @property
    def z(self):
        return self._z
    
    def example_func(self):
        return (self.z)**2

同じような挙動をするメソッドなのに、func1~func3を再利用できず、わざわざfunc4~func6まで追加しています。
これらのトラブルは、端的に言えばExampleClassをfunc1~func3の中でハードコーディングしているために発生しています。
したがって、ここではハードコーディングを避けた書き方をすればOKとなります。
修正したスクリプトがこちらです。

class DesignPattern:
    def __init__(self, x, exampleclass):
        self._x = x
        self._exampleclass = exampleclass # クラスの変数にインスタンスをとるようにする
        
    @property
    def x(self):
        return self._x
    
    @property
    def exampleclass(self):
        return self._exampleclass
    
    def func1(self):
        return self.exampleclass.example_func()+1
    
    def func2(self):
        return self.exampleclass.example_func()+2

    def func3(self):
        return self.exampleclass.example_func()+3

class ExampleClass:
    def __init__(self, y):
        self._y = y
    
    @property
    def y(self):
        return self._y
    
    def example_func(self):
        return self.y

ポイントは、クラスの変数としてインスタンスを与えることです。これによって、example_funcというメソッドを持つ全てのクラスに対応できるようになりました。
これにより、

  1. ExampleClassの名前が変更された
  2. ExampleClass以外のクラスのインスタンスを使ってfunc1~func3と同じような挙動をするメソッドを作る

に容易に対応できるようになりました。

# ExampleClassの名前がExampleClass2に変更された
ec2 = ExampleClass2(z=1) 

dp2 = DesignPattern(x=1, exampleclass=ec2) # インスタンスをあらかじめ作っておいてDesignPatternクラスの引数に入れるだけ

print(dp2.func1())
print(dp2.func2())
print(dp2.func3())

# ExampleClass以外のクラスのインスタンスを使ってfunc1~func3と同じような挙動をするメソッドを作る
ec3 = ExampleClass3(z=1) 

dp3 = DesignPattern(x=1, exampleclass=ec3) # こちらも同様

print(dp3.func1())
print(dp3.func2())
print(dp3.func3())

上記のように、DesignPatternに入れるインスタンスを変更するだけなので、容易にスクリプトの修正、再利用ができました。

Gearは、Wheelのインスタンスがdiameterに応答することを予想している

こちらも問題がわかりやすいようにスクリプトを変えて説明します。AntiPatternクラスのdoMethodOfAisatsuメソッドがAisatsuクラスのfuncメソッドを使っている例です。
(実行結果もわかりやすいようにGistで貼り付けました)

このとき、Aisatsuクラスのfuncメソッドの名前をaisatsu_funcに変更する必要が生じたとします。
このとき、同様の挙動をするスクリプトを作成するには、doMethodOfAisatsuメソッドの中身を下記のように書き換える必要があります。

def doMethodOfAisatsu(self):
        print(self.aisatsu.aisatsu_func().format("日本語", "おはようございます")) # 変更が生じた!
        print(self.aisatsu.aisatsu_func().format("英語", "Hello")) # 変更が生じた!
        print(self.aisatsu.aisatsu_func().format("中国語", "你好")) # 変更が生じた!
        print(self.aisatsu.aisatsu_func().format("マレーシア語", "Selamat pagi")) # 変更が生じた!

今回は4か所変更する必要が生じてしまいました。これは面倒です。そこで、外部依存する箇所を一か所に閉じ込めるという工夫をします。

上記スクリプトでDesignPatternクラスの内部にfuncメソッドを追加しました。これにより、Aisatsuクラスのfuncメソッドの名前が変更されたとき、下記の変更だけで済みます。

# Aisatsuクラスのfuncメソッドがaisatsu_funcに変更されたとき
 def func(self):
        return self.aisatsu.aisatsu_func()

これにより、doMethodOfAisatsuメソッドの中身を変更せずに済みました。

「Gearは、Wheelにrimとtireが必要なことを知っている」を解消する方法

これは比較的簡単です。Pythonにが可変長引数が実装されているので、それを使います。 可変長引数については、下記を参照しました。

Pythonの可変長引数(*args, **kwargs)の使い方 | note.nkmk.me

可変長引数については、単純なので最初からデザインパターンを記載します。

 「3.3 依存方向の管理」の解説

ここまでクラス間の依存度を下げる方法を学んできました。この後は、依存方向をついて学んでいきます。
なお、テキストは「依存関係の逆転→依存方向の選択」の順で説明されています、しかし、私は私自身の理解のしやすさから順番を逆にして説明しようと思います。

依存方向の選択

まず、「クラスAがクラスBに依存している」という言葉の意味を明確にします。
ここでは、「クラスAがクラスBに依存している」といったとき、「クラスAはクラスBのアトリビュート・メソッドを使っている」という意味で使います。スクリプトで書くと下記のような状態を「クラスAがクラスBに依存している」と言います。

class A:
    def __init__(self, ib):
        self._ib = B(b=1)

    def func_A(self):
        print(self._ib.func_B()) # クラスAでクラスBのメソッドを使っている

class B:
    def __init__(self, b):
        self._b = b 

    def func_B(self):
        return self._b
        
# ここまで説明してきたアンチパターンをいくつも使っていますが、お許しください

このとき、依存されるBが満たすべき要件は下記の通りです。

  1. 要件が変わりにくい
  2. 依存されているクラスが少ない

どんなにクラス間の依存度を下げたとしても、要件が変わるたびに依存しているクラス(上記の例だとクラスA)は変更を強いられます。そのため、要件が変わりやすいクラスに依存すべきではないということが1の要件がある理由です。
また、依存されているクラスが多いと、そのクラスの変更がアプリケーション全体に及ぶ可能性が高まります。これが2の要件がある理由です。
これらの事柄を本書では、図1のようにまとめています。(p83から引用)

図1:変わりやすさと依存物の数

依存関係の逆転

本節では、クラスの依存関係を逆転する方法について解説します。 まずは、AがBに依存する場合です。

次にこれを機能を変えずに依存関係を逆転させ、BがAに依存するようにしたスクリプトがこちらです。
ポイントは、Aで定義したメソッドをBで呼び出している点です。

恐らく、どちらの方向にもクラスの依存関係を作ることができるのではないかと思います。したがって、本節前半の「依存方向の選択」に記載した要件に準じて依存関係を決め、それに合わせてスクリプトを書くことが重要なのだと私は理解しました。

まとめ

今回は「第3章:依存関係を管理する」について解説しました。
本章の前半では、クラス間の依存度を下げる方法について学ぶことができます。また、後半では依存関係の方向性を決める方法と依存関係を逆転する方法について学ぶことができました。

【読書記録】アダルト・チャイルドが人生を変えていく本

今回は、「アダルト・チャイルドが人生を変えていく本」について書きます。

前書との比較

本書は、過去記事に書いた「アダルト・チャイルドが自分と向き合う本」の続編です。これら2冊の関係性は図1のようになっています。

(過去記事) aisinkakura-datascientist.hatenablog.com

図1:「アダルト・チャイルドが自分と向き合う本」と「アダルト・チャイルドが人生を変えていく本」の関係性

「アダルト・チャイルドが自分と向き合う本」は、人との関係性や依存症に苦しんでいる人が、自分がアダルト・チャイルドであると認識し、今の辛い状況を作り出した理由を明確にすることが目的でした。一方で、「アダルト・チャイルドが人生を変えていく本」は、自分の感情を開放し、辛い状況を解決していくことを目的としています。

本書の主張

本書のワークは下記に重点が置かれています。

  • 自分のやりたいこと、嫌なことを明確化すること
  • 明確化したやりたいことを実現すること

本書の各章が上記のどちらに重点を置いているか、自分なりに整理してみました。(表1)

表1:重点項目と各章の関係

表1を改めてみてみると、本書は自分の意思をちゃんと人に伝えられるようになることを通じて、「明確化したやりたいことを実現する」につなげていこうとしていると私は感じました。
本書においては、アダルト・チャイルドの特徴として、自分の気持ちを人に伝えられないと繰り返し書かれています。この特徴をしっかり修正していくことが重要であると私は思いました。

読んでどうなったか?

本書を読み、妻に自分の置かれている状況をきちんと説明できるようになりました。そのため、今では自分がリラックスできたり楽しんだりできることの探索に協力してもらっています。
また、私は人生の重要な選択を全て妻に任せてきました。正直、自分が望まない選択もあったのですが、妻から嫌われることを恐れて言いなりになっていたこともあります。 過去に親から受けた制約が後遺症となって、現在の妻との関係性に影響を与えていることは、非常に辛いことです。しかし、本書を読んだことで解決の糸口を見つけられたと感じています。
「人に嫌われることを恐れて自分の本心を言えない」「見捨てられ不安が強くて辛い」と思う人は、ぜひ2冊とも読むことをお勧めします。

(改めてリンクを貼っておきます)

余談

アダルト・チャイルドを支援している人は、本書のワークを自分自身でやってみると良いと思います。本書のワークを通じて、なぜアダルト・チャイルドの人が破滅的な行動に出てしまうのかということを、自分に肉迫した感覚で掴めるようになるのではと思うからです。
また、以前自分が塾でアルバイトをしていたときに出会った教え子で、機能不全家庭で育った子どもがいたのですが、そういった子どもが大人になったときに本書に出会えると良いなと切に思います。