2.やってみる

2_1 試行その1(2019/5/13)

1)データ分析

データ分析では、その目標が大切です。分析は組合せで行いますが、直ぐに星の数ほどの組合せに達してしまいます。目標を定めて優先順位を考えて行うことが重要です。
データ分析は、「見える化」を行い、「分かる化」が図られ、「できる化」につながることが重要ですが、データ分析自体が「できる化」になる訳ではありません。データ分析の直接的な目標は、「見える化」するという事になります。
「見える化」するという事は、判断ができるという事になります。判断には、「絶対的評価」と「相対的評価」があります。絶対的評価ができることは、相対的評価より優れていると思いますが、絶対的評価というのは、個人の志向に依存するものですので、客観性を重視するデータ分析にはそぐいません。つまり、相対的評価ができるようにするということになります。
相対的評価とは、客観的に比較できるという事ですが、例えば、高い、大きい、重いといっても何と比較するのかが分からなければ、評価できません。某市町村の状況を評価しようと考えても、県内の他の市町村と比較するのか?国内なのか?世界なのか?単に隣の市町村との比較なのか?若しくは、当該市町村の過去の状況との比較なのか?が決まらないと何ともいえません。
つまり、データ分析の目標を再確認し、何を「できる化」したくて、何を「分かる化」したいのかを考慮した上で、何を分析対象とし、何と比較することで、「分かる化」に向けていくのかを明らかにし、具体的な分析計画を立てていく必要があります。
本ブログでは、高度な数学や統計は使いませんが、データを「分かる化」するための色々な工夫をしていきます。高度な数学や統計は、一般の人には理解されませんので、重要な手段だとは必ずしもいえません。しかし、データを正確に理解するためには、データの性質を詳細に理解し、分かるため、分かってもらうための工夫をすることはとても重要だと考えています。例えば、余分なデータを除く、分かるためにデータの組合せを変える、データを加工する、分かり易く表現(図表の活用等)する等です。その為には、データ概要を理解し、実際のデータをあらゆる角度で分析し、深耕していくことが重要になります。
本ブログで考えるデータ分析は、なるべく単純な数学で、なるべく多くの人に正しく理解してもらえる方法を学ぶということです。もちろん、高度な数学や統計も1つの方法ですが、いずれにしても正しくデータを理解すること無しに使用しても意味はありませんので、正しくデータを理解するという事は、データ分析の基本だという事でもあります。

2)データ比較

大人のAさんのお小遣いと子供のB君のお小遣いを比較して、Aさんの方が多いからといって、Aさんのお小遣いが多いという評価はできません。これは誰でもわかることですが、データの比較をして評価をする場合、こんな当たり前の間違いを犯してしまう場合があります。
データの比較をする場合は、評価する基準を合わせるという事に注意してください。何を「分かる化」するのかを考慮した上で、「規模」、「密度」、「種類」の3つの基準を合わせることを考えてください。「分かる化」する内容によって、3つ全てを合わす必要が無い可能性もありますし、この3つ以外の条件を合わせる必要がある可能性もあります。また、故意に選択したデータでは、作為的な結果にしかなりませんので注意してください。例えば、ある村の成人男性の平均身長を調べても、我が国の成人男性の平均身長は分かりません。渋谷で100人にアンケートしても、我が国の動向を探ることはできません。
さて、比較時に留意すべき「規模」、「密度」、「種類」の3要素について、市町村の状況を比較をする場合という事で説明します。
例えば、市町村の状況を比較をする場合、「規模」は最も重要です。企業の数や医師の数等を比較するとしても、どこかの村と横浜市を比較しても意味はありません。人口10万人当たりの数に置き替える等することで、対等な比較をすることで、企業の数や医師の数を比較する意味が出てきます。
「密度」は、どの様な分布になっているかという事でもあります。同じ人口の2つの市町村を比較するとしても、全く面積が異なる場合、つまり人口密度があまりに異なる場合は、比較できないことが考えられます。人口密集地と過疎地では、人の行動は異なると考えられます。
「種類」は構成とも言い換えられます。例えば、何かサービス利用量を比較しようとした場合で、男女構成が異なる場合、当該サービスの利用に性差があると単純に比較した結果から、市町村の違いを評価できないことが考えられます。年齢構成に違いがある場合も、同列に比較できない可能性があります。
企業の業績比較には、様々な指標がありますが、そのほとんどは単純な数学で表されます。しかも、この様に進んだ現在においても、新たな企業指標が開発されることがあります。データを理解し、工夫することで正しい理解ができるという事です。

3)データ加工

データが直接比較できない場合、データを加工するという考え方があります。例えば、前述した規模の異なる市町村のケースでは、人口10万人当たりの数に置き替えるという方法があると記載しました。市町村別の医師数を直接比較することはできませんが、医師数を人口10万人当たりの医師数にデータ加工することで、全ての市町村の医師数の多少を比較できるようになります。単純な数学を活用するだけでも、分かるようになることは沢山あります。
「規模」が異なる場合は、発生率を同一にします。一番多く使われるのは、1人当たり使用量の様に最低単位に合わせる方法ですが、数値が1を切るような場合、一般の人がその結果をイメージしにくいという事が考えられますので、人口10万人当たりというような数値にして分かり易くするという手法がとられます。
「密度」や「種類」が異なる場合は、不要なデータを除く・必要なデータだけに絞る方法(例えば、山林の面積を除く等)、種類別に比較する方法(男女別に比較する等)、層別に比較する方法(年齢階層別に比較する等)、グループ別に比較する方法(産業別に比較する等)等が考えられます。
また、層別に比較したものを全体で比較できるようにする標準化という手法があり、標準化には、高度な数学を使わない、疫学的な調整手法として、直接法と間接法があります。例えば、都道府県において、管下の年齢構成が異なる市町村の比較をする際、当該都道府県の年齢構成を基準人口とし、当該基準人口の年齢構成に各市町村の年齢構成を調整してから比較する場合で説明します。
A県の若年、成年、老年の3階層の年齢構成がそれぞれ、a1、a2、a3であったとし、A県の人口をA=Σa=a1+a2+a3とします。B市の人口をB=Σb=b1+b2+b3だとし、B市の若年、成年、老年の3階層の分析対象(例えば、死亡率等)の発生率をそれぞれ、x1、x2、x3だったとします。また、A県の3階層の発生率をAx、発生数をAzとして、全体の発生率をAX、発生数をAZとします。B市も同様に、B市の3階層の発生率をBx、発生数をBzとして、B市全体の発生率をBX、発生数をBZとします。
直接法の場合は、Σb*a/Σa=(b1*a1+b2*a2+b3*a3)/Aで求めます。つまり、観察集団のB市の層別の発生率で、基準集団のA県の層別の人口であった場合として、観察集団の全体の発生率を調整して求めるという事です。
間接法の場合は、AX*BZ/Σb*Ax=AX*BZ/(b1*Ax1+b2*Ax2+b3*Ax3)で求めます。つまり、機銃集団の発生率に対して、観察集団のB市の層別の人口が基準集団と同様に発生した場合の発生数と実際の発生数の比率を乗じて求めるという事です。換言すると、基準集団の死亡率を観察集団の死亡率で調整するというイメージです。基準集団の死亡率を元にして間接的に求めるという事でしょうか。
個人的には、直接法で全体の発生率を求める調整方法を使用します。直接法の方が一般にも分かり易いですし、国(厚生労働省)のデータ分析が直接法を使用しているケースが多く、国の結果と比較し易いというのが理由です。参考までですが、人口に関する比較をする場合には1000を乗じて、人口1000人当たりの発生率にしているケースが多いと思います。
また、分析対象のデータには、質的データ(名義尺度、順序尺度)と量的データ(間隔尺度、比例尺度)があります。質的データとは、性別(1:男、2:女)の様にカテゴリーに分かれたデータであり、量的データとは、年齢の様に数値として意味のあるデータです。
量的データの方が質的データより情報が豊富な訳ですが、わざと量的データを質的データに変換する場合があります。例えば、年齢データを年齢階層(1:0~15才未満、2:15~65才未満、3:65才以上等)に変換してから分析する場合があります。これには、個人を特定させないために分かり難くするという様な理由もありますが、前述したように層別に分析した方が都合が良いという理由、表形式でまとめて表現した方が分かり易いという理由があります。
この様に、データをそのまま分析するだけでなく、目的に応じて工夫し、データ加工してから分析するという事ができないかを考えるようにしてください。

4)データ行列

本ブログで取り扱う分析対象のデータは、2次元のデータ行列(表形式)になります。例えば、クラス10名の12回分のテスト結果の様なデータです。列(横)方向に、種類となる10名を並べ、行(縦)方向に、その観察結果となる12回分のデータが並ぶ2次元のデータになります。3次元(テストの種類が、数学、国語、英語様に分かれる等)の場合は、2次元のデータを3次元目の数だけ用意(数学の表、国語の表、英語の表)し、表毎に分析するのを基本とします。但し、列方向をAさんの数学・国語・英語、Bさんの数学・国語・英語・・・の様にして、3次元ではあるが、2次元のデータの様にして分析することがあります。
分析対象となる2次元のデータ(表形式)は、本ブログでは、PythonのライブラリであるpandasのDataFrameという形式で扱います。DataFrameでは、列方向と行方向の区別なく分析することも可能ですが、本ブログでは、列方向に分析対象のデータの種類を配し、行方向にそのデータ種類毎の観察結果を並べるのを基本とします。
DataFrameは、2次元のデータ行列を扱うpandasのオブジェクト(object)です。オブジェクトとは、定義されたものという理解で問題ありません。システム設計を志す訳ではありませんので、定義の仕方等を理解する必要はありません。pandasでは、DataFrameを始めとして、データ分析に都合の良い仕組みを予め定義して、色々と用意してくれていると考えれば問題ありません。そして、DataFrameは、データ分析の対象となるデータ行列を扱い易いように管理してくれる優れたオブジェクトだということです。
つまり、本ブログのデータ分析では、与えられたデータをDataFrameに読み込んで、そのDataFrameに名前を付けることから始まります。当該DataFrameでは、列や行の名前を付けることもできます。この結果、DataFrame名と列名を指定することで、当該データの分析が可能になります。
pandasのデータ処理は、ブロードキャスト(broadcast)という手法で行われます。ブロードキャストは、一般には、放送という意味で理解されます。1カ所での送出により、多くの受信者が同じ内容を受け取れるという事になります。pandasのデータ処理も同じ様に1カ所のデータ処理が、全てのデータに行きわたります。
例えば、abcというDataFrameにx、y、zという3種類の列(変数)があったとします。xとyには12ケースの観察結果があり、zには値が無いが、、zにはxとyの合計値が入るべきだとします。この場合、pandasでは、以下の様に記述します。
abc[“z”] = abc[“x”] + abc[“y”]
一般のプログラミングでは、12ケース分を繰り返すという処理が必要ですし、表計算ソフトを使用した場合は、計算式を列分だけドラッグする必要がありますが、pandasは、ブロードキャストですので、1つの処理を記述するだけで、全ての観察結果に反映させるという特長があります。
部分的に適用したい場合はどうするのか?という疑問が湧くかもしれませんが、実際のデータ分析において、その様なことは稀です。どうしても部分的に処理がしたい場合は、DataFrameを分析したい対象毎に分割します。そして、全てブロードキャストで処理をするというのが、pandasの基本的な考え方だと思ってください。一般のプログラミングに慣れた方にとっては、イメージしにくいかもしれませんが、結果として、美しい処理になります。
本ブログのデータ分析は、DataFrameを活用した、データ行列に対する、ブロードキャスト形式のデータ処理だと理解してください。
尚、本ブログのデータは、ヘッダー付きのcsvファイルで提供します。ヘッダーは、各列の変数名です。Pythonでは、このデータを読み込んでDataFrameに読み込みますが、このヘッダーに指定した変数名がそのままDataFrameの変数名になります。つまり、Pythonのプログラムでは、変数名をプログラムで事前定義しません。結果として、データの構成が変わったとしても、プログラムの変更は必要ないという事になります。入力するファイルのヘッダーを変更するだけで、プログラムの変更が無く処理できますので、大変便利です。
私は、実際に仕事でデータ分析する場合も、元のデータをコピーして残しておいて、分析用のデータにヘッダーを付して処理するようにしています。

5)データ処理

ここまで読み進んでくれた方は、このブログのデータ分析は、表計算ソフトを対話的に処理する代わりに、DataFrameというデータ行列に対して、データ処理手順を記述することで実現するのだという事をなんとなく理解していただけましたでしょうか?
対話的に処理するのではなく、データ処理手順を記述するということですので、再現性が実現できるというメリットがあります。これは、データ分析において非常に重要なことです。どうしてこの様な結果になったのかを手順で示せているという事ですし、結果がおかしいと思った場合でも、何度でもやり直すことができますし、2回目以降は、対話作業は無く、全ての手順を一括処理するだけで完了します。つまり、第三者に示すことも容易ですし、自分が確認したり再処理することも容易になるという事です。また、データ処理は、似たような処理を行うことが多くあります。この場合、以前のデータ処理の手順をコピーし、異なる部分だけ変更して処理するという事も簡単にできるようになります。
つまり、本ブログ方式のデータ処理は、実施しただけノウハウとして蓄積できるという事になります。データ処理パターンを複数こなすことで、できることが増えていくという事になります。また、一般的なブログの様に、個々のオブジェクトの解説や個々の処理方法の解説を目的としていません。Pythonの解説やpandasの解説も目的としていません。その様なことは、ネット上で検索すれば沢山出てきますので、それらを参照してください。
本ブログでは、「できる化」を示すことを目的としています。つまり、実際のデータ処理の実例を示していきます。皆さんは、こうすればできるということを学んでください。もちろん、簡単な実例から順に示そうと考えていますので、実例に従って、実際に自分で実行してみてください。やってみたことは、できるに繋がります。データも処理手順も示しますので、データを変えたり、処理手順を変えることでどの様に変化するかも経験してみてください。何かを変えることで、処理が動かないことやエラーが表示されることもあると思いますが、それも経験になります。
システム開発において、不具合は付き物ですが、この不具合を解決する方法には鉄則があります。正しく動くところから始め、正しく動かないところにどのタイミングでどの様なことをした時点で不具合が発生するかを見極めるという事です。また、なるべく複合的な確認をしないで済むようにチェックするという事です。
しかし、多くの開発者は、正しく動かないところから始め、正しく動くところに戻そうと試行錯誤し、多くの無駄な時間を費やしています。原因がある程度特定できているのであれば、そういう方法の方が早く解決するのですが、分かっていない場合や、特定していた原因ではなかった場合は、正しく動くところに戻るのが早道です。正しく動くところに物理的に戻せない場合もありますが、論理思考だけでも正しく動くところから考え直すのが、結局は解決の早道になります。
システム開発は関係ないと言いながら、システム開発の話で恐縮ですが、新しく物事を学ぶというのも同じことだと思います。分かりもしないのに、あれやこれやと考えながら理解を深めていくというのは時間が掛かります。美味しい料理を作るのには、食材を吟味するところから始めるより、先ずは美味しい料理を食べることが先決です。美味しい料理を分からずして、素人が食材を試行錯誤するのは時間の無駄だという事です。
本ブログでは、できる実例を示します。こうすればできるという事例を沢山学ぶことで、自然とデータ分析ができるようになるというのが、本ブログが目指すところです。ある程度データ分析ができるようになれば、自分なりの特徴を生かしたデータ分析ができるように勉強を深めてください。Pythonには、沢山の機能があります。また、Pythonの理論やオブジェクト指向の理論を学習するというのも1つの考え方です。自転車の構造を理解するには、自転車が乗れるようになってから考えた方が理解が早いと思います。

5)試行(その1)の実行

本ブログでは、分析するためのデータ(csv形式のデータ)とその処理手順(Pythonのプログラム)をWarehouseから提供します。パソコン上にダウンロードし、実行してみてください。もちろん、パソコン上にPythonを実行する準備(前述)をしてから行います。
最初の段階では、「教育用標準データセット」というものをデータ分析の対象とします。実際のデータ分析では、データの間違いや欠測がありますが、本データにはありません。先ずは、データ分析ができるという事が目標ですので、その様な面倒なことは無いものとします。取り敢えずは、データの検証は不要だと考えて、どうやってデータ分析を進めるかを考えてください。
本処理手順には、コメントが付されています。シャープ記号(#)の後ろは、コメントとして認識され、Pythonコードとして処理されません。コメントは、行全体がコメントである場合は、1文字目にシャープ記号を書いてその後にコメントを記載しますが、Pythonのプログラムの後にコメントを記載する場合は、プログラムの後に1文字のブランクを空けて、シャープを記載してからコメントを記載します。コメントは、非常に重要な情報ですので、詳しく記載することをお勧めします。但し、第三者が見て分かり易いものにしてください。
処理手順は、一連のデータ処理毎に1つのファイルに格納しますので、最初にその一連の処理の概要を記載し、入力するデータや出力するデータの説明も記載します。当該処理手順を作成した年月日も忘れずに記載してください。また、実際の処理毎にどの様な処理をしているのかが分かるようにコメントを記載します。データ処理毎の結果もコメントとして記載しておけば、処理記録にもなります。処理記録を別の資料として作成する方法もありますし、その方が正式だと思いますが、本ブログでは、簡易的な方法で、処理手順に処理結果も併せて記録する方法を採ります。最終的な処理結果は、csvファイルやグラフファイルとして別に残され、出力データとしてそれらのファイルの説明をコメントするのですが、処理手順に簡易的に記載するというのは、処理途中の状況をコメントで記載するという事です。

さて、では試行を始めましょう!
先ず、パソコンのCディスクの直下に、Pythonというフォルダを作成し、その下にssdseというフォルダを作成してください。このssdseというフォルダの下で、「教育用標準データセット」を活用した複数の試行を行っていきます。次に、ssdseの下に、dataというフォルダとsimple1というフォルダを作成してください。フォルダは、Pythonの下にプロジェクトごとに作成して管理します。プロジェクトを階層的に管理するのであれば、フォルダも階層的にしてください。ここに記載した通りのフォルダ構成である必要はありませんが、本ブログでは、ここに記載した通りのフォルダ構成であると仮定して記載します。
dataフォルダの下には、Warehouseの中の1.教育用標準データの「教育用標準データセット(本ブログ版)」をダウンロードして解凍した複数のデータを格納してください。
simple1フォルダの下には、Warehouseの中の2.簡易処理手順の「試行その1」をダウンロードして解凍したsimple1.py(Pythonのプログラム)を格納してください。
これで準備は完了です。IPythonを稼働させます。スタートからAnaconda3(64-bit)を選択し、Anaconda Promptを実行(タスクバーに登録する等すると実行が容易です)します。黒いコマンド実行用の画面が表示されますので、パソコンのディスプレイに合わせて広げてください。以降は、この黒い画面で実行します。
IPythonと入力してEnterキーを押せばIPythonが実行されます。IPythonは、Windowsの実行プログラムとして実行されます。IPythonは、Pythonの実行環境としては、とても軽い環境ですし、補助機能も優れていますので、最初の学習ではIPythonをお勧めします。Windowsのコマンドやプログラムとして実行するには、大文字と小文字の区別はありませんが、IPythonの処理は、大文字と小文字を区別するので注意してください。
それでは、Pythonを実行します。simple1.pyをテキストエディタであるSublime Text3(以下、「ST3」と言います)で開きます。最初の行には、DOSコマンド(cd c:\Python\ssdse\simple1)が記載されていますが、これはIPythonの中でも実行可能ですので、これをコピーして、黒い画面のIPythonの実行環境にペーストして実行します。これで、以降のIPythonの実行が、c:\Python\ssdse\simple1のフォルダで実行(カレントフォルダになる)されることになります。これは、Cディスクからの絶対パスで示されていますが、以降の指定は、相対パスで指定しています。つまり、ssdseをc:\Pythonの下に作成しなかった場合(移動した場合)であっても、ssdse配下のデータが同じであれば、相対パスで指定している部分は、変更が無いという事になります。また、フォルダを指定せずにファイル名だけ指定して入出力した場合は、カレントフォルダに対して行われることになります。つまり、通常のsimple1.pyの出力結果のファイルは、simple1フォルダの中に格納されるという事になります。

続けて、simple1.pyに記載されたプログラムをコピー&ペースト(コピペ)してIPythonで実行します。コメントは、一緒にコピペして実行しても無視されるだけですので、コピペに含めても含めなくてもどちらでも構いません。但し、最初のプログラムの実行は、1行ずつ行ってください。2回目以降は、プログラム部分を複数行をまとめてコピペして実行しても問題ありません。
一度実行した結果は、IPythonが覚えています。abcという変数の内容を知りたければ、abcと入力してEnterキーを押せば表示されます。また、abc?と入力すれば、abcがどういう定義になっているかを示してくれますし、1+2と入力すれば、3と答えてくれます。
IPythonは、Pythonのインタープリター(Pythono命令を1行ごとに対話式で実行してくれる仕組み)で、DOSのコマンドプロンプトと同様に1行ごとに解釈して実行し、処理内容に応じて、プロンプトを返してくれます。
 In [実行番号]:処理内容
 Out[実行番号]:処理結果
 In [次の実行番号]:
処理を実行してもプロンプトが返ってきていない場合は、次の2つの理由のいずれかです。
 ・処理内容の記述が十分ではなく、追加の入力かEnterキーの入力を待っている状態
 ・処理を実行しているが、未だ処理が終わっていない状態
最初にAnaconda Promptを実行した時点でも、直ぐには準備が整わず、コマンドを受け付けられる状態ではないので、DOSのプロンプトが表示されませんし、IPythonを実行した時点でも、直ぐには準備が整わず、IPythonのプロンプトが表示されません。プロンプトが表示されるのを待って、次の処理を実行してください。ビッグデータの処理や複雑な処理を実行した場合は、プロンプトが表示されるのに相当な時間を要する場合があります。
simple1.pyのプログラムを最後まで実行するのですが、コメントに記入されている説明を理解し、処理途中結果のコメントも確認しながら進めてください。最後まで実行したら、出力結果のファイルができていることも併せて確認してください。
これで、試行その1の学習は終わりですが、処理手順の内容を分かる範囲で変えて実行する等して更に理解を深めてください。
IPythonを終了するには、Ctrl+dキーを押して、yをキーインすれば終了しますが、Anaconda Promptの黒い画面を×印をクリックして終了させることでも問題ありません。但し、IPythonを終了すると、今までに実行したプログラムとその結果を覚えていませんので、プログラムの最初から実行しなおす必要があります。
simple1.pyでは、ssdseのデータを使用しており、ssdseには沢山の変数が定義されていますが、9種類のデータ項目のみ分析対象としています。csvファイルのヘッダーに変数名が記録されているのですが、DataFrameに取込む際に使用する列項目番号(番号は0から始まる事に注意)を指定しています。これにより、DataFrameが軽くなり、内容確認が容易になります。

Pythonやpandasについて分からないことがあれば、ネット検索で解決すると思います。但し、間違ったことを記載してしまっているケースも稀ですがありますし、掲載時には正しくても、情報が古くなって、現時点では正しくないというケースは結構ありますので注意してください。
公式なサイトで確認すれば間違いもありません。公式なサイトは、「Master」の3.参考サイトを参照してください。
では、頑張ってください。