第7回 Python による統計処理
Pythonによるデータ解析
Python言語を用いたデータ解析には、Pandas という定番のライブラリーがあります。今回の演習は、これを使ってデータ解析を行います。
DataFrame
Pandas を使用するにあたって重要な概念が DataFrame と呼ばれる表構造です。 そこでは「表」を data、index、columns で把握しています。
- data:表内の個々のデータ値(成績表で言えば、行列に並ぶ点数データ)
- index:行ラベル(レコードを代表する値。成績表で言えば、学籍番号)
- columns:列ラベル(項目名。成績表で言えば、国語・算数・理科・・)
行ラベル、列ラベルとも、指定されない場合は 0, 1, 2,・・・となります。
一般にデータフレームは、CSV や Excel 等のデータを読み込んで生成しますが、直接書いて定義する場合は、以下のように書きます。
# pandasをインポート import pandas as pd df = pd.DataFrame( data = [ [ '佐藤', 170, 60 ] , ['田中', 160, 50 ] , [ '鈴木', 165, 58 ] ] , index = ['S01', 'S02', 'S03'], columns =[ 'name' , 'height', 'weight'] ) df
- df は DataFrame の略として一般によく用いられる変数名で、これが表の全体を包括して把握している・・というイメージになります。
- 時間に余裕のある方は、PythonBasics のノートに上記のコードをコピペしてお試し下さい。実行結果は、以下のように表示されるはずです。
name height weight S01 佐藤 170 60 S02 田中 160 50 S03 鈴木 165 58
データ解析のためのコード
Python による統計解析は、以下のように1行のコードで実現します。
後の演習事例に含めているので、ここでは見るだけでOKです。
- 要約統計量の表示:DataFrame.describe( )
df.describe()
- 相関行列の表示:DataFrame.corr( )
df.corr( numeric_only=True )
- クロス集計:pandas.crosstab( )
pd.crosstab( df['学部'] , df['性別'] )
演習7|データ解析
統計データのサンプルとして有名な Tips を使って、統計処理を体験します。 Tipsでは、レストラン利用者の支払総額、チップの額、性別、喫煙の有無などが一覧表になっています(インターネット上に公開されています)。
サンプルデータの事前確認
- サンプルデータ Tips は以下にあります。
https://github.com/mwaskom/seaborn-data/blob/master/tips.csv- 1行目がフィールド項目名です。
- 2行目以下がデータで、244件のデータ(レコード)があります。
- データが見えるブロック上の raw(生データ)をクリックすると、以下のように、CSVデータを直接表示することができます。
https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv
今回の演習のプログラムでは、このアドレスに直接アクセスしてデータを吸い出す形で利用します。
- ちなみにこの状態で、ブラウザの「ファイル>保存」を行うと、あなたのPCに tips.csv というファイルとしてデータをダウンロードできます。
- PCで xxxxx.csv をダブルクリックすると 、Excel 等のスプレッドシートが対応するデフォルトアプリケーションとして起動すると思います。
- xxxxx.csv はプレーンテキストなので TextEditor で開くことも可能です。
ノートブックの新規作成
- Google Colaboratory でノートブックを新規作成
- Untitled0.ipynb というファイル名を変更 > Statistics.ipynb
サンプルコード
- JupyterNotebook形式(.ipynb)でサンプルプログラムを提供します。
https://github.com/koichi-inoue/DataScience/blob/main/Statistics.ipynb
このページの上から順に、テキストとコードを自分のノートに書く、あるいは、コピー&ペーストして、お試しください。In [ ]:コード部分です。これを自分のノート のコードブロックに書く Out [ ]:実行結果です。コードを実行すると表示されます。 説明文:必要に応じて、自分自身のノートとして記載して下さい。
学科サイトにリンク掲載
ノートを、学科サイトの個人ページからリンクして下さい。以下、手順です。
- 1. 自分のノートを開いた状態で、右上の「共有」をクリック
- 2. 共有設定を変更して、以下のように表示される状態にします。
このリンクを知っているインターネット上の全員が閲覧できます。
- 3. 「リンクをコピー」をクリックして、そのアドレスを、以下の形式で、学科サイトの「Jupyter Notebooks」の部分に掲載して下さい。
-[[データ解析>https://colab.research.go・・=sharing]]
- 4. 以下のようになればOKです。
https://design.kyusan-u.ac.jp/socialdesign/?JohnSmith/DataScience
演習7|プログラムの解説
以下、上記のサンプルプログラムの説明です。
ライブラリの読み込み
import pandas as pd
- この1行を書くことで、以後 pd という変数で pandas の機能を使えます。
- Pandas は、データの読込、集計、並べ替え、欠損値の補完などを行うことができるライブラリで、データ分析の前処理段階で多く利用されます。CSV、EXCEL他、多様な形式のデータを読み込みに対応しています。
- Pandas の特徴は DataFrame の活用にあります。DataFrame にはデータの統計量の算出や、並替え、列名変更といったデータ整形機能があります。
CSVデータの読み込み
df = pd.read_csv('(URL)')
- Pandas のデータ読み込み機能を使ってCSVデータを DataFrame として読み込んで、df という変数に渡しています。
データフレームの基本情報を表示
print('行数・列数:', df.shape) print('項目名:', df.columns) print('各列のデータ型:\n', df.dtypes)
- Print 文は、データを表示する命令です。df.shape は行・列の数、df.columns は項目名の一覧、df.dtypes は各項目のデータ型を意味します。
- df.dtypes で表示される「データ型」の違いが重要です。
- int64 , float64: 数値項目(量的データ)で、計算の対象になります
- object:名義項目(質的データ)で、データを分類する際のカテゴリーキーワードになります。
要約統計量を表示|describe( )
df.describe()
- 各項目のデータ件数、平均、標準偏差、四分位点が表示されます。
相関係数を表示|df.corr( )
df.corr(numeric_only=True)
- すべての数値項目間の相関が一覧表示されます。
- 項目間の相関が瞬時に把握できる・・これだけでも、データサイエンティストになった気分が味わえます。
- 付記:df.corr() だけでも結果は表示されますが、最近のアップデートで、"numeric_only=True" つまり、数値項目のみを対象とすることを明記することが推奨されています。
データを total_bill の順で並べ替え|sort_values( )
df_sort = df.sort_values('total_bill', ascending=False ) df_sort
- データを降順に並べ替える事例です(参考までにご紹介です)。
女性の行のみ抽出|query( )
df_female = df.query( " sex == 'Female' ") df_female
- データを特定の条件で絞り込む事例です。df.query は DataFrame に問い合わせを行うメソッドで、ここでは「性別」の項目が「女性」の行のみを抽出して、新たな DataFrame として df_female に渡した後、それを表示しています。
Dinner に 5名以上で来た客のみ抽出
df_male_smoker = df.query( ' time == "Dinner" and size >= 5 ' )
df_male_smoker
クロス集計|曜日別の男女の数|crosstab( )
cross_table = pd.crosstab( df['day'] , df['sex'] ) cross_table
- 曜日と性別の2項目に注目して、クロス集計表を出力しています。これを正規化( 0.0 - 1.0 の値に変換)して表示するには、normalize='index' と追記します。
以下、データフレーム上のデータへのアクセス方法の事例です。
様々な書き方がありますが、こうした話は、覚えるのではなく、必要に応じてマニュアルで書き方を参照しながら使います。
曜日別のデータ件数|value_counts( )
df_day_counts = df['day'].value_counts() df_day_counts
- df['day'] で DataFrame の「曜日」の項目に注目した上で、その値(曜日)別の件数をカウントしています。
曜日別の平均|groupby( ) , mean(numeric_only=True)
df_day_mean = df.groupby('day').mean() df_day_mean
- 曜日の値別にグルーピングした上で、それぞれの平均を求めています。
関連リンク
https://pandas.pydata.org/
https://github.com/pandas-dev
https://pandas.pydata.org/Pandas_Cheat_Sheet.pdf
https://ja.wikipedia.org/wiki/Pandas
自主演習のススメ
今回の演習では、Web上に公開されている既存のCSVデータを利用しましたが、GitHubのアカウントや、Webサーバーがあれば、そこへ、ご自身がアンケート等で取得したデータをアップロードして解析することが可能です。
参考情報なので、取り組みは任意です。
演習7+|データ解析体験+
架空の大学の成績情報を一覧にした Excel データを使って、データ解析を体験します。1300名ほどの学生について、学部、性別、成績(GPA)、出席率、国語、英語、数学の得点が一覧になっています。
前回の事例との違いは、データを GoogleDrive に置いて利用する・・ということです。この方法を知れば、みなさんが自分で入手したデータを使って統計処理を行うことができるようになります。
基本的には、前回と同様の解析演習となりますが、今回のデータには 欠損値 が存在します。データに欠損があると、統計解析上様々な問題が生じるため、それを除去するプロセスが含まれています。
ノートブックの新規作成
- ブラウザ上の Google Colaboratory で ファイル> ノートブックを新規作成
- Untitled0.ipynb というファイル名を変更 > StatisticsPlus.ipynb
サンプルデータ
- 以下のシートにアクセスして下さい(乱数で生成した架空のデータです)。
StudentsData - ファイル>ダウンロード>Excel 形式でダウンロードして下さい。
- これをあなたの マイドライブ > Colab Notebooksにアップして下さい。
この授業用のフォルダを作っている方はそこにアップして下さい。
サンプルコード
- JupyterNotebook形式(.ipynb)でプログラムを提供します。
https://github.com/koichi-inoue/DataScience/blob/main/StatisticsPlus.ipynb - ここから、見出し・解説(テキスト)とプログラム(コード)をコピー&ペーストする形で、自分のノートを仕上げて下さい。
学科サイトにリンク掲載(任意)
ノートを、学科サイトの個人ページからリンクして下さい。以下、手順です。
- 1. 自分のノートを開いた状態で、右上の「共有」をクリック
- 2. 共有設定を変更して、以下のように表示される状態にします。
このリンクを知っているインターネット上の全員が閲覧できます。
- 3. 「リンクをコピー」をクリックして、そのアドレスを、以下の形式で、学科サイトの「Jupyter Notebooks」の部分に掲載して下さい。
-[[データ解析+>https://colab.research.go・・=sharing]]
- 4. 以下のようになればOKです。
https://design.kyusan-u.ac.jp/socialdesign/?JohnSmith/DataScience
演習7+|プログラムの解説
解説済みの、要約統計量、相関、クロス集計等に関する説明は省略して、この事例ではじめて登場するコードについて説明します。
GoogleDrive 上のデータを読み込むための準備
from google.colab import drive drive.mount('/content/drive')
あなたのGoogleDrive上のマイドライブにアクセスするための準備です。
アクセス許可を求められるメッセージが表示されるので許可して下さい。
Excel データの読み込み
df = pd.read_excel('/content/drive/My Drive/Colab Notebooks/StudentsData.xlsx')
Excel データを読み込んで、DataFrame として df という変数に渡しています。Colab Notebooks フォルダ内に StudentsData.xlsx があることが前提です。
ID の列を削除
df.drop( columns='ID', inplace=True )
ID は単なる通し番号で、統計処理の対象とする意味がないため削除。inplace=Trueというのは、元の df 自体を破壊的に更新することを意味します。
欠損値の確認
df.isnull().sum()
表の中に欠損値(NaN:Not a Number)がないか確認しています。
欠損値を含む行を削除
df = df.dropna( how='any' )
このサンプルデータには欠損値があるので「どこかに1つでも欠損がある場合はその行を削除する」という処理を行っています。このタイミングで df は削除後の状態に更新されます。
理工学部生かつ福岡県出身の行のみ抽出(複数の条件で絞り込む例)
df_select = df.query( ' 学部 =="理工" and 出身県 == "福岡県" ' )
- ピボットテーブルを使ってカテゴリごとの統計量を表示
pivot_table = pd.pivot_table(df, index='学部', columns='性別' , values='成績' , aggfunc='mean' ) pivot_table
APPENDIX
表形式のデータから見えてくるもの
大量の表データからは、何らかの「グループ」や、フィールド項目間の「関係」を見出すことができます。それらは判別や予測に活用することが可能です。
コンピュータがなかった時代は、みんな年長者の勘(つまり過去の経験の蓄積)を頼りに、物事の計画や準備を行っていました。
- 蕎麦屋の主人の勘:今日のような暑い日には、お昼時にざる蕎麦の注文が増えるから、事前に多めに仕込みをしておこう
- 刑事の勘:満月の日の21時ごろには、このあたりで事件が起きることが多いから、パトロールを強化しよう
と、こんな感じです。しかし現在では、過去の購買行動や犯罪事象などのデータが大量に蓄積(データベース化)されています。
例えば、購買行動については、日時、場所、購入商品、年齢、性別等、購入時点の複数のフィールド項目にデータが入る形で、購買行動1件(1レシート)がひとつのレコードとして記録されます。
さらに、その日の天候や気温、道路交通情報などの時系列データなども別のテーブルに記録されているので、複数のテーブルを時刻をキーとして照合すると、天候や気温のデータと売れる商品との関係を調べることも可能になります。
人間が経験的に参照・蓄積できるデータには限りがありますが、コンピュータを使えば、大量のデータを一括処理して、これまでは気づかなかったような「知見」を得ることが可能になります。まずは、データに潜む「グループの存在」や「項目間の関係」を人間の目に見えるかたちに「視覚化」すること。これがデータサイエンスの第一歩です(ここまでは、従来の「統計」の延長にあると言えます)。
で、さらにそれをもとに、自動的な判別(パターン認識)や予測を行うことができるようになります。これが A.I. ということになります。今日の A.I. やロボットの多くは、この大量のデータをもとに得られた「知見」にもとづいて、自動的に判断して行動しています。 データサイエンスと A.I. はその意味で、切っても切れない関係にあると言えます。