データ分析の初歩から応用まで少しずつステップアップしながら学んでいく連載の第12回。グラフを利用して項目同士の関係や、その中での値の大きさを可視化します。散布図やバブルチャートの詳細な取り扱いと視覚的な分析について、ケーススタディを通して学びましょう。
この連載では、データをさまざまな角度から分析し、その背後にある有益な情報を取り出す方法を学びます。
データの収集方法、データの取り扱い、分析の手法などについての考え方を具体例で説明するとともに、身近に使える表計算ソフト(ExcelやGoogleスプレッドシート)を利用した作成例を紹介します。
必要に応じて、Pythonのプログラムや統計ソフトRなどでの作成例にも触れることにします。
数学などの前提知識は特に問いません。肩の力を抜いてぜひとも気楽に読み進めてください。
筆者紹介: IT系ライターの傍ら、非常勤講師として東大で情報・プログラミング関連の授業を、一橋大でAI関連の授業を担当。書道、絵画を経て、ピアノとバイオリンを独学で始めるも学習曲線は常に平坦。趣味の献血は、最近脈拍が多く99回で一旦中断。さらにリターンライダーを目指し、大型二輪免許を取得。1年かけてコツコツと貯金し、ようやくバイクを購入(またもや金欠)。
前回はピボットテーブルによるクロス集計表の作成とヒートマップを利用して分布を可視化しました。今回は、散布図とバブルチャートによって分布を可視化します。
いずれも項目間の関係や分布を可視化するのに便利ですが、ヒートマップは変数が名義尺度や順序尺度である場合、または、階級に分けられている間隔尺度の場合に便利です。前回見たワインの価格は間隔尺度ですが、それを階級に分けて利用しました。評価はそもそも順序尺度ですが、便宜的に間隔尺度として取り扱い、得られた平均値によって階級を分けていました。ちなみに尺度については第2回で説明しています。
今回取り扱う散布図は、主として変数が間隔尺度の場合に使われます。そこで、前回のデータをそのまま(階級に分けずに)散布図を作成してみます。今回は、売上金額を含めた表を基に、価格と評価、そして売上金額の関係を散布図やバブルチャートで分析していくことにします(図1)。前回同様、データは架空のものです。
今回のテーマは、散布図を利用した2つの変数の関係の可視化することです。さらにバブルチャートを利用して2つの変数の関係だけでなくもう1つの変数の規模(大きさ)も可視化します。後半のコラムでは、散布図を色分けしてグループを可視化する方法と、数多くの項目について散布図をまとめて作る方法についても紹介します。
この記事は、データ分析の初歩から応用まで少しずつステップアップしながら学んでいく連載の第12回です。特に、第7回から今回の散布図/バブルチャートまでは「可視化シリーズ」として、グラフの使い方と分析の観点について解説しています。第7回の棒グラフ、第8回の折れ線グラフ、第9回の円グラフ/パレート図、第10回のヒストグラム/箱ひげ図、第11回のクロス集計表/ヒートマップも併せてご参照ください。これらのグラフの目的と効用などについて、特別予告編で簡単に整理しています。事前に確認しておくとより理解が深まるでしょう。
今回は以下のようなポイントについて、分析の方法や目の付けどころを見ていきます。
では、基本の基本である散布図の作成から見ていきます。サンプルファイルの利用についての説明の後、本編に進みましょう。
本稿では、表計算ソフトを使って手を動かしながら学んでいきます。表計算ソフトMicrosoft Excel用の.xlsxファイルをダウンロードできるようにしています。デスクトップ版のExcelが手元にない場合は、Microsoftアカウントがあれば使える無料のMicrosoft 365オンライン、もしくはGoogleアカウントがあれば使える無料のGoogleスプレッドシート(Google Sheets)をお使いください。Microsoft 365オンラインの場合は、.xlsxファイルをOneDriveにアップロードしてから開いてください。Googleスプレッドシートの場合は、.xlsxファイルをGoogleドライブにアップロードしてから開いた上で[ファイル]メニューの[Google スプレッドシートとして保存]を実行してください(Googleスプレッドシート独自の機能を使っている場合は、ファイルを共有して参照できるようにします。その場合は、該当する箇所で使い方を記します)。
では、さっそく散布図を作成してみましょう。サンプルファイルをこちらからダウンロードし、[ワインの売り上げ(1)]ワークシートを開いて取り組んでみてください。Googleスプレッドシートの場合はこちらのサンプルファイルも利用できます。メニューから[ファイル]−[コピーを作成]を選択し、Googleドライブにコピーしてお使いください。
手順は図の後に箇条書きで示しておきます。ただし、タイトルやグラフの表示位置、サイズなど、データ分析そのものにあまり関係のない設定については省略してあります。なお、動画でも手順を解説しているので、操作を一つ一つ追いかけたい方はぜひご視聴ください。
以下の手順で進めていきましょう。
セルC3〜D1003を選択するにはドラッグ操作よりも[名前]ボックスに「C3:D1003」と入力する方が簡単です。これで図3のような散布図が作成されます。
図3から、65万円(実際の値は64万5000円)のワインが外れ値として存在することが分かります。そこで、高価なワインは除外し、値が密集している部分を詳細に見るために、横軸の最大値を変更してみましょう。ここでは、最大値を20000とします。
これで、図2(完成イメージ)のような散布図が作成されます。前回見た通り、2,000円から3,000円で、評価が3.5から4.5あたりの商品が多いことが分かりますね。さらに、グラフからもう一つ重要なことが読み取れます。それは、評価が5.0で頭打ちになっているということです。そもそも、2,000円から3,000円あたりの5.0という評価と、20,000円あるいはそれ以上の価格のワインの5.0は同じ価値を持つ評価でしょうか。品質の良い高価なワインであれば「☆5つではなく☆100個を付けたい」というように、もっと高い評価を付けたい人も多いのではないでしょうか。ネットショッピングの口コミは5段階評価が多いので、図2のようなグラフになってしまいますが、より繊細かつ厳密に評価するのであれば、100点満点にした方がよさそうだということも分かりますね。
ワインの評価としては、パーカーポイントと呼ばれる評価が有名です。パーカーポイントでは、色や風味、質などを基に、100点満点で値が与えられます。詳細については、サッポロビールのワインに関するページなどをご参照ください。
図2や図3を見ると、ある価格のワインがどのような評価を得ているかが分かりますが、そのワインの売り上げがどの程度であるかは分かりません。手頃に購入できるワインは、単価は安くても売上数量が多いので、合計の売上金額も大きいと考えられそうです。一方、高価なワインは、単価が高いので、売上数量が少なくても合計の売上金額は大きいかもしれません。そこで、散布図に売上金額のような「規模」(大きさ)を表す値を反映させるためにバブルチャートを作ってみましょう。
作成の方法は簡単です。横軸に対応する項目と縦軸に対応する項目、規模に対応する項目を指定してグラフを作成するだけです。
では、散布図の作成に利用したファイルの[ワインの売り上げ(2)]ワークシートを開いて取り組んでみてください。[ワインの売り上げ(1)]と同じデータですが、作業しやすいように別のワークシートにしておきました。箇条書きにした以下の手順でバブルチャートを作成してみましょう。これについても、動画での解説も用意してあるので、操作を一つ一つ追いかけたい方はぜひご視聴ください。なお、現在のところ、Microsotf 365オンラインにはバブルチャートの機能がありません。
グラフ化するセルの範囲を選択するには、ドラッグ操作と[Ctrl]+ドラッグ操作で離れた範囲を選択するよりも[名前]ボックスに「C3:D1003,F3:F1003」と入力する方が簡単です。ただし、Googleスプレッドシートでは、この指定ができないので、[名前]ボックスに「C3:D1003」と入力した後、[Ctrl]キーを押しながらセルF3〜F1003をドラッグする必要があります。別の方法としては、E列の見出しをクリックし[列を非表示]を選択した後、[名前]ボックスに「C3:F1003」と入力するのが簡単です。
この段階では、図4のようなグラフになっています。
続けて、以下の手順で最小値と最大値の設定やバブルサイズの変更を行っておきましょう。ただし、Googleスプレッドシートではバブルサイズが自動的に決められ、変更ができないようなので、その操作は省略します。
これで、図5のようなバブルチャートになります。
価格の高いワインはそれほど売上数量が大きいわけではありませんが、売上金額はお手頃なワインとそれほど変わりません。数量が少なくても売り上げが上がるということは、在庫のためのスペースが少なくて済むということですね。これは大きなメリットです(同時に、保管方法に特別な配慮が必要になったり、盗難に遭った際のリスクが大きくなったりしますが)。なお、バブルチャートでは系列のデータ数が多いとバブルが重なり過ぎて、見づらくなることがあります。その場合はバブルのサイズを小さくするとある程度見やすくなります。例えば、バブルサイズを「5」に変更すると、図5の値が集中している箇所が見やすくなります。
前回のコラムでk-means法を利用したクラスタリングの例と、それをヒートマップとして表示する方法を紹介しました。散布図やバブルチャートでも同様にグループによる色分けができれば、より多角的な可視化ができますね。残念ながら、Excelではかなり難しいので、Pythonでのプログラムで作成した例を紹介します(図6)。
図6から、●で表されている0番のグループは価格がお手頃で評価は中ぐらいといったこと、×で表されている1番のグループが低価格または低評価のグループであり、売り上げがそう大きくないことが分かります。また、2番のグループが価格を問わず高評価であり、売り上げも比較的大きいことも分かります。ただ、それ以上のことは少し分かりにくいですね。
ワインのデータを使って、k-means法により6つのグループを作るコードは以下の通りです。これは前回紹介したコードとほとんど同じです。このリンクをクリックすれば、ブラウザが起動し、Google Colaboratoryで以下のコードが表示されます(Googleアカウントでのログインが必要です)。[ドライブにコピー]ボタンをクリックすれば、自分のGoogleドライブにコピーできます。コードの部分をクリックして[Shift]+[Enter]キーを押せば、プログラムが実行され、クラスタリングを行った結果がdfresultという名前のデータフレームとして作成されます。
コードの詳細についてはこの記事の範囲を大きく逸脱するので割愛しますが、コード中のコメントと説明を参照していただければだいたいの意味は分かると思います。なお、上記のリンクにはグループごとに平均値を求めるためのコードや、その値を基にヒートマップを作成するためのコードも含めてあります。さらなる分析に活用できるので、ぜひご参照ください。
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler
# データの読み込み
df = pd.read_excel("https://github.com/Gessys/data_analysis/raw/main/12a.xlsx",
sheet_name="ワインの売り上げ(1)", skiprows=2, usecols="A:F")
data = df.loc[:, ["価格", "評価", "売上金額"]]
# データをスケーリングする(値の大きさが異なるので、0〜1になるように調整する)
sc = MinMaxScaler()
data_sc = sc.fit_transform(data)
# k-means法によるクラスタリング
model = KMeans(n_clusters=6, random_state=0, n_init="auto")
model.fit(data_sc)
# 元のデータにクラスタ番号を追加する
cluster_no = pd.DataFrame(model.labels_, columns=["グループ"])
dfresult = pd.concat([df, cluster_no], axis=1)
リスト1の結果を基に、価格を横軸に、評価を縦軸に、売上金額をバブルのサイズにし、さらにグループによる色分けを行うコードは以下の通りです。散布図やバブルチャートはmatplotlib.pyplotモジュールのscatter関数やデータを簡単に可視化するのに便利なseabornモジュールのscatterplot関数で作成できます。ここではscatterplot関数を使っています。
!pip install japanize_matplotlib # これは最初に1回実行しておけばよい
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import seaborn as sns
import japanize_matplotlib
# 20000未満のデータだけを取り出す
dfbubble = dfresult.loc[dfresult.価格 < 20000]
dfsize = data_sc[dfresult.価格 < 20000, 2] * 200 # マーカーのサイズを計算
# バブルチャートを表示する
plt.figure(figsize=(12, 8))
kwargs = {"linewidth": 0} # 枠線を表示しない
sns.scatterplot(x=dfbubble.価格, y=dfbubble.評価,
c=cm.tab10(dfbubble.グループ), # マーカーの色の指定
s=dfsize, # マーカーのサイズの指定
style=dfbubble.グループ, # マーカーの形の指定
**kwargs)
plt.show()
今回利用したワインのデータでは、項目(列)の数はそれほど多くありませんでした。しかし、項目が多くなると、項目同士の組み合わせも多くなるので、手作業で散布図を作るのはかなり面倒です。そのような場合はプログラムによって散布図をまとめて描画するのが得策です。
図10は、seabornモジュールのpairplot関数を使って、数多くの項目同士の散布図を作成した例です。利用するデータはscikit-learnのデータセットとして用意されている糖尿病関係のサンプルデータで、age(年齢)、sex(性別)、bmi(体格指数)、bp(血圧)、s1(総コレステロール値)、s2(悪玉コレステロール値)、s3(善玉コレステロール値)、s4(=s1/s3)、s5(中性脂肪の対数)、s6(血糖値)、target(1年後の糖尿病の進行度)という項目が含まれています。
コードはこのリンクから参照できます。リンクをクリックすれば、ブラウザが起動し、Google Colaboratoryで以下のコードが表示されます(Googleアカウントでのログインが必要です)。このリンクには、相関行列を求めてヒートマップを作成するためのコードも含めてあります。併せてご参照ください。
from sklearn.datasets import load_diabetes # 糖尿病に関するデータ
import seaborn as sns
df_diabetes = load_diabetes(as_frame=True).frame # サンプルデータを読み込む
sns.pairplot(df_diabetes, # 利用するデータ
hue="sex", # 性別による色分けを行う
diag_kind="hist", # 対角線上はヒストグラムとする
palette = "Set1") # 配色はSet1を使う
今回は、散布図を利用して間隔尺度の項目間の関係を可視化しました。バブルチャートを利用すれば、それらの関係に加えて、規模を可視化し、さらなる分析に役立てることができます。バブルチャートの色分けや多数の散布図の作成などについては、コラムでPythonのプログラムを紹介しました。今回で「可視化シリーズ」はひと区切りです。
次回は関係の強さを数値で表すために、相関係数を計算するとともに、その仕組みについても見ていきます。それ以降の回帰分析による予測へとつながっていくお話です。次回もどうぞお楽しみに!
Copyright© Digital Advantage Corp. All Rights Reserved.