チュートリアル: 機能依存関係を使用してデータをクリーンアップする
このチュートリアルでは、データ クリーニングに機能依存関係を使用します。 機能依存関係は、セマンティック モデル (Power BI データセット) 内の 1 つの列が別の列の関数である場合に存在します。 たとえば、zip code 列によって city 列の値が決まる場合があります。 機能依存関係は、DataFrame 内の 2 つ以上の列の値間の一対多のリレーションシップとして現れます。 このチュートリアルでは、Synthea データセットを使用して、機能リレーションシップがデータ品質の問題の検出にどのように役立つかを示します。
このチュートリアルでは、次の作業を行う方法について説明します。
- ドメインの知識を応用して、セマンティック モデル内の機能依存関係に関する仮説を立てます。
- データ品質分析の自動化に役立つセマンティック リンクの Python ライブラリ (SemPy) のコンポーネントに関する理解を深めます。 コンポーネントには、次が含まれます。
- FabricDataFrame - 追加のセマンティック情報で強化された pandas のような構造体。
- 機能依存関係に関する仮説の評価を自動化し、セマンティック モデル内のリレーションシップの違反を識別するための便利な関数。
前提条件
Microsoft Fabric サブスクリプションを取得します。 または、無料の Microsoft Fabric 試用版にサインアップします。
Microsoft Fabric にサインインします。
ホーム ページの左側にある環境スイッチャーを使って、Synapse Data Science 環境に切り替えます。
- 左側のナビゲーション ペインから [ワークスペース] を選択して、お使いのワークスペースを見つけて選択します。 このワークスペースが現在のワークスペースになります。
ノートブックで作業を進める
このチュートリアルには、data_cleaning_functional_dependencies_tutorial.ipynb ノートブックが付属しています。
このチュートリアルに付随するノートブックを開くには、「データ サイエンス用にシステムを準備する」チュートリアル の手順に従い、ノートブックをお使いのワークスペースにインポートします。
このページからコードをコピーして貼り付ける場合は、[新しいノートブックを作成する] ことができます。
コードの実行を開始する前に、必ずレイクハウスをノートブックにアタッチしてください。
ノートブックを設定する
このセクションでは、必要なモジュールとデータを含むノートブック環境を設定します。
- Spark 3.4 以降では、Fabric を使用する場合、セマンティック リンクは既定のランタイムで使用でき、インストールする必要はありません。 Spark 3.3 以前を使用している場合、またはセマンティック リンクの最新バージョンに更新する場合は、次のコマンドを実行できます。
python %pip install -U semantic-link
後で必要になるモジュールの必要なインポートを実行します。
import pandas as pd import sempy.fabric as fabric from sempy.fabric import FabricDataFrame from sempy.dependencies import plot_dependency_metadata from sempy.samples import download_synthea
サンプル データをプルします。 このチュートリアルでは、合成医療記録の Synthea データセットを使用します (わかりやすくするために小さいバージョン)。
download_synthea(which='small')
データを検索する
providers.csv ファイルの内容を使用して
FabricDataFrame
を初期化します。providers = FabricDataFrame(pd.read_csv("synthea/csv/providers.csv")) providers.head()
自動検出された機能依存関係のグラフをプロットして、SemPy の
find_dependencies
関数を使用してデータ品質の問題がないかを確認します。deps = providers.find_dependencies() plot_dependency_metadata(deps)
機能依存関係のグラフでは、
Id
によってNAME
とORGANIZATION
(実線の矢印で示されます) が決まることが示されています。これは、Id
が一意であるため、想定通りです。Id
が一意であることを確認します。providers.Id.is_unique
コードは
True
を返します。これにより、Id
が一意であることが確認されます。
機能依存関係を詳細に分析する
また、機能依存関係グラフは、ORGANIZATION
によって ADDRESS
と ZIP
が想定どおりに決まることも示しています。 ただし、ZIP
によって CITY
も決まることを想定しているかもしれませんが、破線の矢印は、依存関係が近似的であるに過ぎないことを示しており、データ品質の問題を指しています。
グラフには他にも特徴があります。 たとえば、NAME
によって GENDER
、Id
、SPECIALITY
、ORGANIZATION
は決まりません。 これらの各特徴は、調査する価値があるかもしれません。
SemPy の
list_dependency_violations
関数を使用して違反の表形式の一覧を表示して、ZIP
とCITY
の間の近似的なリレーションシップを詳しく見てみましょう。providers.list_dependency_violations('ZIP', 'CITY')
SemPy の
plot_dependency_violations
視覚化関数を使用してグラフを描画します。 このグラフは、違反数が少ない場合に有用です。providers.plot_dependency_violations('ZIP', 'CITY')
依存関係違反のプロットには、左側に
ZIP
の値、右側にCITY
の値が示されています。 この 2 つの値を含む行がある場合、エッジはプロットの左側の郵便番号と右側の都市を接続します。 エッジには、そのような行の数を示す注釈が付けられています。 たとえば、前のプロットと次のコードに示されているように、郵便番号が 02747-1242 である行が 2 つあり、そのうち 1 つの行の都市が "NORTH DARTHMOUTH" で、もう 1 つの行の都市が "DARTHMOUTH" です。次のコードを実行して、依存関係違反のプロットで行った以前の観察結果を確認します。
providers[providers.ZIP == '02747-1242'].CITY.value_counts()
このプロットでは、
CITY
が "DARTHMOUTH" である行のうち、9 つの行のZIP
が 02747-1262、1 つの行のZIP
が 02747-1242、1 つの行のZIP
が 02747-2537 であることも示されています。 次のコードを使用して、これらの観察結果を確認します。providers[providers.CITY == 'DARTMOUTH'].ZIP.value_counts()
"DARTMOUTH" に関連付けられている郵便番号は他にもありますが、これらの郵便番号は、データ品質の問題を示唆していないため、依存関係違反のグラフには表示されていません。 たとえば、郵便番号 "02747-4302" は "DARTMOUTH" に一意に関連付けられているため、依存関係違反のグラフには表示されていません。 次のコードを実行して確認します。
providers[providers.ZIP == '02747-4302'].CITY.value_counts()
SemPy で検出されたデータ品質の問題を要約する
依存関係違反のグラフに戻ると、このセマンティック モデルにいくつかの興味深いデータ品質の問題が存在していることがわかります。
- 一部の都市名はすべて大文字です。 この問題は、文字列メソッドを使用して簡単に修正できます。
- 一部の都市名には、"North" や "East" などの修飾子 (またはプレフィックス) があります。 たとえば、郵便番号 "2128" は "EAST BOSTON" に 1 回、"BOSTON" に 1 回マップされています。 同様の問題は、"NORTH DARTHMOUTH" と "DARTHMOUTH" の間でも発生しています。 これらの修飾子を削除したり、最も出現数の多い都市に郵便番号をマップしてみてください。
- 一部の都市では入力ミスがあります。たとえば、 "PITTSFIELD" と"PITTSFILED" や、"NEWBURGPORT" と"NEWBURYPORT" などです。 "NEWBURGPORT" の場合、この入力ミスは最も出現数の多いものを使用して修正できます。 "PITTSFIELD" の場合、それぞれが 1 回しか出現していないため、外部の知識や言語モデルの使用なしで自動的にあいまいさを解消するのは非常に困難です。
- 場合によっては、"West" のようなプレフィックスが 1 文字の "W" に省略されることがあります。 この問題は、出現するすべての "W" が "West" を表している場合には、単純な置換で修正できる可能性があります。
- 郵便番号 "02130" は "BOSTON" に 1 回、"Jamaica Plain" に 1 回マップされています。 この問題は簡単に修正できませんが、データが多い場合は、最も出現数の多いものにマッピングすることが解決策になる可能性があります。
データを整理する
すべての大文字/小文字の使用をタイトル ケース (先頭文字を大文字) に変更して、大文字/小文字の問題を修正します。
providers['CITY'] = providers.CITY.str.title()
違反検出をもう一度実行して、いくつかのあいまいさが消えた (違反数が減った) ことを確認します。
providers.list_dependency_violations('ZIP', 'CITY')
この時点で、データをさらに手動で絞り込むこともできますが、データのクリーンアップ タスクの 1 つとして、SemPyの
drop_dependency_violations
関数を使用してデータ内の列間の機能制約に違反する行を削除することが考えられます。決定変数の各値に対して、
drop_dependency_violations
は、従属変数の最も一般的な値を選択し、その他の値を持つすべての行を削除することで機能します。 この操作を適用するのは、この統計ヒューリスティックによって得られる結果がデータに対して正しいものになると確信している場合だけにしてください。 それ以外の場合は、必要に応じて、検出された違反を処理する独自のコードを記述してください。ZIP
およびCITY
列でdrop_dependency_violations
関数を実行します。providers_clean = providers.drop_dependency_violations('ZIP', 'CITY')
ZIP
とCITY
の間の依存関係違反を一覧表示します。providers_clean.list_dependency_violations('ZIP', 'CITY')
このコードは、機能制約 CITY -> ZIP の違反が他にないことを示す空のリストを返します。
関連するコンテンツ
セマンティック リンク や SemPy については、他のチュートリアルを確認してください。