Spaces and DataStore

Spaces and DataStore#

このセクションでは、MINTOの内部構造と主要なコンポーネントについて説明します。これにより、MINTOがどのように動作するかを理解し、より高度な使用方法やカスタマイズが可能になります。

QuickStartでは、MINTOの基本的な使用方法について説明しました。まずはExperiment.runsから取得できるそれぞれの記録を表すDataStoreオブジェクトについて説明します。

まずはQuickStartと同じ数値実験用のコードを用意して実行しましょう。

import minto
import ommx_pyscipopt_adapter as scip_ad
from ommx.dataset import miplib2017

instance_name = "reblock115"
instance = miplib2017(instance_name)

timelimit_list = [0.1, 0.5, 1, 2]

experiment = minto.Experiment(
    "quickstart_example",
    auto_saving=False,     # True is recommended, but set to False for demonstration
    verbose_logging=False  # True is recommended, but set to False for demonstration
)

adapter = scip_ad.OMMXPySCIPOptAdapter(instance)
scip_model = adapter.solver_input

for timelimit in timelimit_list:
    with experiment.run() as run:
        run.log_parameter("timelimit", timelimit)

        scip_model.setParam("limits/time", timelimit)
        scip_model.optimize()
        solution = adapter.decode(scip_model)

        run.log_solution(solution)

experiment.runsには複数のDataStoreオブジェクトが格納されています。各DataStoreオブジェクトは、特定の実験実行に関連するデータを保持しています。例えば、以下のようにアクセスできます。

experiment.runs
[DataStore(problems={}, instances={}, solutions={'0': Solution(raw=<builtins.Solution object at 0x13bf79dd0>, annotations={})}, objects={}, parameters={'timelimit': 0.1}, samplesets={}, meta_data={'run_id': 0, 'elapsed_time': 0.111704}),
 DataStore(problems={}, instances={}, solutions={'0': Solution(raw=<builtins.Solution object at 0x13bf79710>, annotations={})}, objects={}, parameters={'timelimit': 0.5}, samplesets={}, meta_data={'run_id': 1, 'elapsed_time': 0.408131}),
 DataStore(problems={}, instances={}, solutions={'0': Solution(raw=<builtins.Solution object at 0x13bf79230>, annotations={})}, objects={}, parameters={'timelimit': 1}, samplesets={}, meta_data={'run_id': 2, 'elapsed_time': 0.507786}),
 DataStore(problems={}, instances={}, solutions={'0': Solution(raw=<builtins.Solution object at 0x13bf791d0>, annotations={})}, objects={}, parameters={'timelimit': 2}, samplesets={}, meta_data={'run_id': 3, 'elapsed_time': 1.007484})]

DataStoreオブジェクトは

@dataclass
class DataStore:
    problems: dict[str, jm.Problem]
    instances: dict[str, ommx.v1.Instance]
    solutions: dict[str, ommx.v1.Solution]
    objects: dict[str, dict]
    parameters: dict[str, int | float | str]
    metadata: dict[str, Any]

のように定義されていて、run.log_*メソッドで保存されたデータはそれぞれ対応する属性に格納されます。例えば、run.log_problem("my_problem", problem)で保存された問題はDataStore.problems["my_problem"]でアクセスできます。

Two spaces Data storage#

MINTOのデータ保存は2つのspaceで構成されています。1つ目はExperiment spaceで、2つ目は各runspaceです。

runspaceのデータの保存は上記で見てきました。.runsでアクセスできるDataStoreのリストに格納されています。

experiment.dataspace.experiment_datastore
DataStore(problems={}, instances={'reblock115': Instance(raw=<builtins.Instance object at 0x13bf80030>, annotations={'org.ommx.v1.instance.variables': '1150', 'org.ommx.miplib.url': 'https://miplib.zib.de/instance_details_reblock115.html', 'org.ommx.v1.instance.dataset': 'MIPLIB2017', 'org.ommx.miplib.integers': '0', 'org.ommx.v1.instance.license': 'CC-BY-SA-4.0', 'org.ommx.v1.instance.title': 'reblock115', 'org.ommx.miplib.group': 'reblock', 'org.ommx.miplib.status': 'easy', 'org.ommx.miplib.objective': '-36800603.2332', 'org.ommx.v1.instance.created': '2024-11-11T20:38:59.246723+09:00', 'org.ommx.miplib.non_zero': '13724', 'org.ommx.miplib.tags': 'benchmark,binary,benchmark_suitable,precedence,knapsack', 'org.ommx.miplib.continuous': '0', 'org.ommx.v1.instance.constraints': '4735', 'org.ommx.miplib.binaries': '1150', 'org.ommx.v1.instance.authors': 'Andreas Bley'})}, solutions={}, objects={'environment_info': {'os_name': 'Darwin', 'os_version': '24.6.0', 'platform_info': 'macOS-15.6.1-arm64-arm-64bit', 'cpu_info': 'Apple M2', 'cpu_count': 8, 'memory_total': 25769803776, 'architecture': 'arm64', 'python_version': '3.11.11 (main, Jan 14 2025, 23:36:41) [Clang 19.1.6 ]', 'python_executable': '/Users/yuyamashiro/workspace/minto/.venv/bin/python', 'virtual_env': '/Users/yuyamashiro/workspace/minto/.venv', 'package_versions': {'minto': 'unknown', 'jijmodeling': '1.13.1', 'ommx': '2.0.5', 'numpy': '1.24.4', 'pandas': '2.1.0', 'scipy': '1.15.3', 'openjij': '0.11.2', 'pyscipopt': '5.5.0', 'matplotlib': '3.10.5', 'seaborn': '0.13.2'}, 'timestamp': '2025-10-22T06:08:52.091341'}}, parameters={'python_version': '3.11.11 (main, Jan 14 2025, 23:36:41) [Clang 19.1.6 ]', 'os_name': 'Darwin', 'platform_info': 'macOS-15.6.1-arm64-arm-64bit'}, samplesets={}, meta_data={'version': '1.0', 'experiment_name': 'quickstart_example', 'timestamp': '2025-10-22-06-08-52', 'environment_info': {'os_name': 'Darwin', 'os_version': '24.6.0', 'platform_info': 'macOS-15.6.1-arm64-arm-64bit', 'cpu_info': 'Apple M2', 'cpu_count': 8, 'memory_total': 25769803776, 'architecture': 'arm64', 'python_version': '3.11.11 (main, Jan 14 2025, 23:36:41) [Clang 19.1.6 ]', 'python_executable': '/Users/yuyamashiro/workspace/minto/.venv/bin/python', 'virtual_env': '/Users/yuyamashiro/workspace/minto/.venv', 'package_versions': {'minto': 'unknown', 'jijmodeling': '1.13.1', 'ommx': '2.0.5', 'numpy': '1.24.4', 'pandas': '2.1.0', 'scipy': '1.15.3', 'openjij': '0.11.2', 'pyscipopt': '5.5.0', 'matplotlib': '3.10.5', 'seaborn': '0.13.2'}, 'timestamp': '2025-10-22T06:08:52.091341'}})

数理最適化ではインスタンスやモデルを固定してソルバーのパラメータを変更しながら行ったり、モデルに含まれるパラメータを変更してsweepするなどの実験を行います。 そのときに実験中に固定となる数理モデルやインスタンスは固定したいことが多いです。またインスタンスは非常に大きなデータになるため、各runに同じインスタンスデータを保存するのは非効率です。 そのため、MINTOではExperimentレベルで固定データを保存する仕組みを提供しています。Experimentレベルのデータはexperiment.dataspace.experiment_datastoreでアクセスできます。

Experimentレベルへのデータの保存はexperiment.log_global_*メソッドで行います。例えば、数理モデルやインスタンスを保存する場合は以下のようにします。

experiment.log_global_instance(instance_name, instance)
experiment.dataspace.experiment_datastore.instances['reblock115']
Instance(raw=<builtins.Instance object at 0x13bf80030>, annotations={'org.ommx.v1.instance.variables': '1150', 'org.ommx.miplib.url': 'https://miplib.zib.de/instance_details_reblock115.html', 'org.ommx.v1.instance.dataset': 'MIPLIB2017', 'org.ommx.miplib.integers': '0', 'org.ommx.v1.instance.license': 'CC-BY-SA-4.0', 'org.ommx.v1.instance.title': 'reblock115', 'org.ommx.miplib.group': 'reblock', 'org.ommx.miplib.status': 'easy', 'org.ommx.miplib.objective': '-36800603.2332', 'org.ommx.v1.instance.created': '2024-11-11T20:38:59.246723+09:00', 'org.ommx.miplib.non_zero': '13724', 'org.ommx.miplib.tags': 'benchmark,binary,benchmark_suitable,precedence,knapsack', 'org.ommx.miplib.continuous': '0', 'org.ommx.v1.instance.constraints': '4735', 'org.ommx.miplib.binaries': '1150', 'org.ommx.v1.instance.authors': 'Andreas Bley'})

またExperimentレベルのDataStoreもDataFrameで取得することができます。しかしExperimentレベルの場合はDataStoreのattributeごとにdataframeが生成されるため.get_experimenta_tables()の返り値はdict[str, pandas.DataFrame]であることに注意してください。 例えば以下のように使用します。

experiment.get_experiment_tables()['instance']
num_vars num_binary num_integer num_continuous num_cons title
reblock115 1150 1150 0 0 4735 reblock115

まとめ#

mintoでは2つのspaceを用いてデータを効率的に管理する仕組みを提供しています。 このセクションまで把握すればmintoのコアを理解したと言って良いです。
逆に言えばmintoはこの2つのspaceにデータを保存する以上の複雑なことはしておらず、シンプルな管理機能を提供することで数理最適化におけるデータ管理を容易にすることを目指しています。

このあとのチュートリアルは2つのspaceを操作したり、mintoで管理したデータを他の人と共有したりなどさらに使いやすくするためのutilsを紹介していきます。