チュートリアル パート 2: Microsoft Fabric ノートブックを使用してデータを探索して視覚化する
このチュートリアルでは、探索的データ分析 (EDA) を実施し、データ視覚化手法を使ってデータの主な特徴を要約しながら、データを確認および調査する方法について説明します。
seaborn
(データフレームと配列でビジュアルを構築するための高度なインターフェイスを提供する Python データ視覚化ライブラリ) を使います。 seaborn
の詳細については、「Seaborn: 統計データの視覚化」を参照してください。
また、Data Wrangler (探索的データ分析とクリーニングを実行するためのイマーシブ エクスペリエンスを提供するノートブック ベースのツール) も使います。
このチュートリアルの主な手順は次のとおりです。
- レイクハウス内の差分テーブルから格納データを読み取ります。
- Spark データフレームを、Python 視覚化ライブラリでサポートされている Pandas データフレームに変換します。
- Data Wrangler を使って、初期データのクリーニングと変換を実行します。
seaborn
を使って探索的データ分析を実行します。
前提条件
Microsoft Fabric サブスクリプションを取得します。 または、無料の Microsoft Fabric 試用版にサインアップします。
Microsoft Fabric にサインインします。
ホーム ページの左側にある環境スイッチャーを使って、Synapse Data Science 環境に切り替えます。
これは、5 部構成のチュートリアル シリーズのパート 2 です。 このチュートリアルを完了するには、最初に次の手順を完了します。
ノートブックで作業を進める
2-explore-cleanse-data.ipynb は、このチュートリアルに付属するノートブックです。
このチュートリアルに付随するノートブックを開くには、「データ サイエンス用にシステムを準備する」チュートリアル の手順に従い、ノートブックをお使いのワークスペースにインポートします。
このページからコードをコピーして貼り付ける場合は、[新しいノートブックを作成する] ことができます。
コードの実行を開始する前に、必ずレイクハウスをノートブックにアタッチしてください。
重要
パート 1 で使ったものと同じレイクハウスをアタッチします。
レイクハウスから生データを読み取る
レイクハウスの [ファイル] セクションから生データを読み取ります。 前のノートブックでこのデータをアップロードしました。 このコードを実行する前に、パート 1 で使ったものと同じレイクハウスをこのノートブックにアタッチしていることを確認します。
df = (
spark.read.option("header", True)
.option("inferSchema", True)
.csv("Files/churn/raw/churn.csv")
.cache()
)
データセットから pandas データフレームを作成する
処理と視覚化を容易にするために、spark データフレームを pandas データフレームに変換します。
df = df.toPandas()
生データを表示する
display
を使用して生データを探索し、基本的な統計の実行およびグラフ ビューの表示を行います。 データ分析と視覚化に必要なライブラリ (Numpy
、Pnadas
、Seaborn
、Matplotlib
など) をインポートする必要があることに注意してください。
import seaborn as sns
sns.set_theme(style="whitegrid", palette="tab10", rc = {'figure.figsize':(9,6)})
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib import rc, rcParams
import numpy as np
import pandas as pd
import itertools
display(df, summary=True)
Data Wrangler を使って最初のデータ クリーニングを実行する
ノートブック内の pandas データフレームを確認して変換するには、Data Wrangler をノートブックから直接起動します。
Note
ノートブック カーネルがビジー状態の間は、Data Wrangler を開くことができません。 Data Wrangler を起動する前に、セルの実行を完了する必要があります。
- ノートブック リボンの [データ] タブで、[Data Wrangler の起動] を選びます。 編集可能でアクティブな pandas データフレームの一覧が表示されます。
- Data Wrangler で開くデータフレームを選びます。 このノートブックに含まれる DataFrame は
df
の 1 つのみなので、df
を選びます。
Data Wrangler が起動し、データを説明する概要が生成されます。 中央のテーブルには、各データ列が表示されます。 テーブルの横にある [概要] パネルには、DataFrame に関する情報が表示されます。 テーブル内の列を選ぶと、選んだ列に関する情報で概要が更新されます。 場合によっては、表示および要約されたデータは、データフレームの一部が切り捨てられたビューになります。 この場合、概要ペインに警告画像が表示されます。 この警告にカーソルを合わせると、状況を説明するテキストが表示されます。
実行する各操作は、数回クリックするだけで適用でき、リアルタイムでデータ表示を更新し、再利用可能な関数としてノートブックに保存できるコードを生成します。
このセクションの残りの部分では、Data Wrangler でデータ クリーニングを実行する手順について説明します。
重複する行をドロップする
左側のパネルには、データセットに対して実行できる操作一覧 ([検索と置換]、[書式設定]、[数式]、[数値] など) があります。
[検索と置換] を展開し、[重複する行をドロップする] を選びます。
比較する列の一覧を選び、重複する行を定義するためのパネルが表示されます。 RowNumber と CustomerId を選びます。
中央のパネルには、この操作の結果のプレビューが表示されます。 プレビューの下には、操作を実行するコードがあります。 この場合、データは変更されていないように見えます。 ただし、表示されているのは切り捨てられたビューなので、この操作を適用することをお勧めします。
[適用] を選んで (横または下部にあります) 次の手順に進みます。
欠損データがある行をドロップする
Data Wrangler を使って、すべての列で欠損データがある行をドロップします。
列の削除
Data Wrangler を使って不要な列をドロップします。
[スキーマ] を展開し、[Drop columns] (列のドロップ) を選びます。
RowNumber、CustomerId、Surname を選びます。 これらの列は、コードによって変更された (この場合はドロップされた) ことを示すために、プレビューでは赤色で表示されます。
[適用] を選んで次の手順に進みます。
ノートブックにコードを追加する
[適用] を選ぶたびに、左下の [Cleaning steps] (クリーニング手順) パネルに新しい手順が作成されます。 パネルの下部にある [すべての手順のコードをプレビューする] を選ぶと、すべての個別手順の組み合わせが表示されます。
左上隅の [ノートブックにコードを追加する] を選ぶと、Data Wrangler が閉じ、コードが自動的に追加されます。 [Add code to notebook] (ノートブックにコードを追加する) を使うと、コードが関数にラップされ、その関数が呼び出されます。
ヒント
Data Wrangler によって生成されたコードは、新しいセルを手動で実行するまで適用されません。
Data Wrangler を使わなかった場合は、代わりにこの次のコード セルを使用できます。
このコードは Data Wrangler によって生成されたコードと似ていますが、生成された各手順に引数 inplace=True
が追加されています。 inplace=True
を設定することで、pandas は出力として新しいデータフレームを生成する代わりに元のデータフレームを上書きします。
# Modified version of code generated by Data Wrangler
# Modification is to add in-place=True to each step
# Define a new function that include all above Data Wrangler operations
def clean_data(df):
# Drop rows with missing data across all columns
df.dropna(inplace=True)
# Drop duplicate rows in columns: 'RowNumber', 'CustomerId'
df.drop_duplicates(subset=['RowNumber', 'CustomerId'], inplace=True)
# Drop columns: 'RowNumber', 'CustomerId', 'Surname'
df.drop(columns=['RowNumber', 'CustomerId', 'Surname'], inplace=True)
return df
df_clean = clean_data(df.copy())
df_clean.head()
データを検索する
クリーンされたデータの概要と視覚化を表示します。
カテゴリ、数値、ターゲットの各属性を決める
このコードを使用して、カテゴリ、数値、ターゲットの各属性を決定します。
# Determine the dependent (target) attribute
dependent_variable_name = "Exited"
print(dependent_variable_name)
# Determine the categorical attributes
categorical_variables = [col for col in df_clean.columns if col in "O"
or df_clean[col].nunique() <=5
and col not in "Exited"]
print(categorical_variables)
# Determine the numerical attributes
numeric_variables = [col for col in df_clean.columns if df_clean[col].dtype != "object"
and df_clean[col].nunique() >5]
print(numeric_variables)
5 つの数値の概要
次のボックス プロットを使って、数値属性の 5 つの数値の概要 (最小スコア、最初の四分位数、中央値、第 3 四分位数、最大スコア) を表示します。
df_num_cols = df_clean[numeric_variables]
sns.set(font_scale = 0.7)
fig, axes = plt.subplots(nrows = 2, ncols = 3, gridspec_kw = dict(hspace=0.3), figsize = (17,8))
fig.tight_layout()
for ax,col in zip(axes.flatten(), df_num_cols.columns):
sns.boxplot(x = df_num_cols[col], color='green', ax = ax)
fig.delaxes(axes[1,2])
離反した顧客と離反していない顧客の分布
次のカテゴリ属性全体の、離反した顧客と離反していない顧客の分布を表示します。
attr_list = ['Geography', 'Gender', 'HasCrCard', 'IsActiveMember', 'NumOfProducts', 'Tenure']
fig, axarr = plt.subplots(2, 3, figsize=(15, 4))
for ind, item in enumerate (attr_list):
sns.countplot(x = item, hue = 'Exited', data = df_clean, ax = axarr[ind%2][ind//2])
fig.subplots_adjust(hspace=0.7)
数値属性の分布
ヒストグラムを使用して数値属性の頻度分布を表示します。
columns = df_num_cols.columns[: len(df_num_cols.columns)]
fig = plt.figure()
fig.set_size_inches(18, 8)
length = len(columns)
for i,j in itertools.zip_longest(columns, range(length)):
plt.subplot((length // 2), 3, j+1)
plt.subplots_adjust(wspace = 0.2, hspace = 0.5)
df_num_cols[i].hist(bins = 20, edgecolor = 'black')
plt.title(i)
plt.show()
特徴エンジニアリングを実行する
特徴エンジニアリングを実行して、現在の属性に基づいて新しい属性を生成します。
df_clean["NewTenure"] = df_clean["Tenure"]/df_clean["Age"]
df_clean["NewCreditsScore"] = pd.qcut(df_clean['CreditScore'], 6, labels = [1, 2, 3, 4, 5, 6])
df_clean["NewAgeScore"] = pd.qcut(df_clean['Age'], 8, labels = [1, 2, 3, 4, 5, 6, 7, 8])
df_clean["NewBalanceScore"] = pd.qcut(df_clean['Balance'].rank(method="first"), 5, labels = [1, 2, 3, 4, 5])
df_clean["NewEstSalaryScore"] = pd.qcut(df_clean['EstimatedSalary'], 10, labels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
Data Wrangler を使用してワンホット エンコードを実行する
Data Wrangler を使って、One-hot エンコードを実行することもできます。 これを行うには、Data Wrangler を開き直します。 今回は df_clean
データを選びます。
- [数式] を展開し、[One-hot エンコード] を選びます。
- One-hot エンコードを実行する列の一覧を選ぶパネルが表示されます。 Geography と Gender を選びます。
この生成されたコードをコピーし、Data Wrangler を閉じてノートブックに戻り、新しいセルに貼り付けることができます。 または、左上隅の [Add code to notebook] (ノートブックにコードを追加する) を選ぶと、Data Wrangler が閉じ、コードが自動的に追加されます。
Data Wrangler を使わなかった場合は、代わりにこの次のコード セルを使用できます。
# This is the same code that Data Wrangler will generate
import pandas as pd
def clean_data(df_clean):
# One-hot encode columns: 'Geography', 'Gender'
df_clean = pd.get_dummies(df_clean, columns=['Geography', 'Gender'])
return df_clean
df_clean_1 = clean_data(df_clean.copy())
df_clean_1.head()
探索的データ分析からの観測の概要
- スペインやドイツに比べ、フランスからの顧客がほとんどですが、スペインはフランスやドイツに比べてチャーン率が最も低くなっています。
- ほとんどの顧客はクレジット カードを持っています。
- 年齢とクレジット スコアがそれぞれ、60 歳より上および 400 点未満の顧客がいますが、外れ値と見なすことはできません。
- 銀行の商品を 2 つ以上持っている顧客はごくわずかです。
- アクティブでない顧客は、チャーン率が高くなります。
- 性別と利用期間 (年数) は、銀行口座を閉じるという顧客の決定には影響を与えないようです。
クリーンされたデータの差分テーブルを作成する
このデータは、このシリーズの次のノートブックで使います。
table_name = "df_clean"
# Create Spark DataFrame from pandas
sparkDF=spark.createDataFrame(df_clean_1)
sparkDF.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark dataframe saved to delta table: {table_name}")
次のステップ
このデータを使って機械学習モデルをトレーニングして登録します。