実体と情報のはざま

のんびりデータサイエンスでもやりますか

癒しの家庭菜園 やっとゴーヤの雌花が出るように!

 体調を崩してから少し時間はかかったが、完全回復した。いやはや、きつかった。最近は、何か癒されるものをそばに置いておきたいとおもうようになった。自分にとって何がいいか、よーく考えてみたけど、巡り廻ってすでにあるものに戻ってきてしまった。子供たち・家庭菜園・物理やデータサイエンスの本・・・必要なのは、これらを味わう若しくは鑑賞する時間だけだったということかな。

 我が家はマンションなので、家庭菜園といっても超小サイズのプランタ。ミニトマト、あばしゴーヤ、バジル、だけです。これだけでも、ちゃんとお世話をするとなると毎日やることあるし、収穫も楽しい。金銭的な元がとれるとかでは全くないけど、癒しの効果はプライスレス。

 特に、ここ数日でやっとゴーヤの雌花が出てきてくれて嬉しい。雄花ばかりで全く雌花が見当たらなかったが、気温が上がってくると雌花が出てくるらしく、ちらほら小さな実が見られるようになってきた。癒される~。

f:id:myuteru:20170712104609j:plain

↓これが雄花。毎日咲きまくる。当然、実はできず。

f:id:myuteru:20170712104620j:plain

ミニトマト、先日の強風に耐え忍び、大きな実に成長。

f:id:myuteru:20170712104632j:plain

↓バジル。妻が種から育てている。葉が元気でこんもりしてきた。

f:id:myuteru:20170712104638j:plain

 というわけで、今日も我が家の家庭菜園に癒された~。

今日はここまで!

プログラミングと仕事と育児で睡眠不足。体調不良に。。

 ここ数か月、睡眠時間を削ってデータサイエンスの勉強をひたすらやってきた。さらに、本業の仕事が忙しくなってきた。さらにさらに、園児の息子が夜中に熱を出してほとんど2日寝なかった。結構大丈夫なもんだな~と思っていたが甘かった。。40代半ばの身体は徐々に疲労がたまって、ついに思いっきりグダグダになってしまった。症状を言葉にするのは難しいが、特徴的なのは強烈な眠気が突然襲ってきて気絶するように一瞬眠ってしまう。2~3秒後にふと気づくとパソコンにはキーボードを連打したあとが・・・。そんな感じが5日は続いた。寝ても回復しなかった。一番酷いときには歩けないほど眠かった。もしこのとき車を運転していたら・・・あー恐ろしい。。

 というわけで、今後は睡眠時間を優先することにした。データサイエンスの勉強は続けるが、ペースを落とさざるを得ない。ずいぶん前に買った本に書かれていることが身に染みた。下の本。あらためて、今後はエッセンシャリズムを実践していきたいと思う。

 その時々で重要なことだけに集中すべし!仕事が忙しかったらデータサイエンスの勉強は一旦停止。息子が熱出したら、仕事は行くけど最小限にとどめてデータサイエンスは一旦停止。仕事が忙しくなく、息子も元気なら、データサイエンスに集中する。

ランダムフォレストのトレーニング部分まで

 めちゃくちゃ時間がかかってしまったが、ランダムフォレストのプログラムが一応完成した。しかし、まだトレーニング(学習)の部分だけ。。いつものようにPythonで書いたのだが、バグにかなり苦しんだ。いつもは紙と鉛筆でプログラミングの前段階までとことん煮詰めるのが自分流なのだが、ランダムフォレストに関してはプログラミングしながら試行錯誤せざるを得なかった。たぶん、フォレストを数式で扱うのが難しいからだと思う。他とは違う何かがある。そこが面白い!
 今回もプログラムはライブラリを使わないで書いた。scikit-learnにランダムフォレストがあるとのことで、私が以前紹介した本ではそれを使っている。なのでコーディング自体は著作権やらは気にしないでコピペできるのだが、コーディングがヘタなせいか非常に長くなってしまったので結果だけのせておく。トレーニング部分しかなくて何かアウトプットが出せるのかって?実は私が目指していたのはテスト部分(機械学習)ではなく、このトレーニング部分にある。ここから、特徴量の重要度が出したかったのだ!何が重要な特徴量かを知る術を持っておけば様々な問題に対応できると思って。以前、身につけた主成分分析(PCA)とは違う観点で特徴量を見ることができるかなと。
 で、今回の結果がこれ。Irisデータセットを使って特徴量の重要度を算出した。以前紹介した手持ちの本(パターン認識のやつ)とは使っている”不純度”の関数が違うから単純比較はできないが、傾向は同じで一安心。ちなみに、本ではジニ係数を用いていて、私はエントロピーを用いた。
f:id:myuteru:20170705013836p:plain
 計算設定は、木の数は500本で深さは1にした。深さを深くしても大差なかった。木の本数は100本ぐらいだと算出毎のブレが若干あった。10本だと結構ブレた。計算が一瞬で終わるのは嬉しいけど。
 次回はテスト(機械学習)部分も完成させたいと思う。そのあとは、いよいよKaggleに挑戦してみようかな。どうかな。あ、また深夜になってもーた。。
今日はここまで!

ランダムフォレストを勉強中!

 ランダムフォレスト、なかなか手強い。一週間くらいかけて今日やっとアルゴリズムを理解したところ。目標では今日あたりにプログラム第一弾が完成しているはずだったのに、何回も立ち止まってしまった。。ネットで拾った英語の論文の解読にも苦労した。これは単なる遠回りだったのだが。今日は、複数の参考資料から得たアルゴリズムと関連情報を自分なりの解釈で書き下しておきたいと思う。

設定:深さDの決定木をT本使う。

①トレーニング

・N個あるトレーニングデータからそれぞれの決定木に対して、n個のサンプルをランダムに非復元抽出する。

・決定木の各ノードtで、P個ある特徴量のうちP'個をランダムに非復元抽する。P'=√Pがちょうど良いかも。

・この中で情報利得が最大になる特徴量とその閾値を選択する。これがランダムフォレストにおける”学習”。(情報利得とは、データを分割する前後における”不純度”の差分のこと。”不純度”とは、情報エントロピージニ係数と呼ばれる値。)

・決定木が深さDまで達するか不純度がゼロになったら木の成長を止める。(テストでは、木の各末端ノードで入力されたデータがどのクラスに属するか判断する。)

②テスト

・あるテストデータを全ての決定木に投入し、個々の木にこのデータがどのクラスに属するか判断させる。最後は多数決で決定する。

 アルゴリズムはざっくりこんな感じの理解でいいかな。あとは、プログラミング作業なのだが、for文if文をどう回すか、データのソートが必要かといったイメージは全然できていない。。Numpyで効率的にやりたいがどうなるだろ。最近仕事が忙しいけど、3日後にはできるかな。

 最後に参考文献で一番役に立った本を紹介。別件で買って本棚に埋もれていたが、あらためてこの丁寧な解説に感謝したい。データサイエンスではしばしば出てくるアルゴリズムの基礎はこれで勉強すると効率が良いと思う。

 Irisデータセットを使っているのもいいね!

 今日はここまで!

炭酸水でダイエット!

 ここ数か月間、データサイエンスにのめりこんで運動らしい運動はしていない。週末は園児の息子と公園でサッカーなどはするが、平日は仕事でもデスクワーク中心で外出などはなし。そんな状況でも、最近取り組んでいるダイエットで成果が出始めてきたので書き残しておく。

 そもそもなぜ痩せなくてはならないのかというと、会社の健康診断で血中脂質が高いという結果がでてしまったことがきっかけ。会社に行けと言われて医療機関を訪れたところ「まずは体重を5%落とすこと。」と言われた。さらに、「痩せられないなら薬を飲み続けなければね。」とも言われショック大。

 そんなわけでダイエットをすることになったのだが、今回はじめて取り組んだのではなく、いろいろ過去に失敗してきた。まず、私のダイエット挑戦歴をふりかえってみた。

・筋トレ → 2日坊主。さらに動いた分食べてしまう。

・ランニング → 1か月程続いたが痩せず。動いた分食べちゃう。

・ロングブレスダイエット → 1か月程で痩せなかったが腰痛には効いた

・納豆をたくさん食べる→ ガセネタだったらしい

・低GI値ダイエット → 1か月程続け若干効果あったが、妻が大変。ニンジンやジャガイモを使わないメニューとか考えるの大変。

黒酢ダイエット → 1か月程続けたが痩せず。酸っぱかった~。。

 ここにデータサイエンスの出る幕はないのだが、”分類”するとすれば、ダイエットとは、「摂取カロリーを減らすこと」「消費カロリーを増やすこと」に分けられる。上記戦歴と自分の特性を加味して私なりに考えたポイントは「摂取カロリーを減らすことに注力する」である。消費カロリーを増やすというのは、総じてお金がかかるし努力も時間も必要なものばかり。だから私の場合、続かない。一方、摂取カロリーを減らすのはただ「あんまり食べなければいい。」というシンプルな努力だけでよい。

 確かに、あれを食べろこれを食べろという現代社会における広告たちの攻撃に対してすまし顔でいられるわけがない。ケンタもマックも大好きだ。しかし、食べることが悪いわけではなく「食べる量が多すぎる。」ことが悪いのだ。日常の消費カロリーがたいして変動しないのだから、これにふさわしい摂取カロリー制限をしていけば、おのずと体重は減っていくはずである。

 ここで登場するのが、”夕食時に炭酸水”である。食べ過ぎているのは主に夕食だと思う。普通、朝食も昼食もゆっくり食べていられないし、仕事などで食べたものが消費されていく可能性も高い。これらに対して、夕食というのは時間的な余裕があるし、その後に運動することもまれである。なので、食後の消費カロリーの割りに多く摂取してしまうことになりやすい。しかし、”夕食時に炭酸水”を飲むことで満腹感が得られる上に、泡の刺激による満足感も得られる。

 その結果、この「”夕食時に炭酸水”で満足感と満腹感」ダイエットにより、2か月で体重7kg減の成果を得ることができた。今も毎日続けている。お金が大変?炭酸水は安い時にスーパーで箱買いするのでペットボトル1本あたり70円弱。他のダイエットに比べれば大したことないと思う。10年くらいず~と82kg前後だったけど今75kgあたり。嬉しい。

 以前はダイエット効果は得られなかったけど腰痛には効果があったロングブレスダイエット。日常に取り入れやすいのでダイエット効果も期待しつつまた始めてみようかなと考えている。こんどはもっと続けられますように…。

 今日はここまで!

散布図行列と主成分分析PCAをまとめ

 (*2017.06.14(18:30)ちょっとプログラムを修正しました。。)最近取り組んできた上記2つの手法は今後も頻繁に使うことになると思う。データサイエンティストを目指して修行を続けるなら。ただ、勉強を続ける中でデータサイエンティストとしての方向性が見えてきた。機械学習のような現実を近似するというか経験から物事を判別するようなアルゴリズムにはあまり興味がなくなってきた。データから実体の本質を見出す作業にこそやりがいを感じる。そういうわけで、今回のタイトルの手法はちゃんと押さえておきたいと思う。
 冗長なんだろうけど何をやっているか分かるプログラムに!
かなり長くなってしまった。。。データ行列のラベルに対するソートを四苦八苦しながらつくったもんで、素人っぽさがあふれだしてしまった。Pythonをはじめて2か月くらいたつだろうか。まだまだ、初心者の域は出ていないようだ。。
 内容はIrisデータセットの散布図行列と主成分分析。過去に両方ともやっているんだけれど、グラフに凡例を入れられなかったり、応用が利かない形になっていた部分をキレイにした。初心者にとっては簡単ではなかったけれど、冗長ながら納得のいくものができた。以前のものとぱっと見では同じかもしれないが、違いはディテールに表れている。カラーマップの使い方やなんかも作成過程でしっかり身についた。
まずは、散布図行列。
f:id:myuteru:20170614010721p:plain
お次が、主成分分析。
f:id:myuteru:20170614010740p:plain

 参考文献は相変わらずコレ。本当にお世話になっている。この本の著者くらいシンプルにコードが書けたらどんなに楽だろうと思う。。

 もう一つおすすめの本はコレ。基本的なことがしっかり盛りだくさん書かれていている。今まで紹介してこなかったけど、実はPythonをうちのパソコンにインストールする前から読み始めていた。はじめて買ったPython本。まじめな一冊。

 あと、プログラミングでくじけそうになった時の息抜きに読んですごく元気になれた本がコレ。すっごく前向きになれる。朝、通勤電車の中で読むと効果的!

 プログラムはコレ。長文注意!*2017.06.14(18:30)ちょっと修正しました。。
開発環境:Spyder(Python 3.6)

import numpy as np
import matplotlib.pyplot as plt

dat=np.genfromtxt('Iris.csv',delimiter=',',dtype=str)#まずは全部読み出し
X=np.copy(dat[1:,1:5])#数値データ行列を抜き出し
X=np.asfarray(X)#型変換str→float64
Y=np.copy(dat[1:,5])#ラベルの抜き出し
Z=np.copy(dat[0,1:5])#特徴量の名前

def sc_matrix(X,Y,Z):#散布図行列
    n=np.shape(X)
    L=np.zeros(n[0],dtype=int)#ラベルの数値化用
    c_name=np.empty(n[0],dtype=Y.dtype)#クラス名の取得用
    k,p=1,False
    for i in range(0,n[0]):
            if p==True:
                c_name[k]=Y[i-1]            
                k=k+1
            p=False
            for j in range(0,n[0]):
                if Y[i]==Y[j] and L[j]==0:
                    L[j]=k
                    p=True
    if p==True:
        c_name[k]=Y[i]
    Ln,k=L.max(),0#Ln:ラベルの種類数
    L_sort=np.zeros(n[0],dtype=int)#順番をソート
    cn=np.zeros(n[0],dtype=int)#クラス数のカウント
    for j in range(1,Ln+1):
        for i in range(0,n[0]):
            if L[i]==j:
                L_sort[k]=i
                k=k+1
        cn[j]=k
    X_sort=np.zeros((n[0],n[1]))
    Y_sort=np.copy(Y)
    for k in range(0,n[0]):
        X_sort[k,:]=np.copy(X[L_sort[k],:])
        Y_sort[k]=np.copy(Y[L_sort[k]])
    plt.figure(figsize=(14,12))#プロット開始
    k=0
    for j in range(0,n[1]):
       for i in range(0,n[1]):
           k=k+1
           plt.subplot(n[1],n[1],k)
           for m in range(0,Ln):
               plt.scatter(X_sort[cn[m]:cn[m+1],i],X_sort[cn[m]:cn[m+1],j],
                           s=15,alpha=0.8,c=plt.cm.cool((m+1)/Ln),
                           label=c_name[m+1])
           if j==n[1]-1:plt.xlabel(Z[i])#cmap=plt.cm.rainbow,c=m*col[cn[m]:cn[m+1]]
           if i==0 :plt.ylabel(Z[j])
           plt.legend(loc='best',fontsize='x-small',markerscale=0.5)
    plt.subplots_adjust(wspace=0.3,hspace=0.3)
    return

def pca(X,Y,Z):#主成分分析
    n=X.shape
    for j in range(0,n[1]):
        X[:,j]=(X[:,j]-X[:,j].mean())/X[:,j].std()#データの標準化
    cov_X=np.cov(X.T)#共分散行列
    ei_val,ei_vec=np.linalg.eigh(cov_X)#固有値と固有ベクトル
    tot=np.sum(ei_val)#固有値の和
    s_ei_val=sorted(ei_val,reverse=True)#固有値の並べ替え
    ver=s_ei_val/tot#分散説明率
    a=np.zeros(n[1],dtype=np.int32)
    b=np.copy(np.abs(ei_val))
    for i in range(n[1]):#固有値の大きい順に並べ替える
        a[i]=np.argmax(b)#bが最大となるインデックスを格納
        b[a[i]]=0#値を取り出したらゼロにする
    G=np.zeros((n[0],2))
    for i in range(0,n[0]):
        G[i,0]=np.dot(X[i,:],ei_vec[:,a[0]])#PC1
        G[i,1]=np.dot(X[i,:],ei_vec[:,a[1]])#PC2
    L=np.zeros(n[0],dtype=int)#ラベルの数値化用
    c_name=np.empty(n[0],dtype=Y.dtype)#クラス名の取得用
    k,p=1,False
    for i in range(0,n[0]):
            if p==True:
                c_name[k]=Y[i-1]            
                k=k+1
            p=False
            for j in range(0,n[0]):
                if Y[i]==Y[j] and L[j]==0:
                    L[j]=k
                    p=True
    if p==True:
        c_name[k]=Y[i]
    Ln,k=L.max(),0#ラベルの種類数
    L_sort=np.zeros(n[0],dtype=int)#順番をソート
    cn=np.zeros(n[0],dtype=int)#クラス数のカウント
    for j in range(1,Ln+1):
        for i in range(0,n[0]):
            if L[i]==j:
                L_sort[k]=i
                k=k+1
        cn[j]=k
    G_sort=np.zeros((n[0],2))
    Y_sort=np.copy(Y)
    for k in range(0,n[0]):
        G_sort[k,:]=np.copy(G[L_sort[k],:])
        Y_sort[k]=np.copy(Y[L_sort[k]])
    plt.figure(figsize=(15,12))#プロット開始
    pcax=np.empty(n[1],dtype=Y.dtype)
    q=np.arange(n[1])
    for i in range(0,n[1]):pcax[i]='PC'+str(i+1)
    plt.subplot(2,2,1)
    for m in range(0,Ln):
        plt.scatter(G_sort[cn[m]:cn[m+1],0],G_sort[cn[m]:cn[m+1],1],
                    s=30,alpha=0.8,c=plt.cm.cool((m+1)/Ln),
                    label=c_name[m+1])
    plt.legend(loc='best',fontsize='small',markerscale=0.5)    
    plt.xlabel("PC1",fontsize=12)
    plt.ylabel("PC2",fontsize=12)
    plt.subplot(2,2,2)
    plt.bar(q,ver,tick_label=pcax, align="center")
    plt.xlabel("principal components",fontsize=12)
    plt.ylabel("explained variance ratio",fontsize=12)
    plt.subplot(2,2,3)
    plt.bar(q,ei_vec[:,a[0]],tick_label=Z,align="center")
    plt.xlabel("PC1",fontsize=12)
    plt.ylabel("eigen vector",fontsize=12)
    plt.subplot(2,2,4)
    plt.bar(q,ei_vec[:,a[1]],tick_label=Z,align="center")
    plt.xlabel("PC2",fontsize=12)
    plt.ylabel("eigen vector",fontsize=12)
    plt.subplots_adjust(wspace=0.2,hspace=0.2)
    return

sc_matrix(X,Y,Z)
pca(X,Y,Z)

次は、少し毛色の違う手法である決定木とかの勉強をしたいな~!
今日はここまで!

pandasを使わないで散布図行列をつくる

 とあるデータセットを入手したとして、初めにやることは何か?まずは、そのままの値をグラフ化。次は、散布図行列を見るのではないだろうか?私の手元にある本では、散布図行列をpandasとseabornを使ってわずか数行でグラフ化している。すごく便利なのだが、なんかブラックボックス感があって…。先日も中途半端にpandasに依存したものをつくってしまったのだが、今回は純粋にpyplotだけでつくってみた。Irisデータセットを使用。
開発環境:Spyder(Python 3.6)

import numpy as np
import matplotlib.pyplot as plt

def scmatrix(X,Y,Z):#散布図行列
    n=np.shape(X)
    L=np.zeros(n[0])#ラベルの処理 色々
    k,p=0,False
    for i in range(0,n[0]):
        if p==True:
            k=k+1
        p=False
        for j in range(0,n[0]):
            if Y[i]==Y[j] and L[j]==0:
                L[j]=k
                p=True
    plt.figure(figsize=(10,8))#プロット開始
    k=0
    L=(L-L.min())/(L.max()-L.min())#規格化
    for j in range(0,n[1]):
       for i in range(0,n[1]):
           k=k+1
           plt.subplot(n[1],n[1],k)
           plt.scatter(X[:,i],X[:,j],s=5,alpha=0.7,
                            cmap=plt.cm.rainbow,c=L)
           if j==n[1]-1:plt.xlabel(Z[i])
           if i==0 :plt.ylabel(Z[j])
    plt.subplots_adjust(wspace=0.3,hspace=0.3)
    return

dat=np.genfromtxt('Iris.csv',delimiter=',',dtype=str)#まずは全部読み出し
X=np.copy(dat[1:,1:5])#数値データ行列を抜き出し
X=np.asfarray(X)#型変換str→float64
Y=np.copy(dat[1:,5])#ラベルの抜き出し
Z=np.copy(dat[0,1:])

scmatrix(X,Y,Z)

ラベル毎に色を変えるところが苦労した。。
f:id:myuteru:20170611010942p:plain
はじめのほうで触れた「私の手元にある本」はコレ。

今日はここまで!