🐈

Great Expectations(GX Core)始め方と注意ポイント

に公開

はじめに

データ品質管理のフレームワークの Great Expectations(GX Core)
Pythonライブラリとしてローカル環境に簡単に導入でき、期待値(Expectation)をコードで定義・実行し、HTMLベースのレポート(Data Docs)を自動生成できます。
本記事では、個人開発・小規模プロジェクト向けに GX Core の導入手順注意ポイント をまとめます。

GX Core (OSS版) とは

GX Core は、Great Expectations のオープンソース版です。

  • Python ライブラリとして提供され、自分のローカル環境やオンプレミスサーバー上で動作します。
  • コード(Python/YAML)で期待値を定義し、CLI や Jupyter Notebook からバリデーション実行が可能。
  • 完全無料で利用でき、Data Docs(HTML レポート)やデータプロファイリングなど豊富な機能を備えます。

https://greatexpectations.io/gx-core/

ドキュメントに気をつけて

執筆時点(2025年5月)では、1.4.2のようです。

(私は0.17.23を見ながら実行していて、所々エラーで詰まってしまいました...)

Google Colabで動かせなかった

Google Colabratoryで試してみました。
しかし、以下の依存関係のエラーを上手く解決できず、Google Colabを断念し、ローカルJupyter Notebookで検証することにしました。(時間をかけずに試してみたかった。)

環境構築でつまづく

ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
google-colab 1.0.0 requires pandas==2.2.2, but you have pandas 2.1.4 which is incompatible.
plotnine 0.14.5 requires pandas>=2.2.0, but you have pandas 2.1.4 which is incompatible.
mizani 0.13.3 requires pandas>=2.2.0, but you have pandas 2.1.4 which is incompatible.
thinc 8.3.6 requires numpy<3.0.0,>=2.0.0, but you have numpy 1.26.4 which is incompatible.
Successfully installed altair-4.2.2 backoff-2.2.1 great_expectations-1.4.2 marshmallow-3.26.1 monotonic-1.6 numpy-1.26.4 pandas-2.1.4 posthog-3.25.0 ruamel.yaml-0.18.10 ruamel.yaml.clib-0.2.12
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1-093744af7b6d> in <cell line: 0>()
      1 get_ipython().system('pip install great_expectations')
      2 
----> 3 import great_expectations as gx
      4 
      5 print(gx.__version__)

14 frames
/usr/local/lib/python3.11/dist-packages/numpy/random/_pickle.py in <module>
----> 1 from .mtrand import RandomState
      2 from ._philox import Philox
      3 from ._pcg64 import PCG64, PCG64DXSM
      4 from ._sfc64 import SFC64
      5 

numpy/random/mtrand.pyx in init numpy.random.mtrand()

ValueError: numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C header, got 88 from PyObject

ローカル環境のJupyter Notebookで検証

その他、諸々試してみましたが、他のライブラリの依存関係を解決できなかったので(時間ももったいないので)ローカル環境のJupyter Notebookで検証しました。

以下のドキュメントも参考になります。
https://docs.greatexpectations.io/docs/core/set_up_a_gx_environment/install_gx

import sys
import notebook
import great_expectations
import jinja2

print("Python:", sys.version)
print("Notebook:", notebook.__version__)
print("Great Expectations:", great_expectations.__version__)
print("Jinja2:", jinja2.__version__)


バージョンは上記でした。

!pip install great_expectations
import great_expectations as gx

print(gx.__version__)


無事、インストールできました。

チュートリアルを進めるがエラーが発生する

import pandas as pd
df = pd.read_csv(
    "https://raw.githubusercontent.com/great-expectations/gx_tutorials/main/data/yellow_tripdata_sample_2019-01.csv"
)

しかし、所々でドキュメントのコードをコピーしてもエラーが発生します。
理由は表示されているコードと実際にコピーしたコードが異なるためです。

ドキュメントにあるコードをコピーして実行すると

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[10], line 4
      1 import great_expectations as gx
      3 context = gx.get_context()
----> 4 set_up_context_for_example(context)
      6 # All Expectations are found in the `gx.expectations` module.
      7 # This Expectation has all values set in advance:
      8 preset_expectation = gx.expectations.ExpectColumnMaxToBeBetween(
      9     column="passenger_count", min_value=1, max_value=6
     10 )

NameError: name 'set_up_context_for_example' is not defined

上記のようにset_up_context_for_exampleなんて無いよと怒られるのですが、そもそもドキュメントにはset_up_context_for_exampleは表示されていないのに、コピーをするとset_up_context_for_exampleが使用されてしまいます。

他にもドキュメントの順番通りに実行するも、いくつかの変数が存在しない、や前提となるsuite, validation等が存在しない、等のいくつかの引っ掛かりポイントがありました。

動くものを作成する

結果的に以下のような実行結果を得られることに成功しました。
生成されたHTMLは以下です。

それぞれの品質チェック内容は詳細ページに存在します。

以下は私がとりあえず動けばいいやで作成したコードです。

import great_expectations as gx
import pandas as pd

# ファイルパスを指定
file_path = "https://raw.githubusercontent.com/great-expectations/gx_tutorials/main/data/yellow_tripdata_sample_2019-01.csv"

# Step 1: Context 初期化
context = gx.get_context(mode="file")

# Step 2: Expectation Suite 作成
times = "27"
suite_name = "my_expectation_suite" + times
data_source_name = "my_data_source" + times
site_name = "my_data_docs_site" + times
validation_definition_name = "my_validation_definition" + times
suite = gx.ExpectationSuite(name=suite_name)
suite = context.suites.add(suite)

# Step 3: Expectation を追加
suite.add_expectation(
    gx.expectations.ExpectColumnValuesToNotBeNull(column="passenger_count")
)
suite.add_expectation(
    gx.expectations.ExpectColumnValuesToNotBeNull(column="pickup_datetime")
)
suite.add_expectation(
    gx.expectations.ExpectColumnValuesToBeBetween(column="fare_amount", min_value=0)
)

# Step 4: 別の列に変更して保存
expectation = gx.expectations.ExpectColumnValuesToNotBeNull(column="pickup_location_id")
suite.add_expectation(expectation)

# Step 5: データ読み込み
df = pd.read_csv(file_path)

# Step 6: データソース・データアセット追加

data_asset_name = "my_dataframe_data_asset"
data_source = context.data_sources.add_pandas(name=data_source_name)
data_asset = data_source.add_dataframe_asset(name=data_asset_name)
# Define the Batch Definition name
batch_definition_name = "my_batch_definition"

# Add a Batch Definition to the Data Asset
batch_definition = data_asset.add_batch_definition_whole_dataframe(
    batch_definition_name
)
batch_definition_name = "my_batch_definition"
batch_definition = (
    context.data_sources.get(data_source_name)
    .get_asset(data_asset_name)
    .get_batch_definition(batch_definition_name)
)
batch_parameters = {"dataframe": df}
batch = batch_definition.get_batch(batch_parameters=batch_parameters)

# Step 7: Validation Definition 作成
validation_definition = gx.ValidationDefinition(
    data=batch_definition,
    suite=suite,
    name=validation_definition_name,
)
context.validation_definitions.add(validation_definition)

# Step 8: Data Docs サイト構成追加
base_directory = "uncommitted/data_docs/local_site/"
site_config = {
    "class_name": "SiteBuilder",
    "site_index_builder": {"class_name": "DefaultSiteIndexBuilder"},
    "store_backend": {
        "class_name": "TupleFilesystemStoreBackend",
        "base_directory": base_directory,
    },
}
context.add_data_docs_site(site_name=site_name, site_config=site_config)

# Step 9: チェックポイント作成・実行
actions = [
    gx.checkpoint.actions.UpdateDataDocsAction(
        name="update_my_site", site_names=[site_name]
    )
]
checkpoint = context.checkpoints.add(
    gx.Checkpoint(
        name="my_checkpoint" + times,
        validation_definitions=[validation_definition],
        actions=actions,
    )
)
result = checkpoint.run(batch_parameters)

# Step 10: Data Docs を開く
context.open_data_docs()

最後に

今回は Great Expectations(GX Core) を触ってみましたが、なかなかドキュメントのチュートリアル通りに進めることができませんでした。前提となる知識(context, suite, expectation, asset等)がどう紐づくかが理解しづらかった印象です。

もう少し実データで使ってみてから、使い心地を試したい気持ちです。

Discussion