web-technical-blog

web開発に関する技術メモ

Amazon S3に保存されているバケット毎のオブジェクト容量、オブジェクト数を知る方法は大きく分けて下記の2つの方法がある

  • CloudWatchのメトリクスであるS3ストレージメトリクスのBucketSizeBytes、NumberOfObjectsを参照する
  • AWS CLIでS3のバケット配下のオブジェクトに対して再帰的に容量と数を集計する。
    • CloudWatchのメトリクスは自動的に集計してくれるというメリットの一方で1日1回の集計結果しか表示されないというデメリットがある
    • リアルタイムで容量やオブジェクトを知りたい場合は使用できない

www.magtranetwork.com

AWS SAMを利用してGolangなLambdaをデプロイする

AWS CLIでデプロイ

$ GOOS=linux go build -o main
$ zip deployment.zip main
$ aws lambda create-function \
--region us-west-2 \
--function-name HelloFunction \
--zip-file fileb://./deployment.zip \
--runtime go1.x \
--tracing-config Mode=Active \
--role arn:aws:iam::account_id:role/role_name \
--handler main

aws lambda create-functionのオプション

https://docs.aws.amazon.com/cli/latest/reference/lambda/create-function.html

depoly方法

https://github.com/aws/aws-lambda-go https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/deploying-lambda-apps.html


AWS SAMを利用してLambdaをデプロイする

  • template.ymlのroleは指定する

テンプレート

$ cat template.yml

AWSTemplateFormatVersion: "2010-09-09"
Transform: 'AWS::Serverless-2016-10-31'
Resources:
  App:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: lambda-go-sample # ファイル名
      Runtime: go1.x
      CodeUri: build # ビルドファイル設置ディレクトリ
      Role: arn:aws:iam::account_id:role/role_name # roleを設定する
      Timeout: 1

デプロイ

$ GOARCH=amd64 GOOS=linux go build -o build/lambda-go-sample

$ aws cloudformation package \
    --template-file template.yml \
    --s3-bucket <bucket-name> \
    --s3-prefix lambda-go-sample \
    --output-template-file .template.yml

$ aws cloudformation deploy \
    --template-file .template.yml \
    --stack-name lambda-go-sample \
    --capabilities CAPABILITY_IAM

実行結果

$ aws cloudformation describe-stack-resources --stack-name lambda-go-sample

実行

$ aws lambda invoke --function-name lambda-go-sample-App-xxxx --payload '"Lambda"' out.txt

https://qiita.com/ikeisuke/items/3c0c422888ae8ae09831

Docker compose

  • npmコマンドが使用できる必要あり
  • docker-composeコマンドが使用できる必要あり

docker-compose.ymlファイルとは

docker-compose.ymlファイルは以下のようにyaml形式でDockerコンテナに関する起動オプション(buildオプションも含まれることもある)を記述したファイル

docker-compose.ymlサンプル

web:
  build: .
  ports:
    - "5000:5000"
  volumes:
    - .:/code
  links:
    - redis
  redis:
    image: redis

# yaml の記載方法については下記を参照
# https://docs.docker.com/compose/compose-file/

Docker Compose概要

Docker composeとは複数のコンテナから成るサービスを構築・実行する手順を自動的にし、管理を用意にする機能 Docker composeでは、composeファイルを用意してコマンドを1回実行することで、そのファイルから設定を読み込んで全てのコンテナサービスを起動することができる

Docker Composeを使うまでの主なステップ

  • それぞれのコンテナのDockerfieを作成する(既にあるイメージを使う場合は不要)
  • docker-compose.ymlを作成し、それぞれ独立したコンテナの起動定義を行う(場合によっては構築定義も含まれる)
  • docker-compose upコマンドを実行してdocker-compose.ymlで定義したコンテナを開始する

動作確認を行う環境について

(Working dir)
+- docker-compose.yml
+- app-server/
    +- Dockerfile
    +- src/
        +- app.js

Docker composeを使用した簡単なサンプル

Docker composeを使用した複数コンテナでひとつのサービスを作成するサンプルを実施してみる redisを使用してアクセス数をカウントする簡単なアプリケーションを作成してみる

application側の作成

アプリケーション側はnode.jsを使用する nodeの公式レポジトリを使用するための、Dockerfileは以下のように簡単なもの

app-server/Dockerfile

FROM node:5
RUN npm -g install redis
ENV NODE_APTH /usr/local/lib/mode_modules

ENTRYPOINT ["node", "app.js"]

npmはnode.jsのpackageを管理するためのツール ENTRYPOINT ["node", "app.js"]は nodeコマンドの引数にapp.jsを渡している

Redis側の作成

Redis側のコンテナの作成を行うが、公式のRedisイメージを使用するため、Dockerfileは不要

Docker composeファイルの作成

アプリ側のnodeのアプリケーションとredis側のアプリケーションをbuild,runするための定義をdocker-coposeファイルに記載する

docker-compose.yml

nodeapp:
  build: "./app-server"
  container_name: "nodeapp"
  working_dir: "/usr/src/app"
  ports:
   - "10080:10080"
  volumes:
   - "$PWD/app-server/src:/usr/src/app"
  links:
   - "noderedis"
noderedis:
  image: "redis:3"
  container_name: "noderedis"

nodeのアプリケーションが乗るコンテナは、Dockerfileからイメージをbuildしてそこからnodeappという名前のコンテナを起動する redisが乗るコンテナについては、DockerfileからイメージをせずDocker hubからpullしてきた公式イメージを利用し、そこからnoderedisという名前のコンテナを起動する

docker-compose.ymlファイルのあるディレクトリ移動し、docker-compose upコマンドを実行する

$ docker-compose up

動作確認

$ curl http://localhost:10080
You accessed here 1 times.
$ curl http://localhost:10080
You accessed here 2 times.

docker-composeコマンドで作成されるイメージ名

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
wk_nodeapp          latest              c36a03206379        15 minutes ago      649MB
redis               3                   256639e384de        8 weeks ago         99.7MB
node                5                   12b4a63115bc        17 months ago       648MB

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                      NAMES
9fa382e87f70        wk_nodeapp          "node app.js"            15 minutes ago      Up 15 minutes       0.0.0.0:10080->10080/tcp   nodeapp
dba91dafd516        redis:3             "docker-entrypoint.s…"   15 minutes ago      Up 15 minutes       6379/tcp                   noderedis

docker-compose.yml

nodeapp:                            # <- サービス名
  build: "./app-server"             # <- Dockerfile のあるファイルの場所(Dockerfile のある場所。git リポジトリのURL も指定可能)
  container_name: "nodeapp"         # <- コンテナ名。指定しなかった場合はDocker compose で勝手に決められる
  working_dir: "/usr/src/app"       # <- コンテナ内のワーキングディレクトリ。docker run コマンドの-w/--workdir に相当
  ports:                            # <- Expose するポート。docker run コマンドの-p/--publish に相当
   - "10080:10080"
  volumes:                          # <- Bind mount するディレクトリ。volume。docker run コマンドの-v/--volume に相当
   - "$PWD/app-server/src:/usr/src/app"
  links:                            # <- 他のコンテナと接続するときのコンテナ名。docker run コマンドの--link に相当
   - "noderedis"
noderedis:
  image: "redis:3"                  # <- イメージIDとtag
  container_name: "noderedis"

参考URL https://qiita.com/TsutomuNakamura/items/7e90e5efb36601c5bc8a

Docker Hubのオフィシャルイメージを使ったLAMP環境(Apache+PHP+MySQL)

PHP+Apacheのイメージをつかってみる

$ docker rund -d php:5.6-apache

PHP+ApacheのイメージをDocker Hubから取得し、コンテナを起動

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
php                 5.6-apache          61a89dae852c        3 weeks ago         378MB

取得したイメージを一覧を表示する STATUSの欄がUpになっていれば起動

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
0877ed1b4e88        php:5.6-apache      "docker-php-entrypoi…"   5 minutes ago       Up 5 minutes        80/tcp              agitated_wright

ブラウザで確認する

上の方法では、起動しているコンテナのポートが内部で閉じているのでブラウザで確認することはできない。コンテナのポートを公開する

$ docker run -p 80:80 -d php:5.6-apache

-pオプションでホストのポートとコンテナのポートを結びつける。コロンの左側がホスト側、右側がコンテナ側のポート番号。

コンテナを削除する

$ docker rm -f コンテナID

これで削除できる。コンテナIDは以下で確認できる

$ docker ps -a

コンテナを一括で全て削除することも可能

$ docker rm -f $(docker ps -a -q)

コンテナを作成する

1.コンテナに入ってファイルを作成する

$ docker run -p 80:80 --name php -d php:5.6-apache

分かりやすように、--nameオプションでコンテナにphpという名前をつけている

$ docker exec -ti php bash

phpコンテナ内に入ることができる。-tiをつけないとターミナルを開くことはできない

ドキュメントルートの/var/www/htmlにいるはずなので、

# echo '<?php phpinfo();' > index.php

ブラウザでサーバーのURLを開きphpinfoの画面が確認できる

2.コンテナのディレクトリとホストのディレクトリを結びつける

コンテナは永続かされないので、コンテナを削除するとコンテナ内で作成したファイルも消えてしまう。ホスト側にファイルを置き、そのディレクトリをコンテナ側から参照する手法を試す

ホスト側のファイルを置くディレクトリは/Users/121799/docker/wwwどこにおいても問題ない 以前のコンテナを削除してから、以下を実行する

$ docker run -p 80:80 -v /Users/121799/docker/www:/var/www/html --name php -d php:5.6-apache

-vオプションでホストのディレクトリとコンテナのディレクトリを結びつける。コロンの左側がホスト側、右側がコンテナ側のディレクトリ。

MySQLのイメージを使ってみる

起動してコマンドラインから操作してみる

$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=pass -d mysql:5.7

MySQL5.7のイメージをDocker Hubから取得し、起動する -eオプションは環境変数を設定するもので、rootのパスワードをpsssに設定している

コンテナに入る MySQLの操作ができるようになる

$ docker exec -ti mysql bash
$ mysql -ppass

PHPMySQLの連携

DockerfileによるPHPイメージのカスタマイズ

オフィシャルのPHPコンテナは最小限のオプションでコンパイルされている。そのままではMySQLと連動するのが難しい。 Dockerfileを使うと、既にあるイメージをカスタマイズして新しいイメージを作ることができる

Dockerfileの場所はどこでも良い。今回は/docker/phpに作成する ホスト側で/docker/php/Dockerfileを以下の内容で作成する

FROM php:5.6-apache
RUN apt-get update && \
  docker-php-ext-install pdo_mysql mysqli mbstring

FROMは元となるイメージを指定する RUMコマンドを指定する。docker-php-ext-installはphp:5.6-apacheイメージに含まれるユーティリティで、オプションを追加してPHPをリコンパイルするもの

docker-php-ext-install 引数を元にエクステンションをインストールしてくれる

Dockerfileが用意できたら、新しいイメージをビルドする

docker build -t php:custom /docker/php

/docker/phpにあるDockerfileを元にphp:customというイメージを作成する。docker imagesで確認する

MySQLイメージの設定を変更する

先ほど、作成したコンテナは削除しておく

Docker HubのMySQLイメージはcharacter setがlatin1になっている部分があるので設定ファイルを追加する /docker/mysql/custom.confを以下の内容で作成

[mysqld]
character-set-server=utf8
$ docker run --name mysql -v /docker/mysql:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=pass -d mysql:5.7

-vオプションでホスト側の/docker/mysqlディレクトリとコンテナ側の/etc/mysql/conf.dディレクトリを結びつけている

PHPコンテナをMySQLコンテナとリンクして起動する

$ docker run -p 80:80 -v /docker/www:/var/www/html --link mysql:mysql -name php -d php:custom

--linkオプションでコンテナmysqlを連携する。 コロンの左側にコンテナ名を指定する

連携が取れているか確認する

$ docker exec -ti php bash
$ cat /etc/hosts172.17.0.2  
mysql d5ca7e687d9b

--linkオプションで指定した名前でホスト名にアクセスできる コロンの右側で指定した名前

phpMyAdminを導入して確認

連携の確認用にphpMyAdminをホスト側に導入

cd /docker/www
wget https://files.phpmyadmin.net/phpMyAdmin/4.4.13.1/phpMyAdmin-4.4.13.1-all-languages.tar.gz
tar zxf phpMyAdmin-4.4.13.1-all-languages.tar.gz
rm phpMyAdmin-4.4.13.1-all-languages.tar.gz
mv phpMyAdmin-4.4.13.1-all-languages myadmin
cd myadmin/
cp config.sample.inc.php config.inc.php

config.inc.php

$cfg['Servers'][$i]['host'] = 'mysql'

hostをlocalhostから--linkオプションにより設定されたホスト名mysqlに変更する

DockerでPHP7.0 + Apacheの環境を構築する

PHP7.0 + Apacheを起動する

docker run -d -p 80:80 --name php70-apache php:7.0-apacheでイメージからコンテナを立ち上げる(ローカルにimageがない場合はDocker Hubから取得してくれる) -pオプションでポートを80番でフォワード

$ docker run -d -p 80:80 --name php70-apache php:7.0-apache
Unable to find image 'php:7.0-apache' locally

7.0-apache: Pulling from library/php
f49cf87b52c1: Pull complete
185616061386: Pull complete
5fc132db2e0d: Pull complete
00c1c323341a: Pull complete
ff3701349211: Pull complete
faab1d6ad70f: Pull complete
eae8d88d75e0: Pull complete
7fbd4c732645: Pull complete
b2e59bdd1208: Pull complete
d5519147d4e5: Pull complete
512315391b1a: Pull complete
b32d82403bad: Pull complete
b5eb11551d42: Pull complete
02fee8125e6e: Pull complete
Digest: sha256:6616fa9ab36d721c2e3e0e128295f474f1e6f5f7bd04207ce0dc50581ecd4073
Status: Downloaded newer image for php:7.0-apache
f4821286b2156584088f0c29c6e09c6cc4b582c310b6449ca94892bb944e219f

Apacheが起動していることを確認

$ curl http://localhost/
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /
on this server.<br />
</p>
<hr>
<address>Apache/2.4.10 (Debian) Server at localhost Port 80</address>
</body></html>

php70-apacheコンテナへログインする Forbiddenページしか表示されないので、実際にPHPを書いて表示させてみる

$ docker container exec -ti php70-apache bash
$ echo '<?php phpinfo();' > index.php

ホスト⇄コンテナ間でディレクトリを同期する

コンテナを削除した際に同時にそのコンテナ内にあるファイルも消えてしまう

なので、ホスト側とコンテナのディレクトリを同期させて、そこにファイルを書き込む形式をとる

# コンテナを停止
$ docker container stop php70-apache
# コンテナを削除
$ docker container rm php70-apache

新しく新しくディレクトリが同期されるコンテナを作成する ホスト側の同期対象となるディレクト/Users/121799/docker/php70-apache/www コンテナ側はドキュメントルートである /var/www/htmlとする

$ docker run -d -p 80:80 -v /Users/121799/docker/php70-apache/www:/var/www/html --name php70-apache php:7.0-apache
e78a1ac509425b8cf56ee2c0e988a5d5ec39eb539ea8ffefcced4a7ab6bcea76

/Users/121799/docker/php70-apache/wwwにいる場合に

$echo '<?php phpinfo();' > index.php

これで再度、localhostにアクセスしてみる ホスト側で作成されたファイルがコンテナへ正しく同期されていることが確認できる

参考URL

qiita.com

Docker for Macをインストール

公式サイトからDocker for Macをダウンロード https://docs.docker.com/docker-for-mac/install/

安定版をインストール

Stable Channel Get Docker For Mac(Stable)を選択する

  • インストールの確認
$ docker version
Client:
 Version:   17.12.0-ce
 API version:   1.35
 Go version:    go1.9.2
 Git commit:    c97c6d6
 Built: Wed Dec 27 20:03:51 2017
 OS/Arch:   darwin/amd64

Server:
 Engine:
  Version:  17.12.0-ce
  API version:  1.35 (minimum version 1.12)
  Go version:   go1.9.2
  Git commit:   c97c6d6
  Built:    Wed Dec 27 20:12:29 2017
  OS/Arch:  linux/amd64
  Experimental: true

docker run -d -p 80:80 --name {コンテナ名} nginx を実行すると、nginxを80番ポートで起動してくれる docker imageがローカルで見つからない場合は、Docker Hubからpullしてくれる

$ docker run -d -p 80:80 --name webserver nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
e7bb522d92ff: Pull complete
6edc05228666: Pull complete
cd866a17e81f: Pull complete
Digest: sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63d
Status: Downloaded newer image for nginx:latest
6065bc5029d27705e2d0dfd007ff18a40b1625eabd84d6c1dbc36be6ecf2e3ac

nginxが起動しているかを確認するため、Dockerのプロセスをチェックする

$ docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
6065bc5029d2        nginx               "nginx -g 'daemon of…"   3 minutes ago       Up 3 minutes        0.0.0.0:80->80/tcp   webserver

localhostにアクセスしてブラウザ確認する http://localhost

起動を停止する際はdocker container stop {コンテナ名} 起動を開始する際はdocker container start {コンテナ名}}

$ docker container stop webserver
webserver

$ docker container start webserver 

docker container ls -aだと起動していない状態のコンテナも表示することができる

$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
6065bc5029d2        nginx               "nginx -g 'daemon of…"   10 minutes ago      Exited (0) 3 seconds ago                       webserver

コンテナの削除

コンテナを削除したい場合は、docker container rm {コンテナ名} コンテナーは停止していないとエラーするので注意

$ docker container rm webserver
webserver

$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

イメージを削除

イメージを削除したい時は、docker image rm {ID or image name}

$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              3f8a4339aadd        5 weeks ago         108MB

$ docker image rm nginx
Untagged: nginx:latest
Untagged: nginx@sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63d
Deleted: sha256:3f8a4339aadda5897b744682f5f774dc69991a81af8d715d37a616bb4c99edf5
Deleted: sha256:bb528503f6f01b70cd8de94372e1e3196fad3b28da2f69b105e95934263b0487
Deleted: sha256:410204d28a96d436e31842a740ad0c827f845d22e06f3b1ff19c3b22706c3ed4
Deleted: sha256:2ec5c0a4cb57c0af7c16ceda0b0a87a54f01f027ed33836a5669ca266cafe97a

$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

参考URL qiita.com

最強のデータ分析組織を読んで

最強のデータ分析組織

なぜ大阪ガスは成功したのか


はじめに

  • 組織名は「ビジネスアナリシスセンター」

  • 端的には言えば、社内の「データ分析専門組織」


毎回同じ悩みを打ち明けられる

ビジネスアナリシスセンターに訪れる人たちと話しをすると

  • 当社でもデータ分析専門組織を立ち上げたのだが、うまく機能しない

  • これから立ち上げるので、アドバイスが欲しい


第1章

ビジネスアナリシスセンターの実像


経歴がバラバラな多彩なメンバー

  • ビジネスアナリシスセンターには所長を含めて、現在十人が在籍している(2017年7月時点)
  • 20代の若手から51歳のおじさんまで年齢層は幅広い
  • メンバーの大半は理系の大学院を卒業しているが、専門は化学や電気、環境、資源など様々であり、数学や情報工学を専攻していたメンバーは一握り
  • 大学時代に統計学などを全く学んでいないメンバーもいる

分析ツールの選定について

  • プログラミングについても得意なメンバーはいるが、ほとんどコードを書けないメンバーもいる
  • ツールの選定は基本的に、メンバーに任せている

補足しておくと

  • 各メンバーが数学やITに必ずしも詳しくないからと言って、データ分析に欠かせない論理的思考に欠けている訳ではない
  • 論理思考力は非常に高いレベルを有している

メンバーの能力について

  • 以下のような能力に長けている
    • 混沌とした現実問題に対して、「目的」だけを頼りに論点を整理し、その目的を達成するために効果的な「問題設定」ができる力
    • データ分析で得られた結果について、算出の前提条件や結果の不確実性までを踏まえた過不足のない理解をして、それを相手に分かりやすく伝わるように記述・説明できる力
    • 自ら行ったデータ分析や他者によるデータ分析について、本質を突く質問や問いかけを切り出せる力
    • 疑問をきっかけに、頭の中で整理した「理解」を再構造化できる力

ビジネスアナリシスセンターのメンバーは、「意外」な能力を持っている

  • 業務コンサルティング

  • データ分析で業務に役立つには、現場担当者へのヒアリングで業務を理解し、プロセスや費用対効果などの観点から業務プロセスを見直して、問題の所在を突き止める力も持っていなければならない
  • 社内でデータ分析者とみなされているだけでなく、「社内コンサルタント」として見られることもある

データ分析者に必要な3つの力

  • 見つける力

  • 解く力

  • 使わせる力

データ分析者は問題を「解く力」だけでなく、データ分析を活用できる機会を「見つける力」が最初に求められる

その上で、データ分析から得られた結果を現場に「使わせる力」も身につけなければ、ビジネスに貢献できない

データ分析で得られた知見を現場に使わせるプロセスは、現場と一体化しなければいけない


業務改革と業務改善の違いについて

ミッションは「業務改革」であり、業務改善ではない

業務改善

  • 現状の意思決定プロセスは肯定したうえで、既存のプロセスの中で工夫を積み重ねることを指すもの

業務改革

  • 現状の意思決定プロセスの一部を否定し、新たなプロセスに改めること

分析方法という手段へのこだわりがなくなった

  • 方法論へに固執することを忘れ、事業部門が求める成果だけを追求する姿勢に変わっていった


データ分析は手段に過ぎず、「目的はビジネスに貢献すること」


かつては事業部門から来る相談といえば、「こんなデータ分析ができないか」といった、あくまでも分析レベルの話だった


しかし今は「こんな業務課題を抱えて困っている。データ分析で解決できないか」という、ビジネスレイヤーでの相談に変わってきた


ビジネスアナリシスセンターは「攻めのIT」を担うチームとして位置付けられるようになった

  • セキュリティーやコストダウンといった「守り」だけでなく、ITやデータをビジネスに活用していく「攻め」も求めらるようになってきた


「データ分析を受託する」という意識から、「データ分析を武器に事業部門と一緒に業務改革を完遂する」という意識に変わった


取り組みはボトムアップでのアプローチ

  • ひたすら現場でデータ分析の活用を積み重ねてきた

  • ボトムアップで取り組んできたからこそ、強固な社内レピュテーション(信頼)を築き上げられたと考えている


第2章

四種類の「人の壁」を乗り越える


人の壁は「四種類に分けられる」

  • 事業部門と連携する壁

  • 会社の経営に貢献する壁

  • 分析組織のメンバーを育てる壁

  • モチベーションを維持する壁


事業部門との連携が成功への絶対条件


分析結果や予測精度が「すごい」ことと「役立つ」ことは全く違う

  • 山ほどデータを集め、最先端の分析手法を用いて、高精度な予測モデルを作ったり、数多くの分析結果を出してグラフにまとめて報告書に仕立てても、それは「すごい」ことかもしれないが、「役立つ」とは限らない

役立つとは

  • 現場の業務や経営の意思決定に分析結果を使うことで、用いないときよりも望ましい帰結を得られることを指す

高い予測精度やビジュアル的なグラフといったものは、すごいと思わせる「マジック」の効果を持っている

報告会ではすごいと思えた分析結果が意思決定に役立たないとなる最大の理由は 「役立てようとする意図」を持って、データ分析していないから


事業部門に食い込まなければ、課題は見つからない


成果につながらないデータ分析に陥らないようにするには

端的にいえば、現場の業務に役立つ成果を出すように、事業部門と連携してデータ分析を進めること

  • 事業部門とデータ分析組織が一体化するほど密な関係を築くこと
  • データ分析者は事業部門の担当者からお題が出てくるのを待っているような受け身な姿勢ではダメ
  • 事業部門の担当者のところに何度も通って業務課題をヒアリングし、データ分析でできることをディスカッションする

会社全体に貢献してこそ評価される


データ分析専門組織は現場の業務改革に役立つソリューションを提供し、事業部門がそれを使って実際に業務フローや体制の見直しを行うことで初めて、会社に貢献できる


注意点

  • 最新のIT活用事例は、産業界で広く共有すべき大切な情報。一方で、ITは手段に過ぎず、成果ではない

  • ところがメディアの報道はこの1〜2年で過熱する一方で、その影響もあって「手段のすごさ」ばかりが脚光を浴び、「業務改革の成果は手段の優劣で決まる」と錯覚しそうにさえなる


分析者として意識するべきこと

  • 最初に目的ありき、手段は道具であり、分析結果は成果ではない


メンバーの能力だけでなくマインドも育てる

  • 分析者を奮い立たせるのは、自らが「見つけた」課題を「解く」意気込みであり、自ら「解いた」結果を現場に「使わせる」という強い意思が必要

データ分析者は単なる分析だけで終わらず、業務改革につなげるため「見つける」「解く」「使わせる」の3つの力を持たなければいけない

  • 3つの力のうち「解く」については、数学的な分析手法やツールは既に用意されており、書籍やセミナーで学ぶこともできる。
  • しかし分析手法を習得できれば、問題が解けるわけではない。
  • 「特徴量を考える」「分析結果を解釈する」「現場の仮説力と融合する」といったこともできなければいけない
  • これらの力は本を読んで学べるものでなく、OJTで学んで行くしかない

間違ってほしくないこと

  • 事業部門の役に立つことだけを考え、それに必要なければ多様なデータ活用や新たな分析手法に挑戦することは「悪」だと言っているわけではない
  • 様々なデータや分析手法を試す機会は貴重であり、そのチャンスをうまく利用して、しっかりと分析力を培っておくのは、分析者にとって最低限の務めである

第3章

事業部門から信頼と予算を勝ち取る


データ分析が完了した後も、分析結果を現場の業務に導入できなければ、目標を達成したとは認められない。

そうならないように、事業部門の担当者と分析者は運命共同体として協力し合い現場の導入に向けて努力する。


データ分析の費用対効果を見極める合理的なプロセス

  • 分析組織側から費用(必要な予算)を提示して、事業部門はその費用を支払うだけの成果を期待できるかを総合的に判断する


事業部門にデータ分析を提案するには2つの準備が必要

  • 1つはそのデータ分析を実行できるだけの分析者の「能力」
  • もう一つは、データ分析の実現性を事業部門に納得してもらうための「材料」
    • 事業部門からデータ分析の予算を勝ち取るための提案コスト

予算を拠出してもらうためには

  • まずはパワーポイントで事業部門にプレゼンし、事業部門の関心を引き出せたら、必要なデータをもらって「パイロット分析(部分的なデータを用いた分析や部分的な問題に限定した分析)」を行う
  • パイロット分析の結果を事業部門に報告し、その分析結果を基に、本分析の実現性に納得してもらえて、ようやくゴーサインが出て、予算の獲得に至る

意思決定に活用されるデータ分析とは

データ分析から得られた結果を手がかりとして使うことで、それを使わない場合に比べて合理的な意思決定を行えて、それを使わない場合はよりも望ましい帰結を得ること。


第4章

分析組織は経営に必ず貢献できる


全方位外交が基本

全組織と仕事ができる利点を活かす


データ分析専門組織のミッションは、データと分析力で業務課題を解決すること

  • 業務課題は多ければ多いほど、分析力を発揮するチャンスは増える

  • 全方位外交することで、全ての組織の課題を知り、データ分析で会社に貢献できる機会を増やしてきた


組織や業務によって、データ分析を活用できるポテンシャル(データ分析で業績に貢献できる範囲や金額)はマチマチ

  • 相対的に見て貢献度が大きくなるのは「未開拓のエリア」と「大金が動くエリア」


未開拓エリアとは

  • これまでデータ分析をほとんど活用してこなかった業務
  • 未開拓エリアは基本的なデータ分析すらやってこなかったわけなので、データ分析で貢献できるハードルが非常に低い

大金が動くエリアとは

  • 例えば年間1千億円の費用がかかるような大規模な業務
  • 金額が巨額な分、0.1%効率化できるだけで、1億円のコストダウンに繋がる
  • 大金が動くエリアは分析力がお金になりやすい、つまり会社に貢献しやすいエリアと言える

全方位外交による利益は3つ

  1. 全社的に活動していると社内で認知されること
  2. 分析組織のリスクヘッジになること
    • 全事業部門にデータ分析を提供していると、一つの事業環境の変化に翻弄されず、安定的にデータ分析で会社に貢献できる
  3. 仕事のマンネリを防げること
    • 全部門が分析対象となれば、データ分析を活用できる新ネタが枯渇することはなく、挑戦の機会に恵まれ、メンバーには新たな動機付けになる

経営者の視点で分析に臨む

環境変化を敏感に捉える習慣を付ける


事業部門の現場に入り込んでデータ分析を活用する機会を探すボトムアップ型のアプローチ

経営の視点でデータ分析を活用する機会を伺うトップダウン型のアプローチ

  • 前者だけでは森が見えず、後者だけでは個々の木が見えにくい

  • 複眼でデータ分析を活用できるチャンスを見つけようとすることこそ「分析力を武器に成長できる企業になる」


成果をアピールする

自分たちの貢献度をリーダーがPR


成果の説明には2つの観点から

  1. やったことの内容を説明
    • 事業部門に対して自分たちが行った内容を紹介する機会を設けてもらったり
    • 研究開発部門が主催する技術報告会の場を借りて説明してきた
  2. 事業に役立ったことを説明
    • 事業部門がデータ分析を活用した業務改革の成果を経営層に説明するとき、資料に組織名やロゴマークを併記してもらった

社外へのPR

  • どんな形でも成果を説明しても、課題を「解く」ところはみんなに伝わっても、「見つける」「使わせる」の成果はなかなか伝わらない
  • 成果をアピールする打ち手に困り果て、最後に思いついたのが社外へのPRだった

まずは社外の人に価値を認めてもらい、あとから社内でも認知してもらうという「ブーメラン作戦」

  • 日本人は「外の声」に弱いもの
  • 社外で評価されれば、社内からも「社外で高い評価をされているのだから、きっとすごいのだろう」と認知してもらえると考えた

第5章

メンバーの幸福を勝ち取る


成長の道筋を示す

ステップアップの青写真を描く


分析組織のコンピテンシーとは何か

データ分析者に求められるコンピテンシーは、その分析者が働く企業の業種や業態によって異なるので一義的に決めるのは難しい

  • 例えば、アマゾンのような企業では、ビックデータを扱うエンジニアリング力や最先端の分析手法を導入する高度なデータアナリシス力が求められる
  • 一方、大阪ガスのような一般企業では、そういった力よりもむしろ、自社のビジネスにデータを活用する着眼力やそれを実現するための行動力の方が強く求められる。一般的に「ビジネス力」とよばれるもの

解く力とは、データアナリシスとデータエンジニアリングに相当する

それに対し、「見つける力と使わせる力がビジネス力に相当するもの」と定義している


第6章

十八年かけて気づいた三つの無形財産


三つの無形財産

  • ミッション

  • カルチャー

  • レピュテーション

    無形財産は強い信念を持ち、時間を掛けて意識的に行動してこなければ醸成できなかった


私たちのミッション

メンバーの心に根づいて行動が変わる


私たちは「企業内イノベーター」

  • 私たちのミッションが意味することは「業務改善は事業部門にもできる。しかしイノベーション(業務改革)は事業部門では難しい。データと分析力に強いビジネスアナリシスセンターが事業部門を手助けすることで、イノベーションを一緒に実現する」

心に宿していること

  1. 私たちの仕事は社内にイノベーション(業務改革)を起こすこと
  2. データと分析力は手段に過ぎない。使うけれども、手段にはこだわらない
  3. どれだけ素晴らしいイノベーションを考えても、現場が採用してくれなかったら無意味
  4. どういうイノベーションを起こすのか、どうやって現場(人)を動かすのかに知恵を絞る
  5. 成果はイノベーションの中身ではなく、イノベーションの結果のみ

ミッションは言葉で伝えるだけでは、決して人の心に根付かない。仕事を通して成功と失敗を何度も経験しながら、徐々に心に根付いていくもの。


会社のコンピテンシーとなる組織を目指す

会社にとって必要な組織であることと、コンピテンシーとなる組織であることは、意味合いが全くことなる


成果を出すだけでは必要な組織には慣れても、コンピテンシーとなる組織にはなれない。

データと分析力を武器に他社が簡単にまねできないイノベーションを起こし、ライバルに対して圧倒的な優位性をもたらしてこそ、コンピテンシーと言える


レピュテーションを獲得

社内からの財産が最大の財産


レピュテーションの獲得

  • レピュテーションは一朝一夕で築けるものではない
  • レピュテーションは人の心に宿るもの。目には見えない
  • レピュテーションは信頼に値する行動や成果を通してのみ、相手の心に根づくもの
  • レピュテーションは組織単位で勝ち取るものでもない。仕事は最終的には、人と人との信頼関係で決まる。個人単位で信頼を勝ち取っていく活動が欠かせない。

人材やデータやツールはお金を出せば、早期にキャッチアップできるかもしれない。しかしレピュテーションだけはお金を出しても買えない


ただし、レピュテーションは環境の変化には強いが、内部崩壊は簡単に起こる。一度でもいい加減な仕事や逃げ出すような仕事、無責任な仕事をすれば「ビジネスアナリシスセンターは無責任だ」「データ分析はお金だけかかって役に立たない」といった噂が社内に広がる


第7章

分析組織のリーダーに求められるもの


モチベーションの維持は大仕事

データ分析の価値を生み出すのは人


企業内で働くデータ分析者には3つのモチベーションが必要

1. 挑戦するモチベーション

2. 壁を乗り越えるモチベーション

3. 継続するモチベーション


挑戦するモチベーション

データ分析の出発点は、常に「データ分析でこんなイノベーションを実現したい」「データ分析でこれだけの成果を上げよう」といった本人のチャレンジ精神。「できそうなこと」ばかりを考えずに、その殻を破って「できたらすごいこと」に挑もうとするモチベーションを持つことが大切


壁を乗り越えるモチベーション

データ分析は思い通りには進まない。色々な分析手法を試してみても、周囲の期待にこたえられるだけの結果が得られない、せっかく良い分析結果がえられても現場が納得せずに使ってくれない、といったことは日常茶飯事。大きな壁を前にしても打ちひしがれず、「絶対にこの壁を越えてやる」と決意することが、大きなモチベーションにつながる


継続するモチベーション

データ分析のなかに手離れが悪く、いつまでも同じことを続けていかなければならない案件もある。何年も同じデータ分析ばかりしていると、誰しも気が緩み、惰性に流されやすくなる。そうはならず、もっと良いやり方を模索するとか、このデータ分析をとことん極めてやろうといった前向きな姿勢を持てるかどうかが継続するモチベーションになる


データ分析は最初に決めた目標やプロセス通りにうまくいくケースはほとんどない

  • 要件定義に合致したものを決められた納期までに作りあげるSEの仕事とクライアントのニーズしか決まっておらず、要件は自ら考え、うまく行かなかったら何度でもやり直す分析者の仕事。

両者は全く反対の仕事

  • 前者は「目標遵守型」で後者は「目標創造型」である
  • SEにとって、データ分析をする上での最も高い壁は、目標遵守型の価値観に固執せず、目標創造型に頭を切り替え、新たな仕事の進め方を身に着けていくこと

優れた分析者が有能なリーダーになるわけではない

  • 学校の先生のように圧倒的な知識と能力を持ってメンバーに分析手法を教えることではなく、メンバーの心をつかんで、人を動かすこと
  • リーダーも神様ではないので、自らの過ちをメンバーに指摘してもらって自省することは大切
  • リーダーは誰よりも高いモチベーションを持ち、キャリアアップに貪欲で、常に会社を主語にして物事を考え、メンバーや現場とのコミュニケーションを大切にする姿勢を持つことがはるかに大切

中期計画の策定

  • 普段から経営課題や業務課題について社内のいろいろな組織の人たちとコミニケーションをしながら「知る努力」をする
  • 新たなデータ分析やITの活用例について社外の情報にアンテナを張るようにし、無意識のうちに頭の中で両者が交錯するようにする

いざ中期計画策定のタイミングでそのような思索の蓄積がよみがえってそれを起点に、具体性や実現性を深めていく


分析組織のタクティクス

目的は清く、進め方は腹黒く


社内イノベーションを実現できるかどうかは、イノベーションの内容の出来・不出来よりも、むしろ、社内の抵抗をどう乗り越えれるかにかかっている


手段は何であれ、イノベーションを成功させるカギは、リーダーが抵抗を乗り越えることに熱意を持つことと、戦術的に行動すること


いかにして関係者の合意をとりつけるのか、誰が協力的で誰が協力的ではないのか、誰の合意が不可欠なのか

そうしたことを緻密に考え、誰からどんな了承を得ればよいのか、そのためにはどんな説明すればよいのか、どのタイミングでするのか、といったことを考え抜く


まとめ

  • データ分析は手段に過ぎず、目的はビジネスに貢献することを忘れてはいけない
  • 意思決定に活用してもらうには、役立てようとする意図をもっていないといけない
  • 最近は、「手段のすごさ」ばかり脚光をあびて、「業務改革の成果は手段の優劣で決まる」と錯覚している
  • 最初に目的ありき、手段は道具であり、分析結果は成果ではない
  • 社内からのレピュテーションだけは、お金を出しても買えない
  • SEにとってのデータ分析は、目標遵守型の価値観に固執せず、目標想像型に頭を切り替え、新たな仕事の進め方を身に着けていくこと

以上