ドラッカーによるイノベーションの7つの機会

年末年始にドラッカーイノベーションと企業家精神を読んだ。面白かったがが頭の中で整理しきれなかったので、その中から「イノベーションの7つの機会」をまとめてみる。

あるイノベーションは、いずれかの機会のみによって生まれるとは限らず、複数の機会の組み合わせによって生まれることもある。

1. 予期せぬことの生起

予期せぬ成功

  • リスクが小さいはずだが、見逃されることが多い(否定されることすらある)機会。
  • 「弊社のこの事業がなぜか成長しているが、本当に取り組みたい事業ではない」
  • 予期していないため、観測・分析されないこともある。目にとまる仕組みを体系化する必要がある。

予期せぬ失敗

  • 成功すると思っていたビジネスの失敗。予期せぬ成功と違って見逃されることは少ないが、機会であると捉えられることは少ない。
  • 慎重に行われたビジネスであったら、想定と現実に差異があったことになる。差異こそが機会。
  • 自身だけでなく他者の予期せぬ失敗からも学ぶことができる。
  • 企業家たる者にとって、現実が変化した原因を知る必要はない。何が起こったかはわかっても、なぜ起こったかはわからないほうが多い。だが、なぜ起こったかはわからなくともイノベーションに成功することはできる。

2. ギャップ

  • 現実にあるものと、あるべきものとの乖離。
  • 定量的でなく定性的であることが多い。

業績ギャップ

  • 需要が伸びているのに業績が伸びていない状態。
  • 産業全体で生じていることが多い。
  • 行動する前に、解決すべき問題を明確にし、既存の技術・資源を利用して解決策を考える。

認識ギャップ

  • 産業内部の者が現実を誤って認識している状態。
  • 「この問題を解決するためにこの分野に力を入れるべき」
  • 問題を複雑に認識してしまっている状態に対し、より単純な方法を提供することでイノベーションとなることが多い。

価値観ギャップ

  • 消費者が持つ価値観を生産者が誤って認識している状態。
  • 「貧しい人たちが何を変えるかを知っているのは、彼ら貧しい人たちではなく私である」
  • 生産者が提供していると思っているものを購入する消費者はほとんどいない。このとき、生産者は消費者が不合理であるとみなすが、ここにこそ機会がある。

プロセスギャップ

  • ある業務プロセスに課題がある状態。
  • 特定の産業に対して丁寧にヒアリングすることで明らかになることが多い。消費者は多くの場合、すでにそのギャップを感じている。

3. ニーズ

  • ニーズによるイノベーションが成功するには5つの前提がある。
    • 完結したプロセスについてのものである
    • 欠落した部分や欠陥が1箇所だけである
    • 目的が明確である
    • 目的達成に必要なものが明確である
    • 「もっとよい方法があるはず」という認識が浸透している
  • また3つの条件がある
    • 何がニーズであるかが明確に理解されている
    • 必要な知識が手に入る
    • 解決策が、それを使う者の仕事の方法や価値観に一致している

プロセス上のニーズ

  • 状況ではなく課題からスタートする。誰もがそのニーズが存在していることを知っているが、手を付けられていない状態。
  • ひとたび解決すると、そのイノベーションは標準となる。

労働力上のニーズ

  • 機械/ロボットによる自動化など。

知識上のニーズ

  • 研究開発によって満たされるニーズ。課題はすでに明らかになっている。
  • プロセス上のニーズや労働力上のニーズよりも困難でリスクが大きい。

4. 産業構造の変化

  • 産業・市場の構造は、内部の人間が感じるよりも脆弱である。
  • 小さな企業が機会としてとらえ、大企業が損失を被ることが多い。
  • 産業の外部からは機会、内部からは脅威とみえる。
  • ここでのイノベーションは単純でなければならない。
  • 以下の場合、ほぼ確実に起こる。
    • 急速な成長
    • 急速な成長に伴い、その市場のとらえ方、対応の変化
    • いくつかの技術の合
    • 仕事の仕方の急速な変化

5. 人口構造の変化

  • 人口の増減、年齢構成、雇用、教育水準、所得などの変化。
  • 可能性・リードタイムの予測が容易。
  • 急速に、原因もわからず起こる場合もある。このケースを認めようとしない場合は敗者となる。
  • 統計ではなく、街の観察によって変化の可能性に気づく場合もある(ただし統計がベースであるべき)。

6. 認識の変化

  • コップの半分に水が入っているとき、「半分は満たされている」なのか「半分は満たされていない」とするのか。
  • 1960年代から20年後、アメリカでは健康度が著しく上昇したが、多くのアメリカ人の不健康への恐怖は増大していた。健康に対する認識が変わっていた。
  • やはり、原因はわからないことが多い。また定量的でない。定量化できたとしても、そのときにはイノベーションの機会には遅すぎる。
  • 一時的なものか永続的なものか見分けがつきづらいため、小規模に始める必要がある。

7. 新しい知識の出現

  • 技術的・社会的知識によるイノベーション
  • 実用化までのリードタイムが長い。市場で受け入れられるようになるには25年から35年を要する。リードタイムの長さは短くなっているとされているが、錯覚にすぎない。
    • (所感: これはさすがに多少は短くなっているのではないだろうか??)
  • 科学や技術以外の知識を含め、複数の知識が結合して起こる。
  • 必要な知識の全てが用意されなければ必ず失敗する。
  • 3つの条件がある。
    • 社会、経済、認識の変化などあらゆる要因の分析。分析しなければ、何の知識が足りないのかがわからない。
      • 科学者や技術者は自分がすべてを知っていると思い込んでいるが、多くの場合誤っている。
    • 戦略。戦略には3つしかない。
      • システム全体を自ら開発し、それを手に入れる
      • システム全体ではなく、特定の市場を確保する(自ら創造する)。
      • 重要な能力に力を集中し、重点を占拠する。産業が変化しても超然としていられる場所を探す。
    • マネジメント。リスクの大きさをマネジメントで補う必要がある。
      • 新しい知識のイノベーションが失敗する原因の多くはマネジメントの不足である。
  • ほかのイノベーションはすでに起こった変化を利用するが、ここではイノベーションが変化を起こす。それによりニーズが生まれる。世に受け入れられるかどうかはわからない。
  • 誰もがニーズがあると知っていても、実際に現れると抵抗されることもある。
  • リスクが大きいが、それを予期せぬ出来事やギャップの存在、ニーズの存在といった機会とみなし、リスクを減らすことができる。

ひとり Advent Calendar を振り返る

ひとりでやる Advent Calendar 2017 - Adventar 最終日。見切り発車で始めたものの、なんとか最後までたどり着いたのでほっとしています。まとまった時間がとれなかったために当初考えていた重めのテーマがいくつか書けなかったのが心残り。でも、しばらく放置していたブログを更新する心理的ハードルがだいぶ下がったので、今後も思い立ったときに投稿していける気がします。

なぜひとり Advent Calendar をはじめたか

これは完全に思いつきで、先の見えない何かを自分に課してみたかったという、ささやかな冒険です。あとは、本を読んだりコードを書いたり物思いに耽ったり、知識や思考が内向きに積もってきたので、ちょっとここらで発散してみるかというところもありました。

どうだったか

ネタは探せばいくらでもあるもんですね。技術系の記事は、書き留めていたメモが役に立ちました。これはブログに関係無く、(自分にとって)続けるべきものだと改めて感じました。あとは思考についても、これはブログに書く必要はないかもしれないけど、何かしら書き留めておきたい。数年前に自分が考えていたことが、いまになってつながってくるということもあるでしょうし。

あとは、文章にする & 公開することで、自分のなかでさらに整理される、あるいは新たな問いが生まれる、というメリットもありました。

誰が読むんだよとは思ってましたが、たまに Facebook でコメントいただけたのは嬉しかったですね。自分が興味をもたれることは何よりうれしい(分析はしないでほしい)。

おわりに

最後にちょっとだけ今年を振り返ると、仕事では長い一人プロジェクトを完遂したり新規事業に関わりはじめたり、技術的にもこれまで未知だった領域にいろいろ触れられたのでよかったですね。私生活では、オケでシベ6をやり、ライブやコンサートに足を運び(たぶん19回?多い方じゃないが、自分の年間ではこれまでで最多)、酒とめしに投資した。楽しさと寂しさのバランスがとれた、人間らしい1年だったように思います。

... と書いていて思ったけど、全然十分には楽しめてなかったな。まだまだいくらでもやりようはあった。悔しいなぁ。

この悔しさが良い。

というわけで、読んでいただいてありがとうございました。今後ともよろしくお願いします。

音楽をどのように好きか

ひとり Advent Calendar 24日目、きょうはポエムです。

 

音楽が好きだ。詳しくはないが。

俺はどう音楽が好きなのか、昔から考えていたけど、ここ数年で安定してきた。それは、俺は音楽に憧れ、音楽になりたいということだ。

 

続きを読む

いろいろな Web フロントエンドの技術

最近フロントエンドのあれこれに触ることが多い。フロントエンドといえば諸々のつらみとの戦いである。それらを解決するいろんな技術があるがいろいろありすぎてとっつきづらいので各技術が何を解決したいのかまとめてみた。

各技術の詳細は、それぞれ詳しい記事が世の中に溢れてるので省く。包括的にどんな技術があるのか、をみつめることをこの記事の価値におく。

(各技術は、それぞれ重複する部分もある;たとえばモジュールバンドラーである webpack はタスクランナー的な機能ももっている)


JavaScript フレームワーク

  • Vue.js / AngularJS / React

何を解決するか

  • JavaScript でビューを変更する / ビューの変更を受け取るときのつらみ
    • ビューとロジックの分離
    • ビューで変更があったらロジックが起動し、その結果を受けてビューが変更される、とかが書きやすくなる

JavaScript トランスパイル

何を解決するか

  • JavaScript の書きっぷりのつらみ
    • 動的型付け言語である JavaScript に型を付けられたりする
    • == を厳密に扱えたりする
    • 最新の ECMAScript の記法が使える
      • ブラウザによって JavaScript の挙動が異なる問題も併せて。

CSS トランスパイル

  • sass / less

何を解決するか

  • CSS のつらみ
    • 子孫セレクタを使わず、ネストすれば子孫関係が表現できる
    • 変数が使える
    • 演算ができる

テンプレートエンジン

  • Jade / Haml / Slim
  • そのほかサーバーサイドの言語によっていろいろ

何を解決するか

  • 静的な ​HTML を動的に生成したい問題
  • そのほか boilerplate
    • コピペで毎回書かなきゃいけないおまじない的なやつとか
    • < > はタイピングのコストが高いので避けようとしてるものが多い

パッケージ管理

  • npm / bower / yarn

何を解決するか

  • JavaScript のライブラリ管理
    • 欲しいライブラリをわざわざダウンロードしたり、クライアントに CDN にアクセスさせたりするコスト
    • ライブラリ間の依存性も解決できる

モジュールバンドル

  • webpack / browserify

何を解決するか

  • JavaScript / CSS を使用するためには ​HTML でどのファイルを使用するか指定する必要がある
    • 複数のファイルをまとめて hogehoge.bundle.js みたいなファイルにして、これさえ読み込めば OK、という体制にしてくれる
    • クライアントからのリクエストも減る
  • JavaScript / CSS のサイズが大きいとクライアント側にダウンロードの負荷がかかる
    • 改行とか無駄な記述をなくしてくれる (minify という)

スクランナー

  • gulp / Grunt

何を解決するか

  • 上述してきたツール群の多くは、コマンドを叩かなきゃ機能しない
    • たとえばファイルが保存されたら勝手にコマンドを起動する、とかの処理を記述できる

Node.js で Elasticsearch にクエリ

Elasticsearch の公式クライアントで叩く。

const elasticsearch = require('elasticsearch');
const client = new elasticsearch.Client({
  host: 'http://localhost:9200'
  httpAuth: 'user:password'
  log: 'trace'
});

client.search({
  index: index,
  type: type,
  size: size,
  body: {
    _source: [
      // to be included fields
    ],
    aggs: {
      // aggregation contents
    },
    query:{
      // query contents
    }  
  }
});

直で REST API 叩く時とちょっとだけ違っていて、 query や aggs の前に body を挟む必要があったりするので注意。

.search の戻り値は Promise になっていて、中身はこんな以下のように取得する。これは REST API の戻り値と (たぶん) おなじ。

client.search().then(response => {
  const documents = response.hits.hits.(x=>x._source);
  const aggregated = response.aggregations;
  // ...
});

当然、

function get() {
  return client.search().then(response => return response;)
}

get().then(result => {
  // ...
});

とか、

 const result = await client.search();

とか書ける。

Scroll API で取得したい場合はちょっと違って

let documents = [];
client.search({
  index: index,
  type: type,
  size: size,
  scroll: chacheTime
  body: {
    query:{
      // query contents
    }
  }
}, function scroll(error, response) {
  documents = documents.concat(response.hits.hits);
  if(response.hits.total !== documents.length) {
    client.scroll({
      scrollId: response._scroll_id,
      scroll: cacheTime
    }, scroll)
  } else {
    return documents;
  }
});

のようになる。この戻り値が Promise とならず、 client.search({...}, function(){...}).then() のように書けない。なので 上述の例と同じように扱いたければ

const promise = new Promise((resolve, reject) => {
  let documents = [];
  client.search({
    // ...
  }, function scroll(error, response) {
    documents = documents.concat(response.hits.hits);
    if(response.hits.total !== documents.length) {
      client.scroll({
        scrollId: response._scroll_id,
        scroll: cacheTime
      }, scroll)
    } else {
      resolve(documents);
    }
  })
})

と Promise オブジェクトを new してやる必要がある。

これはもっとスマートに解決できる方法があるかも?

Array.prototype.reduce() に親しむ

JavaScript の配列に reduce という関数がある。 MDM のドキュメント によると以下のように書かれている。

arrayObj.reduce(function(previousValue, currentValue, index, array){
  // ...
})

previous とか current いわれてもよくわからん。。 ただ、感覚を掴んでくるとこいつがなかなか便利だ。

たとえば、配列をループの中で処理する場合、そのままだと二重ループになっちゃって計算量がかさむってことがある。なので事前に配列じゃなくて連想配列だと嬉しい。そんなとき、こいつを使うと配列を連想配列に変換することができる。

array.reduce((map, obj) => {
  map(obj.key) = obj;
  return map;
}, {});

また Object.assign() とも相性がいい。これは、第一引数のオブジェクトに第二引数のオブジェクトをくっつけることができるというものだ。なので、たとえばオブジェクトの配列

const array = [
  {
    "1" : {
      ...
    },
  }
  {
    "2" : {
      ...
    }
  }
]

を使って

const result = array.reduce((map, obj) => {
  Object.assign(map, obj);
}, {});

すると、

result = {
  "hoge" : {
    ...
  },
  "fuga" : {
    ...
  }
}

のように変換できる。たとえば Node.js でデータを配列として取得して、 key-value として扱いたいってときに超便利。

Node.js × TypeScript 勉強中 (2)

Node.js × TypeScript 勉強中 - take a keen edge から続いた。


JavaScript の拡張メソッド (って呼ぶの?) 書くときはこうなる。

Array.prototype.chunk = function (size) {
    if (!this.length) return [];

    return [this.slice(0, size)].concat(this.slice(size).chunk(size));
}

で、 Node.js でこいつを別ファイルに切り出したい。そんなときは、

Array.prototype.chunk = function (size) {
  ...
}
exports = Array;

として、呼び出し側で

require('arrayExtensions');

function hoge(array) {
  const chunked = array.chunk(100);
}

してやる。モジュールじゃないので const extenstions = require('arrayExtensions') する必要はない。 TypeScript でいうと import extensions = require('arrayExtensions') みたいに書くと怒られる。

コピペばっかしてると import とか require とかがどの文脈のものなのかわからなくて詰みそうなところである。

ちなみに TypeScript の拡張メソッド (?) は ↑ だと怒られて、 interface を切る必要がある。

interface Array<T> {
    chunk(size: number): Array<T>;
}

Array.prototype.chunk = function (size) {
    ...
}
exports = Array;