kakakakakku blog

Weekly Tech Blog : Keep on Learning 👍

NumPy で「n次元配列」を「1次元配列」に変換できる ravel() 関数と flatten() 関数の違い

NumPy で「n次元配列」を「1次元配列」に変換するときに ravel() 関数と flatten() 関数がサポートされている.ravel() 関数に関しては,正確には numpy.ravel() 関数と numpy.ndarray.ravel() 関数がある.それぞれの違いを整理するためにドキュメントを読みながら試してみた.今回は Numpy 1.20.2 を前提にする.

簡単に違いを整理しておくと,ravel() 関数は基本的には「参照」を返して,flatten() 関数は「コピー」を返す.パフォーマンスにも差がある.個人的には flatten という単語は Ruby で見たことがあるけど,ravel という単語は見たことがなかった!調べてみたら「ほぐす」や「ほどく」という意味だった.なるほどー💡

ravel() 関数を試す 🔢

まず,ravel() 関数(正確には numpy.ndarray.ravel() 関数)を試す.以下のように 3x3 の配列 base_array を作り,ravel() 関数を使うと,配列 ravel_array の結果の通り「1次元配列」に変換できた.

import numpy as np

base_array = np.array(
    [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]
    ]
)
base_array
# array([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])

ravel_array = base_array.ravel()
ravel_array
# array([1, 2, 3, 4, 5, 6, 7, 8, 9])

f:id:kakku22:20210510140705p:plain

次に配列 base_array の値を更新する.すると,配列 ravel_array の値も更新されていた.ravel() 関数は基本的には「参照」を返すため,配列 base_array だけではなく,配列 ravel_array にも影響する.なお,あえて「基本的には」と書いたのはドキュメントに以下のように書いてあるため.

A 1-D array, containing the elements of the input, is returned. A copy is made only if needed.

numpy.ravel — NumPy v1.20 Manual

base_array[1][1] = 50

base_array
# array([[ 1,  2,  3],
#        [ 4, 50,  6],
#        [ 7,  8,  9]])

ravel_array
# array([ 1,  2,  3,  4, 50,  6,  7,  8,  9])

f:id:kakku22:20210510121955p:plain

flatten() 関数を試す 🔢

次に flatten() 関数(正確には numpy.ndarray.flatten() 関数)を試す.同じく 3x3 の配列 base_array を作り,flatten() 関数を使うと,配列 flatten_array の結果の通り「1次元配列」に変換できた.ここまでは ravel() 関数と同じ挙動になる.

base_array = np.array(
    [
        [1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]
    ]
)
base_array
# array([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])

flatten_array = base_array.flatten()
flatten_array
# array([1, 2, 3, 4, 5, 6, 7, 8, 9])

f:id:kakku22:20210510123214p:plain

同じく配列 base_array の値を更新する.すると,配列 flatten_array の値は更新されていなかった.flatten() 関数は「コピー」を返すため,配列 flatten_array には影響しなかった.ドキュメントに以下のように書いてある.

Return a copy of the array collapsed into one dimension.

numpy.ndarray.flatten — NumPy v1.20 Manual

base_array[1][1] = 50

base_array
# array([[ 1,  2,  3],
#        [ 4, 50,  6],
#        [ 7,  8,  9]])

flatten_array
# array([1, 2, 3, 4, 5, 6, 7, 8, 9])

f:id:kakku22:20210510123438p:plain

ravel() 関数と flatten() 関数の実行時間を比較する 🔢

最後は Jupyter Notebook の %%timeit マジックコマンドを使って,ravel() 関数と flatten() 関数の実行時間を比較する.実行環境によって結果に差が出るため,あくまで MacBook Pro で計測したサンプル値として確認してもらえればと🙏

結果としては以下の通り,ある程度差が出る.flatten() 関数は相対的に遅く,「コピー」を返すためにメモリも多く消費するため,アプリケーション目線で用途によって使い分けるのが良さそう.

%%timeit
base_array.ravel()
# 152 ns ± 0.719 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%%timeit
base_array.flatten()
# 560 ns ± 7.72 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

f:id:kakku22:20210510125415p:plain

まとめ 🔢

Pandas に続き,今度は NumPy の機能を学んでいる.今回は NumPy で「n次元配列」を「1次元配列」に変換できる ravel() 関数と flatten() 関数を試しつつ,機能の違いも確認した.

関連記事 🔢

kakakakakku.hatenablog.com

Pandas の機能を実践的に学ぶならこの1冊!「Pandas ライブラリ活用入門」を読んだ

個人的に Pandas を使ってデータ分析をする機会が増えてきて,今までの浅い経験ではうまく使いこなせず,Pandas を中心に細かく学び直している.最近 Pandas 関連の記事を多く書いていることにも関連しているし,少し前には Pandas を学べる「Kaggle Courses」を紹介した.そして並行して「Pandas ライブラリ活用入門」を読んだため,書評をまとめておく.

目次 📚

全部で「第18章」から構成されている.また Python 入門者のために充実した付録も載っている.本書の序盤にも「読み方」が載っているけど,個人的には Pandas を優先的に学ぶなら「第1,2,3部」を読んで,機械学習にも興味があれば「第4部」まで読むと良いと思う.とは言え,Pandas を中心に主要な機能を解説したリファレンス的な内容になるため,全体をザッと流し読みしてから,気になった機能を実際に試しながら読み直すスタイルが僕には1番合っていた👍

  • 第1部「基本的な使い方の基本」
    • 第1ç«  : DataFrame の基礎
    • 第2ç«  : pandas のデータ構造
    • 第3ç«  : プロットによるグラフ描画
  • 第2部「データ操作によるクリーニング」
    • 第4ç«  : データを組み立てる
    • 第5ç«  : 欠損データへの対応
    • 第6ç«  : "整然データ"を作る
  • 第3部「データの準備―変換/整形/結合など」
    • 第7ç«  : データ型の概要と変換
    • 第8ç«  : テキスト文字列の操作
    • 第9ç«  : apply による関数の適用
    • 第10ç«  : groupby 演算による分割-適用-結合
    • 第11ç«  : 日付/時刻データの操作
  • 第4部「モデルをデータに適合させる」
    • 第12ç«  : 線形モデル
    • 第13ç«  : 一般化線形モデル
    • 第14ç«  : モデルを診断する
    • 第15ç«  : 正則化で過学習に対処する
    • 第16ç«  : クラスタリング
  • 第5部「締めくくり―次のステップへ」
    • 第17ç«  : pandas 周辺の強力な機能
    • 第18ç«  : さらなる学びのための情報源
  • 第6部「付録」
    • 付録 A : インストール
    • 付録 B : コマンドライン
    • 付録 C : プロジェクトのテンプレート
    • 付録 D : Python の使い方
    • 付録 E : ワーキングディレクトリ
    • 付録 F : 環境
    • 付録 G : パッケージのインストール
    • 付録 H : ライブラリのインポート
    • 付録 I : リスト
    • 付録 J : タプル
    • 付録 K : 辞書
    • 付録 L : 値のスライス
    • 付録 M : ループ
    • 付録 N : 内包表記 (comprehension)
    • 付録 O : 関数
    • 付録 P : 範囲とジェネレータ
    • 付録 Q : 複数代入
    • 付録 R : numpy の ndarray
    • 付録 S : クラス
    • 付録 T : Odo (TheShapeshifter)

本書の誤植は以下に載っている.

book.impress.co.jp

本書で使う Jupyter Notebook とデータセットは以下の GitHub リポジトリに公開されている.

github.com

Pandas 基礎の基礎 : DataFrame と Series 📚

第1章「DataFrame の基礎」と第2章「pandas のデータ構造」を読めば,Pandas の代表的なオブジェクトである DataFrame と Series の基本的な操作(関数や属性など)を学べる.例えばよく使う関数だと pd.read_csv() / head() / tail() / loc() / iloc() や,プロパティだと shape / columns など.他にもいろいろ載っている.

import pandas as pd
df = pd.read_csv('../data/gapminder.tsv', sep='\t')
type(df)
# pandas.core.frame.DataFrame
df.shape
# (1704, 6)
df.columns
# Index(['country', 'continent', 'year', 'lifeExp', 'pop', 'gdpPercap'], dtype='object')

f:id:kakku22:20210506100321p:plain

可視化 📚

第3章「プロットによるグラフ描画」では可視化テクニックを学べる.読む前は Matplotlib の解説かなぁーと予想していたけど,実際には Matplotlib だけではなく Seaborn や Pandas の DataFrame.plot を使った例も紹介されていた.Seaborn を使えばより高度なグラフをお手軽に描けるし,シンプルなグラフで良ければ Pandas でも描ける.また本書の冒頭にはグラフの例がカラー印刷で載っているため,グラフを見るだけでも楽しめる📊

  • ヒストグラム
  • 密度プロット
  • 散布図
  • hexbin(六角形ビニング)プロット
  • 箱ひげ図
  • etc
import matplotlib.pyplot as plt
import seaborn as sns
tips = sns.load_dataset('tips')
sns.lmplot(x='total_bill', y='tip', data=tips)
plt.show()

f:id:kakku22:20210506100430p:plain

実際に自分で考えたグラフを描こうとすると用語も理解しておく必要があり,Matplotlib のドキュメントに載っている Anatomy of a figure がとてもわかりやすかった.以下に引用して載せておく.

f:id:kakku22:20210506100640p:plain
Anatomy of a figure — Matplotlib documentation より引用

そして Seaborn を使った「ペアプロット図(散布図行列)」の実装は以下の記事で試したりもした

kakakakakku.hatenablog.com

整然データ 📚

第6章「"整然データ"を作る」を中心に第4,5,6章では「整然データ (Tidy Data)」を実現する Tips を学んでいく.「整然データ」は簡単に言えば,データセットを解析しやすくするために構造化したフレームワークで,以下の記事がとてもわかりやすかった.

id.fnshr.info

具体的な Tips としては,具体的には pd.concat() や merge() 関数を使ったデータセットの連結やインデックスの再設定,そして melt() 関数を使って「横持ち」のデータセットを「縦持ち」に変換するなど,実践的で参考になった.

また「欠損値 (Missing data) : NaN」の取り扱いも出てくる.NaN に関しては以下の記事で詳しく試した.

kakakakakku.hatenablog.com

日付操作 📚

第11章「日付/時刻データの操作」では,Pandas の日付や時刻に関連する機能を学べる.例えば pd.to_datetime() 関数を使うと指定したカラムを object 型から datetime64 型に変換できる.以下の例では Date を date_dt に datetime64 型として変換している.

import pandas as pd
ebola = pd.read_csv('../data/country_timeseries.csv')
ebola['date_dt'] = pd.to_datetime(ebola['Date'])
ebola.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 122 entries, 0 to 121
# Data columns (total 19 columns):
#  #   Column               Non-Null Count  Dtype         
# ---  ------               --------------  -----         
#  0   Date                 122 non-null    object        
#  1   Day                  122 non-null    int64         
#  2   Cases_Guinea         93 non-null     float64       
#  3   Cases_Liberia        83 non-null     float64       
#  4   Cases_SierraLeone    87 non-null     float64       
#  5   Cases_Nigeria        38 non-null     float64       
#  6   Cases_Senegal        25 non-null     float64       
#  7   Cases_UnitedStates   18 non-null     float64       
#  8   Cases_Spain          16 non-null     float64       
#  9   Cases_Mali           12 non-null     float64       
#  10  Deaths_Guinea        92 non-null     float64       
#  11  Deaths_Liberia       81 non-null     float64       
#  12  Deaths_SierraLeone   87 non-null     float64       
#  13  Deaths_Nigeria       38 non-null     float64       
#  14  Deaths_Senegal       22 non-null     float64       
#  15  Deaths_UnitedStates  18 non-null     float64       
#  16  Deaths_Spain         16 non-null     float64       
#  17  Deaths_Mali          12 non-null     float64       
#  18  date_dt              122 non-null    datetime64[ns]
# dtypes: datetime64[ns](1), float64(16), int64(1), object(1)
# memory usage: 18.2+ KB

f:id:kakku22:20210506100833p:plain

また pd.read_csv() 関数に parse_dates パラメータを指定すると,データセットを読み込むときに datetime64 型に変換できる.

import pandas as pd
ebola = pd.read_csv('../data/country_timeseries.csv', parse_dates=[0])
ebola.info()
# <class 'pandas.core.frame.DataFrame'>
# RangeIndex: 122 entries, 0 to 121
# Data columns (total 18 columns):
#  #   Column               Non-Null Count  Dtype         
# ---  ------               --------------  -----         
#  0   Date                 122 non-null    datetime64[ns]
#  1   Day                  122 non-null    int64         
#  2   Cases_Guinea         93 non-null     float64       
#  3   Cases_Liberia        83 non-null     float64       
#  4   Cases_SierraLeone    87 non-null     float64       
#  5   Cases_Nigeria        38 non-null     float64       
#  6   Cases_Senegal        25 non-null     float64       
#  7   Cases_UnitedStates   18 non-null     float64       
#  8   Cases_Spain          16 non-null     float64       
#  9   Cases_Mali           12 non-null     float64       
#  10  Deaths_Guinea        92 non-null     float64       
#  11  Deaths_Liberia       81 non-null     float64       
#  12  Deaths_SierraLeone   87 non-null     float64       
#  13  Deaths_Nigeria       38 non-null     float64       
#  14  Deaths_Senegal       22 non-null     float64       
#  15  Deaths_UnitedStates  18 non-null     float64       
#  16  Deaths_Spain         16 non-null     float64       
#  17  Deaths_Mali          12 non-null     float64       
# dtypes: datetime64[ns](1), float64(16), int64(1)
# memory usage: 17.3 KB

f:id:kakku22:20210506100846p:plain

さらに後半では「リサンプリング」と「タイムゾーン変換」の例も載っている.Pandas では resample() 関数を使って「ダウンサンプリング(高い周期から低い周期)」や「アップサンプリング(低い周期や高い周期)」に変換できる.tz_convert() 関数を使うとタイムゾーンを変換できる.

機械学習 📚

Pandas だけではなく機械学習にも興味があれば,第12章「線形モデル」から第16章「クラスタリング」までを読むと,Python の statsmodels や scikit-learn を使った機械学習モデルの実装例を学べる.目次の一部を抜粋すると以下などが載っている.ただし統計学の基礎から学べるわけではなく,あくまでライブラリを使った実装例の紹介が中心となるため,機械学習関連の他の本を併読するべきだと思う.前提知識に依存するところではあるけど,個人的には知識不足もあり本書だけだと理解できないところもあったし,本書の読者層も似た傾向になる気がする.

  • 線形モデル
    • 線形回帰
    • 重回帰
  • 一般化線形モデル
    • ロジスティック回帰
    • ポアソン回帰
  • 正規化
    • リッジ回帰
    • ラッソ回帰
    • 交差検証

まとめ 📚

Pandas の機能を深く理解するために「Pandas ライブラリ活用入門」を読んだ.実際に試して気付くことも多く,全体をザッと流し読みしてから,気になった機能を試しながら読み直した.リファレンス的な内容ではあるけど,Pandas でできることを全体把握できたため,読んで良かった💡今後は Pandas を使った機械学習など,実践的な内容に学習項目をステップアップしていくぞー!

scikit-learn でカテゴリ変数を変換する : OneHotEncoder と LabelEncoder

前回の記事では Pandas の get_dummies() 関数を使って「カテゴリ変数」の変換(One-Hot エンコーディング)を試した.

kakakakakku.hatenablog.com

Pandas 以外の選択肢として scikit-learn の sklearn.preprocessing モジュールを使うこともできる.今回は sklearn.preprocessing モジュールに含まれている OneHotEncoder クラスを試す.さらに関連するラベルエンコーディングとして LabelEncoder クラスも試す.

データセット 🔬

今回の検証も前回と同じく GitHub リポジトリ chendaniely/pandas_for_everyone に含まれているデータセット gapminder.tsv を使う.今回は結果をわかりやすくするために DataFrame を continent に限定しておく.また確認する値を赤と黄色で強調しておいた🖍

import sys
import pandas as pd
from sklearn.preprocessing import LabelEncoder, OneHotEncoder

gapminder = pd.read_csv('./gapminder.tsv', delimiter='\t').loc[:, ['continent']]
gapminder

f:id:kakku22:20210501001144p:plain

OneHotEncoder クラス 🔬

ドキュメントを参考に OneHotEncoder クラスを試す.まず fit() 関数で DataFrame を適用すると categories_ 属性でカテゴリを確認できる.次に transform() 関数で変換すると行列になる.categories_ 属性で確認したカテゴリと一致しているため,今回は Africa と Asia が 1 になっていて「One-Hot エンコーディング」を実現できている.なお,get_feature_names() 関数を使うと Pandas の get_dummies() 関数のような属性名を取得できる.

oh_encoder = OneHotEncoder()
oh_encoder.fit(gapminder)
oh_encoder.categories_
# [array(['Africa', 'Americas', 'Asia', 'Europe', 'Oceania'], dtype=object)]

oh_encoder.transform(gapminder).toarray()
# array([[0., 0., 1., 0., 0.],
#        [0., 0., 1., 0., 0.],
#        [0., 0., 1., 0., 0.],
#        ...,
#        [1., 0., 0., 0., 0.],
#        [1., 0., 0., 0., 0.],
#        [1., 0., 0., 0., 0.]])

oh_encoder.get_feature_names(['continent'])
# array(['continent_Africa', 'continent_Americas', 'continent_Asia', 'continent_Europe', 'continent_Oceania'], dtype=object)

f:id:kakku22:20210501001911p:plain

LabelEncoder クラス 🔬

次は「ラベルエンコーディング」を実現する LabelEncoder クラスを試す.「ラベルエンコーディング」ではエンコードした数値でそのまま変換するため,「One-Hot エンコーディング」とは違って,値ごとにカラムが増えることはなく,値も 0 と 1 以外にも入り得る.

同じように fit() 関数で適用すると classes_ 属性でカテゴリを確認できる.配列の添字から Africa = 0 や Americas = 1 や Asia = 2 であると確認できる.そして transform() 関数で変換すると [2, 2, 2, ..., 0, 0, 0] のような配列が返ってくる.これは Asia と Africa がエンコードされている.

l_encoder = LabelEncoder()
l_encoder.fit(gapminder.continent)
l_encoder.classes_
# array(['Africa', 'Americas', 'Asia', 'Europe', 'Oceania'], dtype=object)

l_encoder.transform(gapminder.continent)
# array([2, 2, 2, ..., 0, 0, 0])

f:id:kakku22:20210501002316p:plain

まとめ 🔬

Pandas の get_dummies() 関数に関連して,今回は scikit-learn の sklearn.preprocessing モジュールを使って OneHotEncoder クラス(One-Hot エンコーディング)と LabelEncoder クラス(ラベルエンコーディング)を試した.

scikit-learn も機能が多くあるため,1歩1歩学んでいくぞー💡

Pandas の get_dummies() 関数でカテゴリ変数をダミー変数に変換する

Pandas で get_dummies() 関数を使うと「カテゴリ変数」を「ダミー変数」に変換できる.「カテゴリ変数」とは,例えば「血液型」や「職業」など,限られた選択肢の中から選んだ値で,ENUM 型のようなイメージをするとわかりやすい💡分析業務を前提に考えると A や B や AB など,文字列のままだと計算しにくく,機械学習などの前処理として数値にエンコーディングする必要がある.そこで get_dummies() 関数を使う.今回は get_dummies() 関数の基本的な操作を試す.

pandas.pydata.org

データセット 🏷

今回の検証では,GitHub リポジトリ chendaniely/pandas_for_everyone に含まれているデータセット gapminder.tsv を使う.これは「国名 / 大陸名 / 平均余命などをまとめたデータセット」となり,1700 行程度含まれている.あくまでサンプルとして使う.GitHub リポジトリ jennybc/gapminder には Gapminder の公式データも載っている.

gapminder = pd.read_csv('./gapminder.tsv', delimiter='\t')
gapminder

f:id:kakku22:20210430210345p:plain

get_dummies() 関数を使う 🏷

get_dummies() 関数の引数に DataFrame を指定する.デフォルトでは「文字列」など dtype が object の全てのカラムを「ダミー変数」に変換する.スクリーンショットには一部しか表示されていないけど country と continent が変換対象となる.具体的には country の値によって,新しいカラム country_Afghanistan や country_Albania が追加されていて,それぞれの値は 0 と 1 になっている.なお,このように「N 個の値」に対して「N 個のカラム」を追加する方法を「One-Hot エンコーディング」と言う.

  • country_Afghanistan
  • country_Albania
  • country_Algeria
  • country_Angola
  • country_Argentina
  • etc
pd.get_dummies(gapminder).head(20)

f:id:kakku22:20210430210633p:plain

columns パラメータを使う 🏷

get_dummies() 関数に columns パラメータを指定すると「ダミー変数」に変換するカラムを指定できる.今回は continent を指定した.すると country はそのままとなり,新しいカラム continent_Africa や continent_Americas が追加された.

  • continent_Africa
  • continent_Americas
  • continent_Asia
  • continent_Europe
  • continent_Oceania
pd.get_dummies(gapminder, columns=['continent']).head(20)

f:id:kakku22:20210430211856p:plain

prefix_sep パラメータを使う 🏷

country_Afghanistan や continent_Africa など,デフォルトでは _ をセパレータとして新しいカラムが追加される.そこで prefix_sep パラメータを指定すると任意のセパレータに変更できる.今回はサンプルとして prefix_sep='/' とした.すると continent/Africa や continent/Americas など,期待通りにセパレータを変更できた.

pd.get_dummies(gapminder, columns=['continent'], prefix_sep='/').head(20)

f:id:kakku22:20210430212324p:plain

dummy_na パラメータを使う 🏷

get_dummies() 関数はデフォルトでは NaN を無視する.そこで dummy_na パラメータに True を指定すると continent/nan のように NaN も値として変換される.

pd.get_dummies(gapminder, columns=['continent'], prefix_sep='/', dummy_na=True).head(20)

f:id:kakku22:20210430212551p:plain

まとめ 🏷

Pandas で「カテゴリ変数」を「ダミー変数」に変換する get_dummies() 関数を試した.値によって新しいカラムを追加する「One-Hot エンコーディング」を簡単に実現できた.試せば試すほど Pandas の機能の豊富さに驚かされる.引き続き学んでいくぞ👍

Pandas で相関件数を計算して Seaborn で可視化する

Pandas で corr() 関数を使うと DataFrame と Series で「相関係数 (correlation coefficient)」を計算できる.今回は DataFrame の corr() 関数と Seaborn を使った可視化を試す.

相関係数 (correlation coefficient) 📊

まず「相関係数」とは「2種類のデータ (x, y) の線形的な関係性を表現する指標」で,値は -1 ~ 1 の範囲となる.大きく3種類あり「正の相関(x が増えると y が増える)」と「負の相関(x が増えると y が減る)」と「無相関」がある.相関係数が 1 に近いほど「正の相関」で,-1 に近いほど「負の相関」になる.例えば「勉強時間 x が長いと学力 y が高い」など💡

データセット 📊

今回の検証では,GitHub リポジトリ chendaniely/pandas_for_everyone に含まれているデータセット housing.csv を使う.これは「住宅情報をまとめたデータセット(コンドミニアム🏢)」となり,今回は以下の「3カラム」に限定して関係性を見ていく.

  • Total.Units : 部屋数
  • Year.Built : 建設年
  • Full.Market.Value : 市場価値
housing = pd.read_csv('./housing.csv').loc[:, ['Total.Units', 'Year.Built', 'Full.Market.Value']]
housing

f:id:kakku22:20210423235309p:plain

よって,今回は以下の組み合わせで「相関係数」を計算する.

  • Total.Units と Year.Built(部屋数と建設年には相関はある?)
  • Total.Units と Full.Market.Value(部屋数と市場価値には相関はある?)
  • Year.Built と Full.Market.Value(建設年と市場価値には相関はある?)

ペアプロット図(散布図行列)📊

まず DataFrame の関係性を「ペアプロット図(散布図行列)」で可視化する.Seaborn の pairplot() 関数を使えば簡単に描画できる.散布図をザッと見ると Total.Units と Full.Market.Value には緩やかな「正の相関」があるように見える.そして Total.Units と Year.Built や Year.Built と Full.Market.Value は「無相関」のように見える.

figure = sns.pairplot(housing, plot_kws = {'alpha': 0.5})
figure.fig.set_figheight(10)
figure.fig.set_figwidth(10)

f:id:kakku22:20210423222703p:plain

なお「散布図」は Pandas の DataFrame.plot.scatter() 関数や plotting.scatter_matrix() 関数を使って描画することもできるけど,今回は「Pandas ライブラリ活用入門」にも載っていた Seaborn を試したくて使った.

相関係数 : corr() 関数 📊

次に Pandas の corr() 関数を使って相関係数を計算する.散布図を見て判断した通り,Total.Units と Full.Market.Value の相関係数は 0.661639 となり,ある程度「正の相関」があると確認できる.

corr = housing.corr()
corr

f:id:kakku22:20210423224136p:plain

相関係数とヒートマップ 📊

最後は corr() 関数を使って計算した相関係数をヒートマップで可視化する.Seaborn の heatmap() 関数を使えば簡単に描画できる.色は設定で変えられるけど,今回の設定だと「正の相関」だと赤くなり「無相関」だと黒くなる.もっとカラム(特徴量)が多くても関係性を見極めることができそう.

sns.heatmap(corr, vmax=1, vmin=-1, center=0)

f:id:kakku22:20210423224233p:plain

まとめ 📊

Pandas の corr() 関数を使って「相関係数 (correlation coefficient)」を計算して,Seaborn の heatmap() 関数を使って可視化した.「相関係数」に関しては,最近並行して読んでいる「Python によるあたらしいデータ分析の教科書」にも載っていた.正確には「ピアソンの積率相関係数」と「スピアマンの順位相関係数」と「ケンドールの順位相関係数」という指標があり,corr() 関数は method パラメータでそれぞれの指標をサポートしていることも確認できた.

df.corr(method='pearson')
df.corr(method='kendall')
df.corr(method='spearman')