#author("2024-11-11T15:42:21+09:00","default:inoue.ko","inoue.ko") #author("2024-11-11T15:48:25+09:00;2024-11-11T15:42:21+09:00","default:inoue.ko","inoue.ko") *第8回 Pythonによる統計グラフ [[データサイエンス/2024]]|[[受講生一覧>https://design.kyusan-u.ac.jp/socialdesign/?%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9]]|[[汎用シート>https://docs.google.com/spreadsheets/d/16-rKwG0foQsE5LM53cMTR2p6rUUpJHem3H6eYlt5jgQ/edit?usp=sharing]] ~ ~ ***サンプル修正版|2024.11.11 &color(red){サンプルプログラムにミスがありましたので、以下修正版に更新しました。}; https://github.com/koichi-inoue/DataScience/blob/main/StatisticalGraph.ipynb 修正点は「グラフ用のデータフレーム の作成 」の部分の以下のコードです。 誤:df2 = df.groupby( 'day' ).mean( ) 正:df2 = df.groupby( 'day' ).mean( numeric_only=True ) 以前は、上の書き方でも動いていました(数値項目のみが自動的に選択されていました)が、現在では「カテゴリ項目の列が含まれる場合」は、numeric_only = True を明示的に記載する必要があるようです。 ~ ~ **統計グラフ ***様々なグラフ -[[ヒストグラム>GoogleImage:ヒストグラム]]:縦軸に度数、横軸に項目を対応させ、事項間の度数を比較するもの。度数分布図、柱状グラフともいう。 -[[ボックスプロット(箱ひげ図)>GoogleImage:箱ひげ図]]:データのばらつきを、箱(box)と、その両側に出たひげ(whisker)で表現する図。特に品質管理でよく用いられる。 -[[散布図>GoogleImage:散布図]]:縦軸、横軸に変数を対応させて、データを点でプロットしたもの -[[折れ線グラフ>GoogleImage:折れ線グラフ]]:時系列の推移を表すもの -[[棒グラフ>GoogleImage:棒グラフ]]:項目間の値を比較するもの -[[円グラフ>GoogleImage:円グラフ]]:円図形を扇形に分割し、事項の構成比率を表すもの -[[ヒートマップ>GoogleImage:ヒートマップ]]:2次元データの個々の値を色や濃淡として表現したもの ~ ***統計グラフ表示のためのライブラリ Pythonを用いた統計グラフには、様々な関連ライブラリーのインポート、データの読み込み、各種メソッドの活用が前提となります。以下、各種ライブラリの紹介です。 //-[[numpy>https://numpy.org/]]|数値計算 // import numpy as np -[[pandas>Pandas]]|データフレームの活用 import pandas as pd -[[matplotlib>https://matplotlib.org/]]|グラフ描画の基本機能の提供 import matplotlib.pyplot as plt -[[seaborn>https://seaborn.pydata.org/]]|matplotlib をベースにした美麗な可視化 import seaborn as sns ~ ~ **統計グラフの描画体験 はじめに matplotlib と pandas の連携による基本的なグラフ描画を体験します。 ~ ***データの準備 統計グラフの作成には、対象となるデータを''データフレーム''として読み込む必要があります(すでに前回までに確認済み)。 df = pd.read_csv( '/path/to/xxxxx.csv' ) ~ ***ヒストグラム #image(Pandas/hist.png,right,30%) ヒストグラム(柱状グラフ、度数分布図)は、横軸に階級、縦軸に度数をとった統計グラフで、データの分布状況を可視化するために用いられます。 データフレームからヒストグラムを生成するコードは非常に簡単です。 df.hist( ) 全項目一挙表示 df[ 'XXX' ] .hist( ) 特定カラムの表示 &small(df はデータフレーム変数の例です。); ~ ***ボックスプロット #image(Pandas/box.png,right,30%) ボックスプロット(箱ひげ図)は、データのばらつきを可視化する統計グラフで、箱(box)と、その両側に出たひげ(whisker)で表現されることからその名が付けられています。 一般に以下の五数が要約(five-number summary)されて表示されます。 -最小値(minimum) -第1四分位点(lower quartile) -中央値(第2四分位点、median) -第3四分位点(upper quartile) -最大値(maximum) 以下のコードは、対象カラム(XXX)をグループ(AAA)別に表示します。 df.boxplot( column='XXX' , by='AAA' ) ~ ***散布図 #image(Pandas/scatter.png,right,30%) 散布図(scatter plot)は、縦軸、横軸に2つの量的データ項目を対応させて、各レコードのデータを点でプロットしたものです。項目間の相関の有無が可視化されます。 以下のコードは、x軸とy軸にカラム項目を指定して表示します。 df.plot.scatter( x='XXX', y='YYY' ) ~ ***折れ線グラフ・棒グラフ・円グラフ これらのグラフは項目間の推移や比較を見るために使います。数万件もある全レコードを表示しても視覚的に読み取ることはできないので、グラフにしたい内容によって、事前に「データの平均値を出す」、「クロス集計する」といった処理を行った後、それを新たなデータフレームとしてグラフの表示に利用するのが一般的です(以下、棒グラフの事例です)。 # 性別ごとに国語・英語・数学の平均値を算出 df_mean = df.groupby( 'Gender' , as_index=False ).mean( ) df_mean ||Gender|Japanese|English|Mathematics|h |0|F|62.350000|58.475000|39.800000| |1|M|56.420455|41.142045|39.539773| #image(Pandas/bar.png,right,30%) 生成された df_mean を使うと、簡単に積み重ね棒グラフができます。 df_mean.plot.bar( stacked=True ) &small(stacked=True は、積み重ねを有効にする・・という意味です。); ~ ~ **演習8|統計グラフ CSVデータから統計量を視覚化するサンプルです。matplotlib と連携した pandas のグラフ描画機能を使って、様々なグラフの描画を体験します。 ~ ***ノートブックの新規作成 -__[[Google Colaboratory>https://colab.research.google.com]]__ でノートブックを新規作成 -Untitled0.ipynb というファイル名を変更 > StatisticalGraph.ipynb ~ ***サンプルデータ Tips のデータをサンプルとして利用します。 直接読み込むので、ダウンロードの必要はありません。 https://github.com/mwaskom/seaborn-data/blob/master/tips.csv //https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv ~ ***サンプルコード JupyterNotebook形式(.ipynb)でプログラムを提供します。 https://github.com/koichi-inoue/DataScience/blob/main/StatisticalGraph.ipynb ~ ***学科サイトにリンク掲載 ノートを、学科サイトの個人ページからリンクして下さい。以下、手順です。 -1. 自分のノートを開いた状態で、右上の「共有」をクリック -2. 共有設定を変更して、以下のように表示される状態にします。 このリンクを知っているインターネット上の全員が閲覧できます。 -3. 「リンクをコピー」をクリックして、そのアドレスを、以下の形式で、学科サイトの「Jupyter Notebooks」の部分に掲載して下さい。 -[[統計グラフ>https://colab.research.go・・=sharing]] -4. 以下のようになればOKです。 https://design.kyusan-u.ac.jp/socialdesign/?JohnSmith/DataScience ~ ~ **演習8|プログラムの解説 ***ライブラリーの読み込み 冒頭で、グラフ描画用のライブラリー''matplotlib''とデータ解析用のライブラリー ''pandas''を読み込んでいます。 # matplotlib パッケージ から pyplot モジュールを plt として import import matplotlib.pyplot as plt # pandasライブラリの読み込み import pandas as pd ~ ***ヒストグラム・ボックスプロット・散布図 -ヒストグラム(度数分布) hist 以下の1行で、データフレームに含まれる「量的データ」すべての項目について''度数分布''が描画されます。 df.hist() 以下の一行で、グラフを表示します。この1行は書かなくても、df.hist が自動的に matplotlib を呼んで表示まで行ってくれますが、後のコードに合わせて、表示を明示的に行っています。 plt.show() -ボックスプロット(箱ひげ図) boxplot 以下の一行で曜日ごとのチップの額に関するボックスプロットが表示されます。 df.boxplot( column = 'tip', by = 'day' , figsize = ( 9, 6 ) ) figsize はノート上に表示されるグラフの幅と高さを指定しています。 -散布図 plot.scatter 以下の一行で「総支払い額」と「チップ」の散布図が表示されます。 df.plot.scatter( x = 'total_bill' , y = 'tip' , figsize = ( 9, 6 ) , alpha = 0.7 ) alpha は点をプロットする際の「不透明度」を意味します。 ~ ***棒グラフ・折れ線グラフ・円グラフ -事前のデータ処理 折れ線グラフ、棒グラフ、円グラフでは、全てのデータを可視化しても読み取れません。以下、グラフ用に「曜日別の平均」を算出して新たなデータフレームを作成しています。 df2 = df.groupby( 'day' ).mean() df2 -indexの並べ替え データフレームを処理すると、項目がアルファベット順に出力されます。そのままだと、Fri, Sat, Sun, Thur と、違和感のある並びになるので、reindex というメソッドを使ってデータを Thur, Fri, Sat, Sun の順に並べ替えています。 df3 = df2.reindex( index = [ 'Thur', 'Fri', 'Sat' , 'Sun' ] ) df3 -折れ線グラフ plot 以下の一行で量的データ項目の折れ線グラフが表示されます。この例では、曜日の時間的「推移」として読むことができます。 df3.plot( figsize = ( 9, 6 ) ) -棒グラフ plot.bar 以下の一行で量的データ項目の棒グラフが表示されます。 df3.plot.bar( figsize = ( 9 , 6 ) ) -積み重ね棒グラフ 以下の一行で総支払額とチップの積み重ね棒グラフが表示されます。 df3[ ['total_bill' , 'tip'] ].plot.bar( stacked=True , figsize = ( 9 , 6 ) ) -円グラフ plot.pie 以下の一行で量的データ項目の曜日構成比が円グラフとして表示されます。 df3.plot.pie( subplots = True , figsize = (12,6) ) ~ ~ #hr CENTER:'''以下は、seaborn というライブラリを活用した事例です''' '''参考情報なので、取り組みは任意です。''' #hr ~ ~ **Pythonによる統計グラフ+ seaborn というライブラリを使った応用的なグラフ描画を体験します。 ~ ***seabornについて seabornは Python の可視化ライブラリで、matplotlib が内部で動いています。 -公式サイト:https://seaborn.pydata.org/ -seabornの長所 --美麗なグラフを描くことができる --matplotlibと比較すると少ないコードで描画できる -seabornの利用には、Pythonのバージョンが3.6以上であることが必要 &small(Google Colab は問題ありません。); ~ ***ヒストグラム -量的変数のヒストグラム sns.displot( ) sns.histplot( ) //&color(red){Web検索では dis ''t'' plot が表示されることが多いようですが、dis ''t'' plot は将来削除される予定で、代わりに以下の関数を利用することが推奨されています。}; //https://seaborn.pydata.org/generated/seaborn.distplot.html --displot( ) sns.displot( df['total_bill'] , bins=20 , color='#0033AA' ) --histplot( ) 例えば以下のように書くと、曜日ごとのデータを色違いに重ねます。 sns.histplot( data = df , x= 'total_bill' , bins=20 , hue = 'day' ) ~ -質的変数のヒストグラム sns.countplot( ) ~ ***ボックスプロット sns.boxplot( ) ~ ***散布図 質的変数の違いを色・形で区別、また量的変数をドットのサイズで表現可能 sns.scatterplot( ) ~ ***散布図行列 相関行列同様に、量的項目間の相関を一括表示 sns.pairplot( ) ~ ***ヒートマップ 2次元の表の値を色の差( 青:小 ←→ 赤:大 など)で表現 sns.heatmap( ) ~ ***棒グラフ・円グラフ等 seaborn ライブラリーによる棒グラフの表示は煩雑、また seaborn には円グラフを描く機能が実装されていないため、ここでは省略します。 ~ ~ **演習8+|統計グラフ+ ***ノートブックの新規作成 -__[[Google Colaboratory>https://colab.research.google.com]]__ でノートブックを新規作成 -Untitled0.ipynb というファイル名を変更 > StatisticalGraphPlus.ipynb ~ ***サンプルデータ いずれも https アクセスでプログラム内で直接読み込むので、ダウンロードする必要はありません。 ~ -サンプル1:tips.csv(前回同様) レストランにおける総支払額、チップの額、テーブルサイズ等 https://github.com/mwaskom/seaborn-data/blob/master/tips.csv -サンプル2:covid-19.csv(ヒートマップ作成サンプルとして使用) covid-19 陽性者数(都道府県別・月別) https://github.com/koichi-inoue/DataScience/blob/main/covid-19.csv オリジナルは以下、厚生労働省が公開している[[オープンデータ>OpenData]]のページで、ページの先頭にある「新規陽性者数の推移(日別)」を変形したものです。 https://www.mhlw.go.jp/stf/covid-19/open-data.html ~ ***サンプルコード JupyterNotebook形式(.ipynb)でプログラムを提供します。 https://github.com/koichi-inoue/DataScience/blob/main/StatisticalGraphPlus.ipynb ~ ***学科サイトにリンク掲載 ノートを、学科サイトの個人ページからリンクして下さい。以下、手順です。 -1. 自分のノートを開いた状態で、右上の「共有」をクリック -2. 共有設定を変更して、以下のように表示される状態にします。 このリンクを知っているインターネット上の全員が閲覧できます。 -3. 「リンクをコピー」をクリックして、そのアドレスを、以下の形式で、学科サイトの「Jupyter Notebooks」の部分に掲載して下さい。 -[[統計グラフ+>https://colab.research.go・・=sharing]] -4. 以下のようになればOKです。 https://design.kyusan-u.ac.jp/socialdesign/?JohnSmith/DataScience ~ ~ **演習8+|プログラムの解説 ***ライブラリーの読み込み 冒頭で、グラフ描画用のライブラリ matplotlib、seaborn とデータ解析用のライブラリ pandasを読み込んでいます。 # matplotlib パッケージ から pyplot モジュールを plt として import import matplotlib.pyplot as plt # seaborn ライブラリを sns として読み込み import seaborn as sns # seabornの機能を有効化 sns.set() # pandasライブラリの読み込み import pandas as pd ~ ***ヒストグラム -量的変数(総支払額)のヒストグラム sns.displot( ) --df['total_bill']:対象となるカラム項目 --bins=12:階級の分割数 --color='#0033AA':グラフの色 --height=6 , aspect=2:グラフのサイズ指定(高さとアスペクト比) &small(アスペクト比は 幅/高さ); --kde=True :確率密度関数の曲線を重ねて表示 -質的変数(曜日別)のカウントをヒストグラム化 sns.countplot( ) --data = df:データとして データフレーム df を使用 --x = 'smoker':喫煙者か非喫煙者で分布を比較 --order = ['Yes', 'No'] :喫煙者、非喫煙者の順に表示 --hue = 'day':曜日を色で区別 ~ ***ボックスプロット sns.boxplot( ) --data = df:データとして データフレーム df を使用 --x = 'day':横軸は「曜日」 --y = 'total_bill':縦軸は「総支払額」 --order = ['Thur','Fri','Sat','Sun']:木金土日の順に表示 ~ ***散布図 -一般的な散布図 sns.scatterplot( ) --data = df:データとして データフレーム df を使用 --x = 'total_bill':横軸に「総支払額」 --y = 'tip':縦軸に「チップの額」 -質的変数の違いを色・形で区別 --hue = 'day':曜日の違いを色で区別 --style = 'time':ディナーを◯、ランチを × でプロット --s = 100:ドットのサイズ指定 -量的変数をドットのサイズで表現(バブルチャート) --size = 'size':テーブルサイズ(人数)をドットのサイズに反映 --sizes = (100,1000) :ドットのサイズは 100 〜 1000 に割り当て --alpha = 0.5:不透明度 0.5 ~ ***散布図行列 相関行列同様に、量的項目間の相関を一括表示 sns.pairplot( ) --data = df:データとして データフレーム df を使用 --hue = 'day':曜日の違いを色で区別 --height = 4 , aspect = 1 :グラフのサイズ指定(高さとアスペクト比) &small(アスペクト比は 幅/高さ); ~ ***ヒートマップ このサンプルでは、covid-19 の陽性者数を「横軸:年月、縦軸:都道府県」というかたちで2次元の表にしたデータ(df2)を利用しています。 sns.heatmap( ) --df2:データフレーム df2 を使用 --linewidths=.5:ヒートマップの各データ間に線を描く --cmap = "coolwarm":ヒートマップの色の組み合わせ(青 - 赤) --fmt="d":表示フォーマット 10進数 --annot = True:セルに値を出力 --robust = True:極端に大きな値や小さい値の影響を受けないように処理 &small(ロバスト推定とは「外れ値に影響されにくい推定」を意味します。); ~ ***ファイルの保存について GoogleColab のファイル操作のためのライブラリを読み込むことで、描画されたグラフを画像ファイルとしてダウンロード保存することができます。 -ライブラリの読み込み from google.colab import files -matplotlib の機能を使って画像に名前を付けて保存(内部的に保存されます) plt.savefig('heatmap.png') -GoogleColab の機能を使ってファイルをダウンロード files.download('heatmap.png') ~ ~ **APPENDIX ***数理グラフ 数式等を用いたグラフ表示のサンプルです。時間に余裕のある方のみお試しください。取り組みは任意です。 https://github.com/koichi-inoue/DataScience/blob/main/Plotting.ipynb ~ ~