実体と情報のはざま

いつかデータサイエンティストになって世界を読み解く仕事がしたい!

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

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

設定:深さ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)ちょっと修正しました。。

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データセットを使用。

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
はじめのほうで触れた「私の手元にある本」はコレ。

今日はここまで!

PCA(主成分分析)を手中に収める!

 機械学習を学んでいて、やたらと出てくるのがこのPCAというやつ。どの文献でもさらっと事前準備みたいな扱い。「まずはPCAで次元を削減してから・・・」なんてよく出てくる。ありきたりな手法のようですな。しかし、データサイエンス初心者の私としては、なんであれ一通りは理解しながら前へ進みたい!今回は、このPCAの学習と実装について書き残すことにする。
ライブラリを使えば簡単ですが!
 Pythonではおなじみのsckit-learnには簡単に実装可能なライブラリが用意されている。しかし、いつものことながら理論的な部分もしっかり学びたいので、ライブラリは使わないでやりたい。ただ、ここから少し深みにはまった。PCAの理論を解説している文献はいくつもネットに転がっているものの、理論の理解から実装まで導いてくれるものはなかった。理論の部分はネットの参考文献でよさそうなものを数件選んで勉強した。実装の部分は、自分の本棚からPython機械学習プログラミング 達人データサイエンティストによる理論と実践 (impress top gear)を引っ張り出してきて参考にした。参考にはしたものの出来上がったものはちょっと違うものになっている。というのも、自分が理解した理論の流れに沿ってプログラミングをしていくと、どうしても参考文献とは異なってしまうから。ここに自己流が入ることが不安でもあり楽しいところでもある。
できた!けどあってるのか!?
 データセットはデータサイエンスでは有名なIrisとwineを使った。前者は以前kaggleから入手したが、wineはUCI Machine Learning Repositoryから入手した。このサイトも有名。実はIrisデータセットはここにもある。できたPCAのプログラムはこんな感じ。

import numpy as np
import matplotlib.pyplot as plt

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

def PCA(X):
    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]])
        g[i,1]=np.dot(X[i,:],ei_vec[:,a[1]])
    return ver,ei_vec,a,g

ver,ei_vec,a,g=PCA(X)
n=X.shape
##############以下、グラフ化作業
#rmd=np.dot(np.dot(ei_vec[:,a[1]],cov_X),ei_vec[:,a[1]])
plt.figure(0)
plt.bar(np.arange(n[1]),ver[0:n[1]])
plt.xlabel("principal components")
plt.ylabel("explained variance ratio")
plt.figure(1)
plt.bar(np.arange(n[1]),ei_vec[:,a[0]])
plt.xlabel("PC1")
plt.ylabel("Y")
plt.figure(2)
plt.bar(np.arange(n[1]),ei_vec[:,a[1]])
plt.xlabel("PC2")
plt.ylabel("Y")
plt.figure(3)
for i in range(0,n[0]):
    if Iris[i+1,5]=='Iris-setosa':
        plt.scatter(g[i,0],g[i,1],color='b',alpha=0.7)
    elif Iris[i+1,5]=='Iris-versicolor':
        plt.scatter(g[i,0],g[i,1],color='r',alpha=0.7)
    elif Iris[i+1,5]=='Iris-virginica':
        plt.scatter(g[i,0],g[i,1],color='g',alpha=0.7)
plt.xlabel("PC1")
plt.ylabel("PC2")
plt.legend()

 結果はこんな感じ。次元削減というよりは教師なし分類として見ると、グラフが単色で見分けがつくのは青いやつだけかな。ところで、他のサイトで同じことをやっているはずのプロットと若干異なる。なんで?よく見ると、ネットに転がっている同様の結果どうしも若干違っている!そんなものなのか?今はいいや。いつか振り返ってみよう。プログラム中には分散説明率のグラフも入っているので忘備録として解説を入れたいが説明が長くなりそうなので省略。
f:id:myuteru:20170607232450p:plain
 つぎに、wineデータセットを使った場合の結果。これも教師なし分類としてみると単色で見分けがつくのは緑だけかな。ちなみに、上のプログラムのdef以外の部分をwineデータセットに合わせてちょいといじるだけでできる。
f:id:myuteru:20170607233029p:plain
 今回は使い古されてなお現役で機械学習の前座で重宝されているPCAを実装した。この手法自体をちょっと軽んじてたけど、実際に四苦八苦しながらやってみると、初めに考えた人のすごさや奥深さを知ることになり大変に勉強になった。。
 おっと、日付が変わってしまう!今日はここまで!

kaggleと日経BigDataのサイトについて

 今日は一旦プログラミングから目を離して、最近の情報の中で私のアンテナに引っかかったもの2点について書いておきたい。

①kaggleにPrizeMoney $1,200,000 のCompetitionが出たこと。

②「日経ビッグデータ」ってやつの存在を知ったこと。

 数日前に、kaggleのサイトを楽しんでいたらコンペにとんでもない数字が並んでいてドキッとした。それが①の件。他と桁が違うじゃないっすか!Overviewを読んでみると、Zillowというアメリカの有名不動産会社の住宅価格を予測する懸賞案件らしい。金額の大きさから話題性を引き出したいという狙いもあるのではないかとは思うが、データサイエンス業界にとっては嬉しいこと。どんどんやってほしい。

 kaggleではすでに突っ込んだdiscussionが行われている様子で、Zillowの担当者がKagglerたちの疑問に答えるなど活発な意見交換もあるようだ。読んでいてすごくワクワクする。私も早く参加できるレベルになりたい!英語力も含めて。。このブログでもちゃんとした翻訳で面白いやりとりのポイントを紹介したいのだけれど、英訳に確信が持てないので今はまだ無理。面白そうな議論てのは例えば、predictionに他から持ってきたデータを使っちゃっている人を指摘しているやつとかね。

 次は②の話。データサイエンティストを志す者としては常識がないと思われても仕方ないのだが、日経ビッグデータというメジャー誌の存在をつい先日まで知らなかった。たまたま勤めている会社(非IT系)のリサーチ部門が書いたレポートにその名前があったのがきっかけでサイトを見てみた。

 できれば定期購読したいところだけど、私のような平均的な会社員が個人で契約するのはちょっとハードル(嫁のご機嫌)が高すぎる。なので、今はサイトのトップページ右側にあるMostPopularの記事ランキングをチェックしている。これだけでも結構面白い。

 基本的に産業向けなので、学術的に最新の技術がどうとかは出てこない。それはそれで良かったりする。どんなに高度な技術であっても、広く社会に普及し世の中で役に立たなくては面白くないからね。私の場合、相対性理論がGPS技術で活用されていることを知ったときは一瞬テンションが上がって再学習した経験がある。

 上記2つのサイトには、データサイエンスはデータがあってなんぼの世界であることをあらためて気づかされる。あたりまえだが。データがあって初めて成立する。課題が先かデータが先かは両方よくある話で、課題を克服するためにデータをとって解析する場合とデータを分析した結果を見て課題を発見する場合の両方とも世間では散見される。私は、十分な実力が身についた暁には、与えられたデータからではなく、課題からデータを見つけ場合によっては必要なデータを取りに行く(とってもらうよう要請する)ような積極的な問題解決法としてデータサイエンスを使いたいと考えている。…思想は立派ですね。実力は序の口なのにね。。

 今日はここまで!

データセットの分割

 データサイエンスの初めの一歩として、有名なIrisデータセットをいじり始めている。先日はデータの中身をプロットしたり散布図行列をつくってみたりした。データが俯瞰できたので、さっそく何かしらの機械学習をやってみようと思ったのだが、その前にやることがあった。
Numpyに最適なコマンドが!
 機械学習に入る前にデータセットをトレーニング用とテスト用に分割しなくてはならないようだ。そりゃそうか。以前Kaggleからダウンロードしてちょっと覗いてみたTitanicのデータセットチュートリアル用だからトレーニングとテストが初めから分割されていた。しかし、通常は一連のデータがぶわ~と並んでいるだけである。
 そこで、どうやってデータを分割するかあれこれ考えてはみたものの、すっきりしたアルゴリズムになかなかならなくて。。Numpy配列のデータ型の扱いづらさ(私が不慣れなだけですが。。)も拍車をかけて、も~こんなところで時間を浪費するなんて~!と、参考文献(一番下で紹介)を丸パクリも頭によぎったが、本のテクニックはテクニカルすぎて勉強にならんと思い直し、原点に戻って試行錯誤した。その結果、振り返ってみれば大したことはなく、Numpyの"shuffle"というコマンドを使うと自分としては見通しの良いデータの分割ができた。”shuffle”はデータ行列を勝手にシャッフルしてくれる!
 その結果を反映したデータ分割プログラムがコレ。元データを丸々読み込んで、データ部分のみをシャッフル(1行!)し、分割する簡単なプログラム。これで十分。

import numpy as np
import matplotlib.pyplot as plt

Iris=np.genfromtxt('Iris.csv',delimiter=',',dtype=str)#まずは全部読み出し
IrisR=np.copy(Iris)
np.random.shuffle(IrisR[1:,:])#シャッフル!
n=np.shape(Iris)             

A,B=8,2#全データを A:B=training:test に分割
a=np.uint32(n[0]*A/(A+B))
Iris_train=np.copy(IrisR[0:a+1,:])#トレーニングデータ
Iris_test=np.copy(IrisR[a:,:])#テストデータ部分
Iris_test[0,:]=np.copy(IrisR[0,:])#テストデータ完成
np.savetxt('Iris_training.csv',Iris_train,delimiter=',',fmt='%20s')#出力
np.savetxt('Iris_test.csv',Iris_test,delimiter=',',fmt='%20s')#出力

 このあと続くグラフ化プログラムはのせてないけど、グラフで内容を説明するとこんな感じ。
 まずは、元データ。50個おきに値が異なるグループがある。
f:id:myuteru:20170603090750p:plain
 で、次がシャッフル後のプロット。この初めの8割をトレーニングデータ、残り2割をテストデータとしてCSV形式で保存するようにしてある。
f:id:myuteru:20170603090847p:plain

 今回の件に関してデータサイエンスのエキスパートがどのように取り組んでいるかが垣間見れるのが、下記の本である。

 この本はscikit-learn(機械学習ライブラリ)などをフル活用して、実務的な部分でデータとどう向き合うかを教えてくれる。内容のレベルが高いのでまだ理解できていないことが多いが、要所とデータ処理の流れは特に分かり易くかかれていて頼りになる。例えば、今回のようにデータを分割する際に、どれくらいの割合で分割すべきかの勘所なんかも書いてあって興味深い。