hidekatsu-izuno 日々の記録

プログラミング、経済政策など伊津野英克が興味あることについて適当に語ります(旧サイト:A.R.N [日記])

性別、国籍、年齢の多様性は組織にマイナス

世界の経営学者はいま何を考えているのか」の著者、入山章栄氏の新著「ビジネススクールでは学べない 世界最先端の経営学」に面白い話が載っていた。

ビジネススクールでは学べない 世界最先端の経営学

ビジネススクールでは学べない 世界最先端の経営学

 

 大昔は、学者の書く本と言えば、一般受けのしないお硬いタイトルの本が多かったけれども、スティグリッツの邦訳はじめ、昨今はキャッチーなタイトルも多くなった。一見、トが付く類の煽り書名だが、中身はたいへん面白かった。

特に13章の「日本企業にダイバーシティー経営は本当に必要か」は、センシティブな話題も含み大変興味深い。正直、ビジネスの業界用語に疎い当方としては、ダイバーシティと言われても、お台場のあれしか思い浮かばないのだけれども「人の多様性」を意味する言葉だそうだ。たしかに、女性比率を上げようとか、人員登用の国際化とか、しばしば耳にする話題ではある。

著者(の語る最先端の経営学での知見)によると、まず人の多様性と言っても、

  • タスク型の人材多様性:実際の業務に必要な「能力・経験」、例えば、多様な教育バックグラウンド、多様な職歴、多様な経験など
  • デモグラフィー型の人材多様性:性別、国籍、年齢など、その人の目に見える属性の多様性

の2種類があるそうだ。

そして、それぞれのパフォーマンスについて検証した結果、前者については組織のパフォーマンスにプラスの影響を与えるものの、後者については、組織のパフォーマンスに影響を及ぼさないか、むしろマイナスの影響を与える、との結論が得られた。

経験のバックグラウンドの多様性が組織に良い影響を与えるという結論は、知識の多様化により不確実性の高い出来事への対応や新たなビジネスの展開が容易になるという点でたしかにそうだろうと思える。

一方で性別、国籍、年齢の多様性がむしろマイナスに働くという結論は一見不可思議だ。サンデルNHK DVD ハーバード白熱教室で、多様な国籍や性別を迎えることが大学にとって良いことであるという観点から、アファーマティブ・アクションを擁護したのとは対照的に思える。

後者の原因として挙げられているのは、目に見える属性によって人間関係のクラスタが出来やすいという単純な理由だ。たしかに、世界どこにいっても、○○人街のように国籍でコミュニティができていることが多い。人間関係を見ても、同年齢での繋がりに比して、異なる年齢層が混在したグループというのはそうそうはできないように思える。人類みな兄弟という言葉とは裏腹に、人種、民族、宗教による対立がいまだ無くならないどころか拡大している現状は、前述の結果を裏付けているようにも思える。

大学という見識を広げる場では有効でも、組織という目的を達成するための場においては協調することの方が重要だということなのかもしれない。

それにしても以前、「女性だけで企業を作るべき理由」というエントリを書いたのだけれども、意外に核心を突いていたのかもしれない。同書でも、人脈という観点から、女性の内部昇進にはハンディキャップがあることが紹介されている。

男性社員は男性社員と、女性社員は女性社員とつながりやすく、結果、性別による「ホモフィリー(似たもの同士がつながりやすいこと)な社内人脈」ができるのです。

そして多くの日本企業は男性社員が大半ですから、必然的に「男性のホモフィリー人脈」 が厚くなり、よくも悪くもその中でインフォーマルな会社情報がシェアされるようになります。企業幹部の多くは男性ですので、経営方針、人事制度の変更、社内の異動情報などのインフォーマルな重要情報は、いち早く男性の人脈内で回され、男性はますます情報優位になります。

 同書では、他にも「ブレストのアイデア出しは効率が悪い」、「補完性、囲い込みは企業価値に影響しない一方で、新奇性こそが高い企業価値を実現している」など、他にも面白い話題がたくさん書かれている。文章的にも堅苦しくなく、気軽に読めるので、たいへんお買い得な一冊だ。

低額のベーシック・インカムじゃダメなの?

フィンランドベーシック・インカムを導入するのでは? という観測が流れ話題になっている。

どうも、この話まだ検討中の内容にすぎないということで、この社会実験の実現はまだまだ先のことになりそうなのが残念ではあるけれども。

ベーシック・インカムと聞くと直観的に正しくないと感じてしまったり、究極の社会主義のように思ったりする向きもあるようだ。しかし、ベーシック・インカムには合理的な基礎があることはもっと知られて良いのではと思う。

負の所得税という言葉を聞いたことがあるだろうか。これは文字通り最低の所得税をマイナス(すなわち所得水準が低い人々には給付)する政策で、リベラルの巨人ミルトン・フリードマンが提唱した政策だ。負の所得税の考え方は現在では給付付き税額控除という形で様々な国で採用されている。

ベーシック・インカムは累進的な所得税と組み合わせることで、事実上の負の所得税として機能することが知られている。しかも、負の所得税の欠点である所得把握が不要、要件による排除が起きないという大きなメリットも持っている。社会主義的な政策である一方でリベラルで合理的な裏付けもあるという、なかなかに面白く興味深い制度となっている。

過去に書いた内容の焼き直しになるけれども、個人的には月額2~3万円程度の低額のベーシック・インカムから始めてみてはどうだろうかと思う。「アダプト思考」ではないけれども、何事もビッグバンで始めることはない。良かれと思って始めたことが、失敗するなどよくあるのだから、いったんそのレベルで様子を見るのがいい。

月額2~3万円なんて財源はどうするんだと思われるが、同額分、所得税増税生活保護、年金の減額を行えば、社会保障の枠から外れた人たちだけの財源で済むのだから、たかがしれている。この度、せっかくマイナンバーを導入することになったのだから、国民口座もついでに開設してワンセットで運用すれば給付も納税も効率よい運用が可能になるのではないかと思うのだけれどいかがだろうか。

各データベースで使える識別子

複数データベースに対応したシステムを作ってるとよくわからなくなるのでメモ。

こういう話題だとなにかと OracleANSI標準に沿わないと槍玉にあがるが、MySQLの方が意外と鬼っ子だったりする。

Oracle Database

  • 英字で始まる 英数(A-Z0-9)、アンダースコア(_)、ドル($)、シャープ(#)からなる文字列
  • 30バイト以内
  • 大文字/小文字の区別なし(大文字に正規化)
  • ダブルクォート("識別子")にてエスケープ可能

DB2

  • 英字で始まる 英数(A-Z0-9)、アンダースコア(_)からなる文字列
  • 128バイト以内
  • 大文字/小文字の区別なし(大文字に正規化)
  • ダブルクォート("識別子")にてエスケープ可能

SQL Server

  • 英字で始まる 英数(A-Z0-9)、アンダースコア(_)、アットマーク(@)、シャープ(#)からなる文字列
  • 128バイト以内
  • 大文字/小文字の区別はデータベースの照合順序次第
  • ダブルクォート("識別子")、角括弧([識別子])にてエスケープ可能

MySQL

  • 英数で始まる 英数(A-Z0-9)、アンダースコア(_)、ドル($)からなる文字列
  • 64バイト以内
  • 大文字/小文字の区別なし(ただし、一部の環境では混在不可)
  • バッククォート(`識別子`)にてエスケープ可能、後者は ANSI_QUOTES 有効時はダブルクォート("識別子") も可

PostgreSQL

  • 英字あるいはアンダースコアで始まる英数(A-Z0-9)、アンダースコア(_)、ドル($)からなる文字列
  • 64バイト以内(設定で変更可)
  • 大文字/小文字の区別なし(小文字に正規化)
  • ダブルクォート("識別子")、ユニコードクォート(U&"識\5225+005B50")にてエスケープ可能

*1

H2 Database

  • 英字あるいはアンダースコアで始まる英数(A-Z0-9)、アンダースコア(_)からなる文字列
  • 長さの制限なし
  • 大文字/小文字の区別なし
  • ダブルクォート("識別子")にてエスケープ可能

sqlite

  • 英字あるいはアンダースコアで始まる英数(A-Z0-9)、アンダースコア(_)からなる文字列
  • 長さの制限なし
  • 大文字/小文字の区別なし
  • ダブルクォート("識別子")、バッククォート(`識別子`)、角括弧([識別子])にてエスケープ可能

*1:1/19 ドル記号が抜けていたおり、また、ユニコードクォートによるエスケープ方法もあるため追記修正を行った。

elasticserch で全件データを取得する

elasticsearch で from/to を指定せずに検索したところ、なぜか10件しか取得できない。調べたところ、なんと to のデフォルト値は無制限ではなく 10 件となっている。

なるほど、それならばこの値をものすごく大きい数にすれば解決できなくはない。しかしながら、それを行うとHTTPのプロトコル的に巨大なJSONが返されるに違いなく一旦メモリに確保されてしまうようでは大問題だし、大きな数を指定するというのは適当すぎる。だからと言ってページ分割して問い合わせすると、結果の整合性が保証できない。本当にそんな方法しかないのだろうかと思っていたところ、やはり解決策が用意されていた。

stackoverflow.com

size defaults to 10, so you may also need &size=BIGNUMBER to get more than 10 items. (where BIGNUMBER equals a number you believe is bigger than your dataset)

BUT, elasticsearch documentation suggests for large result sets, using the scan search type.

ただし、この回答で書かれている search_type=scan という記述は現在では古いようで、最新版では以下のように書く必要がある。

curl -XGET 'localhost:9200/test/kens/_search?scroll=1m'

このクエリを発行すると scroll に指定した時間(上記の例だと1分間)検索結果のスナップショットが取られ、最初のページデータと共にそのIDが返される。

{
  "_scroll_id": "cXVlcnlU...zTUE7MDs=",
  "took":2,
  "timed_out":false,
  "_shards":{
    ...

このIDを使い

curl -XGET  'localhost:9200/_search/scroll'  -d'
{
    "scroll" : "1m", 
    "scroll_id" : "cXVlcnlU...zTUE7MDs=" 
}'

のような問い合わせを次々とおこなうことで、残りのデータを順次取得することができる。

時間が経てばこのスナップショットは自動的に消滅するものの、(仕組みを考えれば想像に固くないけれども)状態を保持するコストが大きいので、明示的に削除すべし、とドキュメントには書かれている。

curl -XDELETE  'localhost:9200/_search/scroll' -d '
{
    "scroll_id" : ["cXVlcnlU...zTUE7MDs="]
}'

HTTPはステートレスなプロトコルなので、SQLのフェッチのようなことを実現するのは難しいことを考えれば、こういう仕組みにならざるを得ないのだよなぁ、と思う反面、RDBMS では当たり前に実現できていたことでも REST インターフェイスだと案外面倒なものだな、と思ってしまった次第。

続 React 始めました。相変わらず React.js + Webpack の環境構築。

前回の記事では、Webpack 遅すぎて困ったという話で終わってしまったのだけど、その後、webpack dev serverを使えばリアルタイムプレビューできるよという噂を聞きつけ使ってみたところ、即座に反映することが確認できた。

動作を見る限り、オンメモリで差分を調べながらコンパイルしているように見える。

手順 1. Node.js のインストール

前回同様、Node.jsのサイトから長期サポート版の4.2.2をインストール。

手順 2. package.json の作成

npm init で package.json を生成後、dependencies を記載する。本来は単にインストールすればよいだけのはずなのだけど、webpack 用の babel-loader の依存性の問題でなぜか古いバージョンの babel がインストールされてしまう。現段階ではバージョンを明示する必要があるようだ。

{
  ...
  "dependencies": {
    "react": "^0.14.2",
    "react-dom": "^0.14.2"
  },
  "devDependencies": {
    "babel-core": "^6.1.21",
    "babel-loader": "^6.1.0",
    "babel-preset-es2015": "^6.1.18",
    "babel-preset-react": "^6.1.18",
    "css-loader": "^0.23.0",
    "node-sass": "^3.4.2",
    "sass-loader": "^3.1.1",
    "style-loader": "^0.13.0",
    "webpack": "^1.12.6",
    "webpack-dev-server": "^1.12.1"
  }
}

あとはコマンドラインから一括でインストール。

> npm install

手順 3. webpack.config.js の作成

内容的には前回と変わらないが、パフォーマンスを上げるため、一旦 sourcemap と minify は外した。

wepack-dev-server はファイルを物理的には生成せず、HTTP上に動的に生成されるため、どのURLに生成するかを output.publicPath にて指定している。

module.exports = {
  context: __dirname,
  entry: {
    app: './src/main/js/app.js'
  },
  output: {
    path: './src/main/webapp/js',
    publicPath: '/js/',
    filename: '[name].js'
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          cacheDirectory: true,
          presets: [ 'react', 'es2015' ]
        }
      },
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        loaders: [ 'style', 'css', 'sass' ]
      }
    ]
  }
}

手順 4. npm run から実行できるようにする。

webpack-dev-server はコマンドラインからでも実行できるが、package.json に追記すると簡単に起動できる。

  ...
  "scripts": {
    "start": "npm run dev",
    "dev": "webpack-dev-server --content-base src/main/webapp/"
  },
  ...

コマンドラインから実行。

> npm start

ブラウザで http://localhost:8080/js/app.js を実行すると変換された app.js が表示されることが確認できる。試しに app.js を書き換えると、ファイルが監視されており即座に画面のリフレッシュがかかる。

あとは、JavaEE サーバとどうやって組み合わせて使うか。普通は Apache とかでパスをマウントして同じドメインに見せかけるとかするんですかね? 本番はともかく開発環境でそれは面倒なので、なんとかしたい気もする。

MorphDOM を使って jQuery replaceWith を置き換える

仕事では相変わらず jQuery を使っているのだけれども、画面の書き換えには replaceWith を多用している。昨今のブラウザはものすごく高速なので、さほど遅さを感じるわけではないけれども、それでもタブ移動のような場合には、遅れを感じてしまうことがある(仕事で使っているPCが非力ということもあるけれども)。

VirtualDOMについて調べていたところ、VirtualDOMじゃなくてもそんなに速度差ないんだよ、と主張している人々がおり、そのひとつの実装として MorphDOMが紹介されていた。

VirtualDOMを使う場合、あるべきビューとしての仮想DOMと新しい仮想DOMを比較してパッチを当てる方式を取るため、既存の考え方と共存させるのはなかなかに難儀だと思われる。しかし、本物のDOMを比較してパッチを当てるのであれば、DOM の置換と同じように使えるのではないか……という思いつきで作ってみたのが以下のライブラリ。

https://github.com/hidekatsu-izuno/jquery.morphreplace

使い方は、scriptタグでロードするだけでOK。jQuery の replaceWith と replaceAll はこのプラグインが勝手に置き換えるので、プログラム側の変更は不要です。

残念ながら、ローカルの chrome でデモを動かして見た限りだと、普通の replaceWith との速度差はほぼなし。条件によっては有利/不利あるのかもしれないけれども、今のところ、メリットがよくわからない感じ。

なお、ソースコード読んでもらえればわかるように、jQueryメソッドをコピペして replaceChild を MorphDOM に置き換えるだけというお手軽な内容だったりする。創作性のかけらもない。

React 始めました。あるいは、React.js + Webpack の環境構築。

このブログの説明を読むと「プログラミング」という文字が見えるはずなのだけど、今現在に到るまでまったく書けていないということもあり、ずっと興味を持っていた React.js に手を付けてみることしてみた。

ところが着手してみると、Node.js のメジャーバージョンが上がったり、React.js のツールチェインが変わっていたりと、動かすだけでもひと苦労。結局、React.js と webpack の環境構築だけで一日が終わってしまった。昨今はツール類も多種多様で目的に到るまでに時間がかかりすぎるのが困ったもの。

バックエンドは、慣れている Java で書く予定なので以下の作業は Windows 上の eclipse から Terminal を開いて作業しているけれども、Node.js のインストールを除けば特に環境に依存する内容はないと思われる(はず)。

手順 1.Node.js のインストール

Node.jsのサイトからインストーラーをダウンロードしてインストールする。せっかくなので、最新版の v5.0.0 でやってみるかと試してみたのだけれど、(予期はしていたが)以降の作業でいくつかのモジュールがインストールできず先に進まないので、長期サポート版の v4.2.2 を入れなおし再度試してみたところ、こちらは問題ないようだ。

手順 2. package.json の作成

package.json は node.js のパッケージ管理用の定義ファイル。Maven でいうところの pom.xml みたいなもの。npm init とコマンドを打つと質問に答えながらファイルの作成ができる。

> npm init
...
name: (test) hogehoge
...

各項目の詳細はここの説明を参照のこと。最低限、名前とバージョンがあれば動作は可能なようだ。

手順 3.npm で各種ツールをインストール

React.js のサイトを見ると browserfy を使ってのビルドになっているけれども、後々、CSS の JS へのマージや画像の圧縮なども行いたいため webpack を使う方向とした。npm を使い関係するツール類をインストールする。

> npm install --save react react-dom <s>babel</s> babel-core babel-loader babel-preset-es2015 babel-preset-react webpack style-loader css-loader sass-loader

この記述だけ見るとさもどのモジュールを使えばいいのか最初からわかっているかのような感じだけれど、この構成になるまでずいぶん試行錯誤が必要だった。本家サイトの方にも、webpack の場合のインストールガイドを書いておいてほしい……

オプションの「--save」は必須ではないけれども、付けておくとインストールしたモジュールを package.json に依存関係(dependencies)として自動的に追記してくれる。「--save」の代わりに「--save-dev」を使うとビルド時のみ使う依存関係(devDependencies)として追記される。

依存関係が書かれていると、

> npm install

を実行するだけで、指定されたバージョンのモジュール一式がインストールがされる。なかなかに便利。

一応、各モジュールの説明を簡単にしておくと、

  • react: React.js のコアモジュール
  • react-dom: React Native の登場を受けブラウザに依存する部分が別のモジュールとして独立させたもの
  • babel, babel-core, babel-loader: 元々、ES5 や ES6 から ES3 への変換ツールとして開発されてきたツール。現在は、JS変換基盤として利用されており、React では JSX から JS への変換に使われている(旧来のJSXTransformer は廃止)
  • babel-preset-es2015: Babel の ES6 -> ES3 変換モジュール
  • babel-preset-react: Babel の JSX -> JS 変換モジュール
  • webpack: JS、CSS、画像などをひとつのファイルにパッケージングするためのツール
  • style-loader, css-loader: CSS をパッケージするための webpack 用ローダー機能
  • sass-loader: SASS を CSS に変換するための webpack 用ローダー機能

指定されたモジュールのインストールが完了すると React+ES6 + SASS からなるクライアント・プログラムをひとつの JS ファイルとしてパッケージ化することができる。

手順 4.webpack.config.js の作成

webpack の処理はコマンドラインから行うこともできるけれども、設定量が多くなりがちなので、通常は設定ファイルに記載する。

var webpack = require('webpack');
var path = require('path');

module.exports = {
    context: path.join(__dirname, '/src/main/js'),
    entry: {
        app: './main.jsx'
    },
    output: {
        path: path.join(__dirname, '/src/main/webapp/js'),
        filename: './[name].js'
    },
    module: {
        loaders: [
            {
                test: /\.jsx$/,
                loaders: [ 'babel?presets[]=es2015&presets[]=react' ]
            },
            {
                test: /\.js$/,
                loaders: [ 'babel?presets[]=es2015' ]
            },
            {
                test: /\.scss$/,
                loaders: [ 'style', 'css?sourceMap', 'sass?sourceMap' ]
            },
            {
                test: /\.css$/,
                loaders: [ 'style', 'css?sourceMap' ]
            }
        ]
    },
    devtool: '#source-map',
    plugins: [
        new webpack.optimize.UglifyJsPlugin() // minify
    ]
}

path モジュールを使わずに、__dirname + '/src/main/js' と書いたり loaders ではなく loader を使うと意味不明なエラーを出して異常終了するなど、とにかく webpack には何度も躓いたが、ここまで来ればようやく開発に入れる。

それにしても、Node.js 系のプロジェクトはプロジェクトのルートフォルダが設定ファイルだらけでとても萎える。.NET の設定ファイルのように package.json に統一的に設定を書けるくらいのほうがわかりやすいと思うのだけど。GulpとかBabelの設定とか始めるとさらに増えてしまうんだろうなぁ。

手順 5.npm run から実行できるようにする。

今回は、各モジュールをローカルにインストールしたので、webpack コマンドは直接使えない(パスが通っていない)。そこでnpm で依存もタスクも一元化する を参考に project.jsonスクリプトのエントリを追加する。

{
    ...
    "scripts": {
      "build:webpack": "webpack"
    }
}

これで、

> npm run build:webpack

で、webpack の処理が実行できる。ただ、今回使ってみて気付かされたのは webpack 遅すぎ。Ant は起動が遅くて……、などと言っていた時代が嘘かと思うくらいの実行時間(処理に 1分近くかかる)。進歩なのか退化なのか、はたまた歴史は繰り返すというべきか。

2015/11/12追記

babelパッケージは旧パッケージで、現在は babel-core のみインストールすればいいようだったので、該当の箇所には打ち消し線を入れた。また、webpack は相変わらず遅いが、loaders の指定に include で該当のパスを書くか、exclude で node_modules を除くと半分くらいの時間で終わるようになった。とはいえ、それでも 30 秒なので実用に耐えない……。google closure でも commonjs については対応できるので、そっちにしようかと思案中。