技術とか戦略とか

証券レガシーシステムを8年いじってから転職した普通のSEによるブログ。技術のみではなく趣味の戦略考察についても。PCから見た方が色々見やすいと思います。

リスクを抑える分散投資の考え方

自分自身は投資らしい投資はあまりしていないのですが、職業柄ある程度の知識はあります。
戦略を考える上で参考になる考え方も少なくないので、他分野への応用が効きそうな汎用的な話を中心に紹介していこうと思います。今回は、分散投資の考え方について紹介していきます。
 
投資先を1つに絞るのはリスクの高い考え方です。
例えば、冷房メーカーのA社にのみ投資をしていた場合、雨ばかりで冷夏の年に株価が下がり、損してしまいます。
しかし、雨具メーカーのB社にも投資していた場合、冷夏の年にはB社の方が株価が上がるので、A社の損失をB社の利益でカバーすることができます。
イメージ図としては以下の通りです。

 

https://cdn-ak.f.st-hatena.com/images/fotolife/a/akira2kun/20190112/20190112182029.jpg

このように、分散投資の本質は、様々なシナリオに対応できるようにする、という所にあります。
「日本円の貯金ばかりなのは却ってリスクが高い」と言われるのは、財政危機や経済成長で日本円がインフレ(今の1円の価値が将来的に1円未満になってしまう)になるシナリオに弱くなるからです。
また、2008年にリーマンショックが起こったのは、信用力が低い個人の住宅ローンをかき集めて作った商品(サブプライムローン)の収益に証券会社が頼り切っていたためです。信用力が低い個人の住宅ローンを信用力が低い個人の住宅ローンで分散投資していたような形なので、住宅ローン会社が貸付に消極的になりことによりローンを返せなくなる人が次々と現れるシナリオに対応できませんでした。
 
応用としては、各々の投資先への投資額を調整することで、利益が出る確率を高めたり、リスクをより抑えたりすることができます。
先のシナリオがある程度読める場合は、そのシナリオが実現した時に利益が出る投資先への投資額を増やし、他の投資先への投資額を減らすことで、リスクを取りすぎることなく利益が出る確率を高めることができます。先のA社・B社の例で言うと、猛暑が予想される時にA社への投資額を増やすことで、利益が出る確率を高めることができます。
また、値動きが激しい投資先がある場合は、その投資先への投資額を減らし、他の投資先への投資額を増やすことで、値動きの激しさを投資額の少なさで相殺し、全体で見た場合の値動きを穏やかにすることができます。先のA社・B社の例で言うと、A社の値動きが激しい場合は、A社への投資額を減らしB社への投資額を増やすことで、値動きが激しいA社の影響を抑え、値動きが穏やかなB社の影響を強め、結果として値動きを穏やかにすることができます。これをしないと、A社の値動きの影響が強くなるため、猛暑の時には利益が出やすくなる代わりに冷夏の時には損失が出やすくなり、全体としてリスクを抑えきれなくなります。

サクラエディタ:UNIXの改行コード(LF)をWindowsの改行コード(CRLF)へ変換(改行コード混在考慮)

改行コードが混在しているファイルについて、UNIXの改行コード(LF)をWindowsの改行コード(CRLF)へ変換する(統一する)のに意外と頭を使ったので、メモします。
下記のマクロを使えば変換ができます。
 
【マクロ】
・LF→CRLF.mac
S_ReplaceAll('([^\\r])\\n', '${1}\\r\\n', 60); // すべて置換
S_ReplaceAll('^\\n', '\\r\\n', 60); // すべて置換
S_ReDraw(0); // 再描画

【説明】
・単純に\nを\r\nにするだけだと、元から\r\nの行が\r\r\nになってしまう。
・マクロの1行目で、\r\n以外の\nを\r\nに置換している。
 ()と${1}を使うことで、文末の一文字が消えるのを回避する。
・文頭が\nである行(空行)については、マクロの2行目で対応する。

java:thisで指定されたメンバ変数が自クラスにない場合、スーパークラスを参照しにいく

javaでは「thisで指定されたメンバ変数が自クラスにない場合、スーパークラスを参照しにいく」という挙動になると聞いたので、やってみました。
確かにそうなりました。
 
【テストコード】
・Main.java
package jp.co.thistest;
public class Main {
    public static void main(String[] args) {
        ThisClass obj = new ThisClass();
        SpecializeClass obj2 = new SpecializeClass();
        obj.method(10);
        obj2.method(10);
    }
}

・ThisClass.java
package jp.co.thistest;
public class ThisClass {
    int a = 20;
    int b = 30;
    public void method(int a) {
        System.out.println
        ("■引数から与えられた値を参照(期待値10)");
        System.out.println(a);
        System.out.println
        ("■自クラスのメンバ変数をthis参照(期待値20)");
        System.out.println(this.a);
        System.out.println
        ("■自クラスのメンバ変数をthis参照(期待値30)");
        System.out.println(this.b);
    }
}

・SpecializeClass.java
package jp.co.thistest;
public class SpecializeClass extends ThisClass {
    int b = 40;
    public void method(int a) {
        System.out.println
        ("■引数から与えられた値を参照(期待値10)");
        System.out.println(a);
        System.out.println
        ("■スーパークラスのみメンバ変数をthis参照(期待値20)");
        System.out.println(this.a);
        System.out.println
        ("■スーパークラスのみメンバ変数をsuper参照(期待値20)");
        System.out.println(super.a);
        System.out.println
        ("■両クラスにあるメンバ変数をthis参照(期待値40)");
        System.out.println(this.b);
        System.out.println
        ("■両クラスにあるメンバ変数をsuper参照(期待値30)");
        System.out.println(super.b);
    }
}

【実行結果】
■引数から与えられた値を参照(期待値10)
10
■自クラスのメンバ変数をthis参照(期待値20)
20
■自クラスのメンバ変数をthis参照(期待値30)
30
■引数から与えられた値を参照(期待値10)
10
スーパークラスのみメンバ変数をthis参照(期待値20)
20
スーパークラスのみメンバ変数をsuper参照(期待値20)
20
■両クラスにあるメンバ変数をthis参照(期待値40)
40
■両クラスにあるメンバ変数をsuper参照(期待値30)
30

機械学習の手法が多すぎて良く分からないので調べてみた

表題の通り、機械学習の手法が多すぎてどれを使えば良いか良く分からなかったので、調べてみました。
私が調べた限りでは、下記のページが良くまとまっていると思いました。
 
代表的な機械学習手法一覧 - Qiita

https://qiita.com/tomomoto/items/b3fd1ec7f9b68ab6dfe2

 
各々の手法について、Pythonのライブラリを使用すれば実装できそうです。
以下は使用できるライブラリの例です。
各々の手法についてサンプルプログラムっぽいものが見つかったらその時点で調べるのをやめているので、網羅性はあまりないですが…。

 
【教師データあり】
1.回帰
 ・(一般化)線形回帰
  sklearn.linear_model等
  
 ・ロジスティック回帰
  sklearn.linear_model等
  
 ・サポートベクターマシーン(SVM)
  sklearn.svm
 
2.木
 ・決定木(CART)
  sklearn.tree等
  
 ・回帰木
  sklearn.tree等
  
 ・ランダムフォレスト
  sklearn.ensemble等
  
 ・勾配ブースティング木
  sklearn.cross_validation等
 
3.ニューラルネットワーク(NN)
 ・パーセプトロン
  sklearn.neural_network等
  
 ・畳み込みニューラルネットワーク(CNN)
  sklearn.neural_network等
  
 ・再帰ニューラルネットワーク(RNN)
  TensorFlow等
  
 ・残差ネットワーク(ResNet)
  TensorFlow等
 
4.ベイズ
 ・単純ベイズ(ナイーブベイズ)
  sklearn.naive_bayes等
 
5.時系列
 ・AR,MA,(S)ARIMAモデル
  statsmodels.tsa等
  
 ・状態空間モデル
  statsmodels.api
 
6.クラスタリング
 ・k近傍法(KNN)
  sklearn.neighbors等
 
7.アンサンブル学習
 ・ブースティング
  ※勾配ブースティング木ばかり出てくるのでよくわかりませんでした
  
 ・バギング
  ※ランダムフォレストばかり出てくるのでよくわかりませんでした
  
【教師データなし】
1.クラスタリング
 ・階層型クラスタリング(ユークリッド距離*ウォード法など)
  scipy.cluster.hierarchy等
  
 ・非階層型クラスタリング(k-meansなど)
  sklearn.cluster等
  
 ・トピックモデル(LDAなど)
  gensim等
  
2.NN
 ・自己組織化マップ(SOM)
  somoclu等
  
3.その他
 ・アソシエーション分析
  pyfpgrowth等
  
 ・協調フィルタリング(アイテムベース、ユーザベースなど)
  ※ライブラリは特に見つかりませんでしたが、実装例はありました。
   Pythonで簡単な協調フィルタリングを実装するためのノート - Qiita
   https://qiita.com/hik0107/items/96c483afd6fb2f077985

 

Python:scikit-learnのニューラルネットワークを試してみた(テストデータ付き)

何番煎じかわかりませんが、scikit-learnというライブラリを用いて、ニューラルネットワークのプログラミングを試してみました。
「トレーニングデータで学習→テストデータで学習結果を確認→学習したニューラルネットワークを保存→学習したニューラルネットワークをロード→ロードしたニューラルネットワークを使って処理する」という一連の流れを試しています。
 
今回は、20~24歳の体力測定結果から、男性か女性かを切り分けるというのを試してみました。
 
プログラムを作るにあたり、主に以下のページを参考にさせていただきました。
 
Windowsでscikit-learn(sklearn)をインストールしてirisの予測をサクッとするまで - SuprSonicJetBoy's blog

http://blog.suprsonicjetboy.com/entry/2017/08/30/171308

 
scikit-learnのディープラーニング実装簡単すぎワロタ  新規事業のつくり方

http://aiweeklynews.com/archives/50172518.html

 
scikit-learnで学習した分類器をjoblib.dumpで保存するときはcompressをTrueにするとファイルが一つにまとまって便利 - 洋食の日記

https://yoshoku.hatenablog.com/entry/2017/03/16/003000

 
ちなみに、今回試したニューラルネットワークの他に、線形回帰や決定木等もscikit-learnを用いて行うことができます。
ライブラリを使うだけで統計解析ができるなんて良い時代になりましたね。
もちろん、使いこなすには、統計的な知識やライブラリの知識が必要になりますが…。
 
【プログラム】
・AITest.py
# scikit-learnから必要な関数をインポート
# 事前にPythonとAnacondaをインストールしておく
# ライブラリのパスは各自の環境に合わせて変更する
# importで落ちる場合はコマンドプロンプトで下記を実行
# 「pip uninstall numpy」→「pip install numpy」
# 「pip uninstall scipy」→「pip install scipy」
# 「pip uninstall scikit-learn」→「pip install scikit-learn」
import sys
sys.path.append("C:/Anaconda3/Anaconda3/Lib/site-packages")
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from sklearn.externals import joblib
import numpy as np

# ファイルから入力値と正解値を取得し、リストへ格納
# ファイルはCSV形式
# 1項目目:入力値…握力(kg)
# 2項目目:入力値…上体起こし(回)
# 3項目目:入力値…長座体前屈(cm)
# 4項目目:入力値…立ち幅とび(cm)
# 5項目目:正解値…性別(男性は1、女性は2)
x_data = # 入力値のリスト
y_data =
# 正解値のリスト
file = open("C:/tmp/physical_data.txt","r")
line = file.readline()
while line:
    param = line.rstrip().split(",")
    input = param[:4] # 入力値(1~4項目目)
    answer = param[4] # 正解値(5項目目)
    x_data.append(input)
    y_data.append(answer)
    line = file.readline()
file.close()

# 学習データとテストデータに分割
# (トレーニングデータ8割、テストデータ2割)
x_train, x_test, y_train, y_test = train_test_split(
    np.array(x_data, dtype=np.int32),
    np.array(y_data, dtype=np.int32),
    test_size=0.2
)

# ニューラルネットワーク生成
clf = MLPClassifier(
    max_iter=1000
)

# トレーニングデータで学習
clf.fit(x_train,y_train)

# テストデータで学習結果をテスト
result = clf.predict(x_test)
print("■テスト結果の見方")
print("     出力値")
print("       1  2")
print(" 正解値 1")
print("     2")
print("■テスト結果")
print(confusion_matrix(y_test,result))

# 学習結果を保存
# (上手く行った学習結果を使い回すため)
joblib.dump(clf,'C:/tmp/physical_learn.dmp',compress=True)

# 実務ではここから下は別のpyファイルになる
# 学習結果をロード
clf2 = joblib.load('C:/tmp/physical_learn.dmp')

# ロードした学習結果を用いて性別を切り分けてみる
x_test2 = np.array([[54,30,42,228],[29,21,43,164]])
result2 = clf2.predict(x_test2)
print("■上手く行った学習結果をロードして試した結果")
print("出力値:",result2[0],"、正解値:1")
print("出力値:",result2[1],"、正解値:2")


【テスト結果の一例】

■テスト結果の見方
     出力値
       1  2
 正解値 1
     2
■テスト結果
[[18  0]
 [ 1 21]]
■上手く行った学習結果をロードして試した結果
出力値: 1 、正解値:1
出力値: 2 、正解値:2

Process finished with exit code 0


【参考:入力データ】

続きを読む

人間のカンが持つ利点と問題点

AI全盛の今においても、人間のカンというものは侮れないものです。
 
単純な状況で100%正しい結論を素早く導く、ということにおいては人間よりもコンピュータの方が優秀です。
人間のカンは、曖昧な状況である程度妥当性のある結論を素早く導くことができる、という意味で優秀です。
将棋のトップ棋士は、複雑な中盤の状況でも、次に指す手の候補を2~3つにすぐに絞り込むことができます。
これは近年のAIでもなかなか真似できるものではありません。
(手元に文献がないので、裏付けとなる数値は出せないのですが)
 
将棋のAIは発展を続け、ついにトップ棋士をも上回る強さを身に付けました。
しかし、将棋は
・ルールと勝利条件が明確である
・プレイヤーは二人のみである
・どちらかが勝ちどちらかが負ける(winwinという概念がない)
・ゲーム上で示される選択肢を新たに生み出せない
・ゲーム上で示される選択肢が具体的であり、数え上げられる
・相手が持つ選択肢を把握することができる
・乱数等の不確定な要素がない
・プレイヤーは個人である(チーム戦ではない)
という特徴があり、ゲームとしては単純な部類に入ります。
このような単純なゲームであっても、数十年の間トップ棋士はAIよりも強かったのです。
数十年の研究の末に将棋で人間がAIに負けた、しかしそれまでは負けなかった、という事実は、人間のカンの限界を示しつつも、人間のカンの優秀さも示しています。
 
仕事では、人間のカンがあらゆる場面で使われています。
仕事でよく「職人技」と呼ばれることがありますが、これは人間のカンが成せる業です。
例えば、企業が行うセキュリティ診断では、脆弱性診断ツールを使いつつも、経験豊富なセキュリティの専門家が判断を行うことで、短時間でセキュリティの問題点を洗い出すことができます。
また、ソフトウェア開発手法の一つである「アジャイル開発」では、直感に基づいたスピーディな判断が推奨されています。
 
しかし、人間のカンを用いた判断には、ある種の誤りが生じやすいという問題があります。
例えば、「利得よりも損失の方が強く感じやすい」「生起確率が低い事象を過大評価し、生起確率が高い事象を過小評価する」等です。
これについては、行動経済学という分野の学問でまとめられています。
どのような誤りが生じやすいのかを知ることができるので、人間のカンの誤りに対する対策も立てやすくなります。
私のブログでは、以下の記事に簡単にまとめています。
本当に簡単にしかまとめていないので、気になる項目があれば自力で調べてみることをお勧めします。
 
行動経済学の用語を1行ずつまとめる記事

https://akira2kun.hatenablog.com/entry/2018/08/08/000720

情報処理技術者試験対策「QC七つ道具・新QC七つ道具」

QC七つ道具と新QC七つ道具は、品質管理を行う時に使う手法です。
現在の品質の状況を図や表で表し、問題点を明らかにすることで、品質の改善に繋げようとするものです。
 
私の前職が品質の意識が高い職場であったので、仕事をする上でも勉強しました。
品質分析に時間がかかるので実務ではなかなか使う機会がないかもしれませんが、少なくとも品質管理の発想は知っておくに越したことはありません。
 
QC七つ道具・新QC七つ道具の内容は以下の通りです。
情報処理技術者試験対策ということで、説明文は実際の試験で使われたものを引用します。
(「散布図」「アローダイアグラム」は一部のみ引用し、私の言葉で補っています)
(出題実績のない「チェックシート」「層別」「マトリックス図」「マトリックスデータ解析」は私の方で文章を書いています)
 
【QC七つ道具】
ヒストグラム
 収集したデータを幾つかの区間に分類し,
 各区間に属するデータの個数を棒グラフとして描き,ばらつきをとらえる。
 
・管理図
 時系列的に発生するデータのばらつきを折れ線グラフで表し,
 管理限界線を利用して客観的に管理する。
 
・チェックシート
 チェックするべき項目を表として表すことで,
 抜けや漏れを発見する。
 
パレート図
 データを幾つかの項目に分類し,出現頻度の大きさの順に棒グラフとして並べ,
 累積和を折れ線グラフで描き,問題点を絞り込む。
 
・特性要因図(フィッシュボーンダイアグラム)
 原因と結果の関連を魚の骨のような形態に整理して体系的にまとめ,
 結果に対してどのような原因が関連しているかを明確にする。
 
・散布図
 ある要因の値xと品質特性の値yとの関係をプロットしたもの。
 相関関係を見るために使用する。
 (右上がりなら正の相関、右下がりなら負の相関、どちらでもなければ無相関)
 
・層別
 たくさんのものを,ある特徴によってグループ分けする。
 
【新QC七つ道具】
連関図
 複雑な要因の絡み合う事象について,
 その事象間の因果関係を明らかにする方法である。
 
親和図
 収集した情報を相互の関連によってグループ化し,
 解決すべき問題点を明確にする方法である。
 
・系統図法
 目的・目標を達成するための手段・方策を順次展開し,
 最適な手段・方策を追求していく方法である。
 
・アローダイアグラム法
 プロジェクトが完了するまでに最短で何日を要するかを把握するため,
 各作業(ノード)を所要日数(矢印)で結んだもの。
 所要日数ゼロの場合はダミー作業(点線の矢印)として扱う。
 
マトリックス図法
 多くの事象や要因等を行と列にして表し,
 それぞれの連関について表中で重み付けする方法である。
 
マトリックスデータ解析法
 ある主成分をX軸,他のある主成分をY軸におき,
 二つの主成分の値に応じて二次元平面図(X-Y平面図)を描き,
 問題とその要因の関係をわかりやすく示す方法である。
 
・PDPC(Process Decision Program Chart)法
 事態の進展とともに様々な事象が想定される問題について対応策を検討し,
 望ましい結果に至るプロセスを定める方法である。
 
----------------------
 
なお、手法の使い方を詳しく知りたい場合は、以下のサイトがお勧めです。
 
品質管理の知識

https://www.sk-quality.com/

 
----------------------
目次

https://1drv.ms/b/s!AivF3bzWXOzuhG1Xk5hscKYqkLkM