{"id":109546,"date":"2026-08-06T20:26:05","date_gmt":"2026-08-06T20:26:05","guid":{"rendered":"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/"},"modified":"2026-08-06T20:26:05","modified_gmt":"2026-08-06T20:26:05","slug":"adaptive-experimentation-with-metas-ax-a-practical-coding-guide","status":"publish","type":"post","link":"https:\/\/youzum.net\/th\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/","title":{"rendered":"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide"},"content":{"rendered":"<p class=\"wp-block-paragraph\">In this tutorial, we explore adaptive experimentation using<a href=\"https:\/\/github.com\/facebook\/Ax\"> <strong>Meta\u2019s Ax<\/strong><\/a><strong> <\/strong>with the modern Client API. We work through a complete workflow where we tune a RandomForest model on a synthetic classification dataset while balancing predictive accuracy against model footprint. We begin by defining a mixed search space with integer, float, log-scaled, and categorical parameters, then use Ax\u2019s ask-tell optimization loop to run constrained Bayesian optimization, multi-objective optimization, and parameter-constrained experimentation. Along the way, we visualize convergence, inspect the Pareto frontier, use Ax\u2019s built-in analysis tools, and persist the experiment for future reuse.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\"no-line-numbers\"><code class=\"no-wrap language-php\">import importlib, subprocess, sys\ndef _ensure(module, pip_name=None):\n   try:\n       importlib.import_module(module)\n   except ImportError:\n       print(f\"Installing {pip_name or module} ...\")\n       subprocess.check_call([sys.executable, \"-m\", \"pip\", \"install\", \"-q\", pip_name or module])\n_ensure(\"ax\", \"ax-platform\")\n_ensure(\"sklearn\", \"scikit-learn\")\nimport logging, warnings, time\nimport numpy as np\nimport matplotlib.pyplot as plt\nwarnings.filterwarnings(\"ignore\")\nlogging.getLogger(\"ax\").setLevel(logging.WARNING)\nfrom ax.api.client import Client\nfrom ax.api.configs import RangeParameterConfig, ChoiceParameterConfig\nfrom sklearn.datasets import make_classification\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.model_selection import StratifiedKFold, cross_val_score\nnp.random.seed(0)\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p class=\"wp-block-paragraph\">We begin by preparing the Colab environment and installing the required packages for Ax and scikit-learn. We import the core libraries for optimization, machine learning, plotting, logging, and reproducibility. We also configure warnings and Ax logging to keep the notebook output clean and focused on the experimental results.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\"no-line-numbers\"><code class=\"no-wrap language-php\">X, y = make_classification(\n   n_samples=1400, n_features=20, n_informative=8, n_redundant=4,\n   n_classes=3, random_state=0,\n)\nCV = StratifiedKFold(n_splits=3, shuffle=True, random_state=0)\ndef evaluate(p):\n   n_est, depth = int(p[\"n_estimators\"]), int(p[\"max_depth\"])\n   clf = RandomForestClassifier(\n       n_estimators=n_est,\n       max_depth=depth,\n       max_features=float(p[\"max_features\"]),\n       min_samples_leaf=int(p[\"min_samples_leaf\"]),\n       criterion=p[\"criterion\"],\n       ccp_alpha=float(p[\"ccp_alpha\"]),\n       n_jobs=-1,\n       random_state=0,\n   )\n   accuracy = cross_val_score(clf, X, y, cv=CV, scoring=\"accuracy\").mean()\n   model_size = n_est * depth\n   return {\"accuracy\": float(accuracy), \"model_size\": float(model_size)}\nSEARCH_SPACE = [\n   RangeParameterConfig(name=\"n_estimators\",    bounds=(50, 300),     parameter_type=\"int\"),\n   RangeParameterConfig(name=\"max_depth\",       bounds=(3, 24),       parameter_type=\"int\"),\n   RangeParameterConfig(name=\"max_features\",    bounds=(0.2, 1.0),    parameter_type=\"float\"),\n   RangeParameterConfig(name=\"min_samples_leaf\",bounds=(1, 12),       parameter_type=\"int\"),\n   RangeParameterConfig(name=\"ccp_alpha\",       bounds=(1e-5, 1e-1),  parameter_type=\"float\", scaling=\"log\"),\n   ChoiceParameterConfig(name=\"criterion\", values=[\"gini\", \"entropy\", \"log_loss\"],\n                         parameter_type=\"str\", is_ordered=False),\n]\ndef run_study(client, total_trials, metric_keys, batch=4):\n   records = []\n   while len(records) &lt; total_trials:\n       trials = client.get_next_trials(max_trials=min(batch, total_trials - len(records)))\n       if not trials:\n           break\n       for idx, params in trials.items():\n           full = evaluate(params)\n           raw = {k: full[k] for k in metric_keys}\n           client.complete_trial(trial_index=idx, raw_data=raw)\n           records.append({\"trial\": idx, \"params\": params, **full})\n   return records\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p class=\"wp-block-paragraph\">We create a synthetic multi-class classification dataset and define a cross-validation strategy to evaluate Random Forest models. We build an evaluation function that returns both accuracy and model size, allowing us to measure performance and cost together. We then define a mixed search space with integer, float, log-scaled, and categorical parameters, along with a reusable ask-tell study runner.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\"no-line-numbers\"><code class=\"no-wrap language-php\">print(\"n=== Study 1: constrained single-objective Bayesian optimization ===\")\nc1 = Client()\nc1.configure_experiment(parameters=SEARCH_SPACE, name=\"rf_constrained\")\nc1.configure_optimization(objective=\"accuracy\",\n                         outcome_constraints=[\"model_size &lt;= 2500\"])\nrec1 = run_study(c1, total_trials=24, metric_keys=[\"accuracy\", \"model_size\"])\nbest_params, prediction, best_idx, best_arm = c1.get_best_parameterization()\nprint(\"nBest feasible configuration found:\")\nfor k, v in best_params.items():\n   print(f\"   {k:&gt;16}: {v}\")\nprint(\"   predicted:\", prediction)\nfeasible = [(r[\"trial\"], r[\"accuracy\"]) for r in rec1 if r[\"model_size\"] &lt;= 2500]\nbest_so_far, cur = [], -np.inf\nfor _, acc in feasible:\n   cur = max(cur, acc); best_so_far.append(cur)\nplt.figure(figsize=(7, 4))\nplt.plot(range(1, len(best_so_far) + 1), best_so_far, \"o-\")\nplt.xlabel(\"feasible trial #\"); plt.ylabel(\"best accuracy so far\")\nplt.title(\"Study 1 \u2014 convergence (subject to model_size &lt;= 2500)\")\nplt.grid(alpha=0.3); plt.tight_layout(); plt.show()\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p class=\"wp-block-paragraph\">We run a constrained single-objective Bayesian optimization study where we maximize accuracy while keeping model size below a fixed threshold. We use Ax to suggest hyperparameter configurations, evaluate them, and report both accuracy and model size back to the optimizer. We then extract the best feasible configuration and plot the best accuracy achieved over feasible trials.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\"no-line-numbers\"><code class=\"no-wrap language-php\">print(\"n=== Study 2: multi-objective (accuracy vs. model_size) ===\")\nc2 = Client()\nc2.configure_experiment(parameters=SEARCH_SPACE, name=\"rf_multiobjective\")\nc2.configure_optimization(objective=\"accuracy, -model_size\")\nrec2 = run_study(c2, total_trials=28, metric_keys=[\"accuracy\", \"model_size\"])\ntry:\n   frontier = c2.get_pareto_frontier()\n   print(f\"Ax identified {len(frontier)} Pareto-optimal configurations.\")\nexcept Exception as e:\n   frontier = None\n   print(\"get_pareto_frontier unavailable in this version:\", e)\nacc = np.array([r[\"accuracy\"] for r in rec2])\nsize = np.array([r[\"model_size\"] for r in rec2])\norder = np.argsort(size)\npareto_idx, best_acc = [], -np.inf\nfor i in order:\n   if acc[i] &gt; best_acc:\n       best_acc = acc[i]; pareto_idx.append(i)\nplt.figure(figsize=(7, 5))\nplt.scatter(size, acc, c=\"lightgray\", label=\"all trials\")\nplt.scatter(size[pareto_idx], acc[pareto_idx], c=\"crimson\", zorder=3, label=\"Pareto front\")\nplt.plot(size[pareto_idx], acc[pareto_idx], \"--\", c=\"crimson\", alpha=0.6)\nplt.xlabel(\"model_size (lower = cheaper)\"); plt.ylabel(\"accuracy (higher = better)\")\nplt.title(\"Study 2 \u2014 accuracy vs. model size trade-off\")\nplt.legend(); plt.grid(alpha=0.3); plt.tight_layout(); plt.show()\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p class=\"wp-block-paragraph\">We move from single-objective optimization to multi-objective optimization by jointly maximizing accuracy and minimizing model size. We use Ax to search for configurations that represent strong trade-offs between predictive performance and computational footprint. We then calculate and visualize the empirical Pareto frontier to understand how accuracy varies with model size.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\"no-line-numbers\"><code class=\"no-wrap language-php\">print(\"n=== Study 3: parameter constraints on a synthetic surface ===\")\nc3 = Client()\nc3.configure_experiment(\n   parameters=[\n       RangeParameterConfig(name=\"x1\", bounds=(0.0, 1.0), parameter_type=\"float\"),\n       RangeParameterConfig(name=\"x2\", bounds=(0.0, 1.0), parameter_type=\"float\"),\n   ],\n   parameter_constraints=[\"x1 + x2 &lt;= 1.5\"],\n   name=\"constrained_surface\",\n)\nc3.configure_optimization(objective=\"-dist\")\nfor _ in range(14):\n   for idx, p in c3.get_next_trials(max_trials=1).items():\n       dist = (p[\"x1\"] - 0.9) ** 2 + (p[\"x2\"] - 0.9) ** 2\n       c3.complete_trial(trial_index=idx, raw_data={\"dist\": float(dist)})\nbp, _, _, _ = c3.get_best_parameterization()\nprint(f\"Best point: x1={bp['x1']:.3f}, x2={bp['x2']:.3f}, \"\n     f\"sum={bp['x1'] + bp['x2']:.3f} (constraint: &lt;= 1.5)\")\nprint(\"Unconstrained optimum would be (0.9, 0.9); Ax respects the boundary.\")\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p class=\"wp-block-paragraph\">We demonstrate parameter constraints using a simple two-dimensional synthetic optimization problem. We ask Ax to minimize the distance to a target point while enforcing the input constraint that the sum of the two variables remains below a boundary. We observe that the optimizer respects the constraint and finds the best feasible point near the constrained optimum.<\/p>\n<div class=\"dm-code-snippet dark dm-normal-version default no-background-mobile\">\n<div class=\"control-language\">\n<div class=\"dm-buttons\">\n<div class=\"dm-buttons-left\">\n<div class=\"dm-button-snippet red-button\"><\/div>\n<div class=\"dm-button-snippet orange-button\"><\/div>\n<div class=\"dm-button-snippet green-button\"><\/div>\n<\/div>\n<div class=\"dm-buttons-right\"><a><span class=\"dm-copy-text\">Copy Code<\/span><span class=\"dm-copy-confirmed\">Copied<\/span><span class=\"dm-error-message\">Use a different Browser<\/span><\/a><\/div>\n<\/div>\n<pre class=\"no-line-numbers\"><code class=\"no-wrap language-php\">print(\"n=== Ax built-in analyses for Study 1 ===\")\ntry:\n   import plotly.io as pio\n   if \"google.colab\" in sys.modules:\n       pio.renderers.default = \"colab\"\n   cards = c1.compute_analyses(display=True)\n   print(f\"Computed {len(cards)} analysis cards.\")\nexcept Exception as e:\n   print(\"Interactive analyses didn't render in this environment:\", e)\n   print(\"(The matplotlib plots above already capture the key results.)\")\nprint(\"n=== Saving \/ loading the experiment ===\")\ntry:\n   c1.save_to_json_file(\"ax_study1.json\")\n   reloaded = Client.load_from_json_file(\"ax_study1.json\")\n   print(\"Saved to ax_study1.json and reloaded successfully.\")\n   rp, _, _, _ = reloaded.get_best_parameterization()\n   print(\"Best params from reloaded client match:\", rp == best_params)\nexcept Exception as e:\n   print(\"JSON persistence API differs in this version:\", e)\n   print(\"See: https:\/\/ax.dev\/docs\/recipes\/experiment-to-json\")\nprint(\"nDone. You optimized a mixed-type search space with constraints, \"\n     \"traced a Pareto frontier, and persisted in the experiment.\")\n<\/code><\/pre>\n<\/div>\n<\/div>\n<p class=\"wp-block-paragraph\">We use Ax\u2019s built-in analysis tools to generate diagnostic cards, such as sensitivity, cross-validation, and other experiment insights, when the environment supports them. We then save the completed experiment to a JSON file and reload it to verify that the optimization state is preserved. We finish by confirming that the tutorial covers constrained optimization, multi-objective trade-offs, analysis, and experiment persistence.<\/p>\n<p class=\"wp-block-paragraph\">In conclusion, we developed a practical understanding of how Ax helps us run efficient and structured hyperparameter optimization experiments. We optimized a mixed-type search space, enforced both outcome and parameter constraints, compared accuracy against model size through multi-objective optimization, and identified trade-offs using an empirical Pareto frontier. We also used Ax\u2019s analysis and persistence features to make the experimentation workflow more interpretable and reproducible.<\/p>\n<p class=\"wp-block-paragraph\">\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n<\/p><p class=\"wp-block-paragraph\">\n<\/p><p class=\"wp-block-paragraph\">Check out the<strong>\u00a0<a href=\"https:\/\/github.com\/MARKTECHPOST-AI-MEDIA-INC\/AI-Agents-Projects-Tutorials\/blob\/main\/ML%20Project%20Codes\/adaptive_experimentation_with_meta_ax_constrained_multiobjective_optimization_Marktechpost.ipynb\" target=\"_blank\" rel=\"noreferrer noopener\">Full Codes here<\/a>.\u00a0<\/strong>Also,\u00a0feel free to follow us on\u00a0<strong><a href=\"https:\/\/x.com\/intent\/follow?screen_name=marktechpost\" target=\"_blank\" rel=\"noreferrer noopener\"><mark>Twitter<\/mark><\/a><\/strong>\u00a0and don\u2019t forget to join our\u00a0<strong><a href=\"https:\/\/www.reddit.com\/r\/machinelearningnews\/\" target=\"_blank\" rel=\"noreferrer noopener\">150k+ML SubReddit<\/a><\/strong>\u00a0and Subscribe to\u00a0<strong><a href=\"https:\/\/www.aidevsignals.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">our Newsletter<\/a><\/strong>. Wait! are you on telegram?\u00a0<strong><a href=\"https:\/\/t.me\/machinelearningresearchnews\" target=\"_blank\" rel=\"noreferrer noopener\">now you can join us on telegram as well.<\/a><\/strong><\/p>\n<p class=\"wp-block-paragraph\">Need to partner with us for promoting your GitHub Repo OR Hugging Face Page OR Product Release OR Webinar etc.?\u00a0<strong><a href=\"https:\/\/forms.gle\/wbash1wF6efRj8G58\" target=\"_blank\" rel=\"noreferrer noopener\"><mark>Connect with us<\/mark><\/a><\/strong><\/p>\n<p>The post <a href=\"https:\/\/www.marktechpost.com\/2026\/08\/06\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/\">Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide<\/a> appeared first on <a href=\"https:\/\/www.marktechpost.com\/\">MarkTechPost<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>In this tutorial, we explore adaptive experimentation using Meta\u2019s Ax with the modern Client API. We work through a complete workflow where we tune a RandomForest model on a synthetic classification dataset while balancing predictive accuracy against model footprint. We begin by defining a mixed search space with integer, float, log-scaled, and categorical parameters, then use Ax\u2019s ask-tell optimization loop to run constrained Bayesian optimization, multi-objective optimization, and parameter-constrained experimentation. Along the way, we visualize convergence, inspect the Pareto frontier, use Ax\u2019s built-in analysis tools, and persist the experiment for future reuse. Copy CodeCopiedUse a different Browser import importlib, subprocess, sys def _ensure(module, pip_name=None): try: importlib.import_module(module) except ImportError: print(f&#8221;Installing {pip_name or module} &#8230;&#8221;) subprocess.check_call([sys.executable, &#8220;-m&#8221;, &#8220;pip&#8221;, &#8220;install&#8221;, &#8220;-q&#8221;, pip_name or module]) _ensure(&#8220;ax&#8221;, &#8220;ax-platform&#8221;) _ensure(&#8220;sklearn&#8221;, &#8220;scikit-learn&#8221;) import logging, warnings, time import numpy as np import matplotlib.pyplot as plt warnings.filterwarnings(&#8220;ignore&#8221;) logging.getLogger(&#8220;ax&#8221;).setLevel(logging.WARNING) from ax.api.client import Client from ax.api.configs import RangeParameterConfig, ChoiceParameterConfig from sklearn.datasets import make_classification from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import StratifiedKFold, cross_val_score np.random.seed(0) We begin by preparing the Colab environment and installing the required packages for Ax and scikit-learn. We import the core libraries for optimization, machine learning, plotting, logging, and reproducibility. We also configure warnings and Ax logging to keep the notebook output clean and focused on the experimental results. Copy CodeCopiedUse a different Browser X, y = make_classification( n_samples=1400, n_features=20, n_informative=8, n_redundant=4, n_classes=3, random_state=0, ) CV = StratifiedKFold(n_splits=3, shuffle=True, random_state=0) def evaluate(p): n_est, depth = int(p[&#8220;n_estimators&#8221;]), int(p[&#8220;max_depth&#8221;]) clf = RandomForestClassifier( n_estimators=n_est, max_depth=depth, max_features=float(p[&#8220;max_features&#8221;]), min_samples_leaf=int(p[&#8220;min_samples_leaf&#8221;]), criterion=p[&#8220;criterion&#8221;], ccp_alpha=float(p[&#8220;ccp_alpha&#8221;]), n_jobs=-1, random_state=0, ) accuracy = cross_val_score(clf, X, y, cv=CV, scoring=&#8221;accuracy&#8221;).mean() model_size = n_est * depth return {&#8220;accuracy&#8221;: float(accuracy), &#8220;model_size&#8221;: float(model_size)} SEARCH_SPACE = [ RangeParameterConfig(name=&#8221;n_estimators&#8221;, bounds=(50, 300), parameter_type=&#8221;int&#8221;), RangeParameterConfig(name=&#8221;max_depth&#8221;, bounds=(3, 24), parameter_type=&#8221;int&#8221;), RangeParameterConfig(name=&#8221;max_features&#8221;, bounds=(0.2, 1.0), parameter_type=&#8221;float&#8221;), RangeParameterConfig(name=&#8221;min_samples_leaf&#8221;,bounds=(1, 12), parameter_type=&#8221;int&#8221;), RangeParameterConfig(name=&#8221;ccp_alpha&#8221;, bounds=(1e-5, 1e-1), parameter_type=&#8221;float&#8221;, scaling=&#8221;log&#8221;), ChoiceParameterConfig(name=&#8221;criterion&#8221;, values=[&#8220;gini&#8221;, &#8220;entropy&#8221;, &#8220;log_loss&#8221;], parameter_type=&#8221;str&#8221;, is_ordered=False), ] def run_study(client, total_trials, metric_keys, batch=4): records = [] while len(records) &lt; total_trials: trials = client.get_next_trials(max_trials=min(batch, total_trials &#8211; len(records))) if not trials: break for idx, params in trials.items(): full = evaluate(params) raw = {k: full[k] for k in metric_keys} client.complete_trial(trial_index=idx, raw_data=raw) records.append({&#8220;trial&#8221;: idx, &#8220;params&#8221;: params, **full}) return records We create a synthetic multi-class classification dataset and define a cross-validation strategy to evaluate Random Forest models. We build an evaluation function that returns both accuracy and model size, allowing us to measure performance and cost together. We then define a mixed search space with integer, float, log-scaled, and categorical parameters, along with a reusable ask-tell study runner. Copy CodeCopiedUse a different Browser print(&#8220;n=== Study 1: constrained single-objective Bayesian optimization ===&#8221;) c1 = Client() c1.configure_experiment(parameters=SEARCH_SPACE, name=&#8221;rf_constrained&#8221;) c1.configure_optimization(objective=&#8221;accuracy&#8221;, outcome_constraints=[&#8220;model_size &lt;= 2500&#8221;]) rec1 = run_study(c1, total_trials=24, metric_keys=[&#8220;accuracy&#8221;, &#8220;model_size&#8221;]) best_params, prediction, best_idx, best_arm = c1.get_best_parameterization() print(&#8220;nBest feasible configuration found:&#8221;) for k, v in best_params.items(): print(f&#8221; {k:&gt;16}: {v}&#8221;) print(&#8221; predicted:&#8221;, prediction) feasible = [(r[&#8220;trial&#8221;], r[&#8220;accuracy&#8221;]) for r in rec1 if r[&#8220;model_size&#8221;] &lt;= 2500] best_so_far, cur = [], -np.inf for _, acc in feasible: cur = max(cur, acc); best_so_far.append(cur) plt.figure(figsize=(7, 4)) plt.plot(range(1, len(best_so_far) + 1), best_so_far, &#8220;o-&#8220;) plt.xlabel(&#8220;feasible trial #&#8221;); plt.ylabel(&#8220;best accuracy so far&#8221;) plt.title(&#8220;Study 1 \u2014 convergence (subject to model_size &lt;= 2500)&#8221;) plt.grid(alpha=0.3); plt.tight_layout(); plt.show() We run a constrained single-objective Bayesian optimization study where we maximize accuracy while keeping model size below a fixed threshold. We use Ax to suggest hyperparameter configurations, evaluate them, and report both accuracy and model size back to the optimizer. We then extract the best feasible configuration and plot the best accuracy achieved over feasible trials. Copy CodeCopiedUse a different Browser print(&#8220;n=== Study 2: multi-objective (accuracy vs. model_size) ===&#8221;) c2 = Client() c2.configure_experiment(parameters=SEARCH_SPACE, name=&#8221;rf_multiobjective&#8221;) c2.configure_optimization(objective=&#8221;accuracy, -model_size&#8221;) rec2 = run_study(c2, total_trials=28, metric_keys=[&#8220;accuracy&#8221;, &#8220;model_size&#8221;]) try: frontier = c2.get_pareto_frontier() print(f&#8221;Ax identified {len(frontier)} Pareto-optimal configurations.&#8221;) except Exception as e: frontier = None print(&#8220;get_pareto_frontier unavailable in this version:&#8221;, e) acc = np.array([r[&#8220;accuracy&#8221;] for r in rec2]) size = np.array([r[&#8220;model_size&#8221;] for r in rec2]) order = np.argsort(size) pareto_idx, best_acc = [], -np.inf for i in order: if acc[i] &gt; best_acc: best_acc = acc[i]; pareto_idx.append(i) plt.figure(figsize=(7, 5)) plt.scatter(size, acc, c=&#8221;lightgray&#8221;, label=&#8221;all trials&#8221;) plt.scatter(size[pareto_idx], acc[pareto_idx], c=&#8221;crimson&#8221;, zorder=3, label=&#8221;Pareto front&#8221;) plt.plot(size[pareto_idx], acc[pareto_idx], &#8220;&#8211;&#8220;, c=&#8221;crimson&#8221;, alpha=0.6) plt.xlabel(&#8220;model_size (lower = cheaper)&#8221;); plt.ylabel(&#8220;accuracy (higher = better)&#8221;) plt.title(&#8220;Study 2 \u2014 accuracy vs. model size trade-off&#8221;) plt.legend(); plt.grid(alpha=0.3); plt.tight_layout(); plt.show() We move from single-objective optimization to multi-objective optimization by jointly maximizing accuracy and minimizing model size. We use Ax to search for configurations that represent strong trade-offs between predictive performance and computational footprint. We then calculate and visualize the empirical Pareto frontier to understand how accuracy varies with model size. Copy CodeCopiedUse a different Browser print(&#8220;n=== Study 3: parameter constraints on a synthetic surface ===&#8221;) c3 = Client() c3.configure_experiment( parameters=[ RangeParameterConfig(name=&#8221;x1&#8243;, bounds=(0.0, 1.0), parameter_type=&#8221;float&#8221;), RangeParameterConfig(name=&#8221;x2&#8243;, bounds=(0.0, 1.0), parameter_type=&#8221;float&#8221;), ], parameter_constraints=[&#8220;x1 + x2 &lt;= 1.5&#8243;], name=&#8221;constrained_surface&#8221;, ) c3.configure_optimization(objective=&#8221;-dist&#8221;) for _ in range(14): for idx, p in c3.get_next_trials(max_trials=1).items(): dist = (p[&#8220;x1&#8221;] &#8211; 0.9) ** 2 + (p[&#8220;x2&#8221;] &#8211; 0.9) ** 2 c3.complete_trial(trial_index=idx, raw_data={&#8220;dist&#8221;: float(dist)}) bp, _, _, _ = c3.get_best_parameterization() print(f&#8221;Best point: x1={bp[&#8216;x1&#8217;]:.3f}, x2={bp[&#8216;x2&#8217;]:.3f}, &#8221; f&#8221;sum={bp[&#8216;x1&#8217;] + bp[&#8216;x2&#8217;]:.3f} (constraint: &lt;= 1.5)&#8221;) print(&#8220;Unconstrained optimum would be (0.9, 0.9); Ax respects the boundary.&#8221;) We demonstrate parameter constraints using a simple two-dimensional synthetic optimization problem. We ask Ax to minimize the distance to a target point while enforcing the input constraint that the sum of the two variables remains below a boundary. We observe that the optimizer respects the constraint and finds the best feasible point near the constrained optimum. Copy CodeCopiedUse a different Browser print(&#8220;n=== Ax built-in analyses for Study 1 ===&#8221;) try: import plotly.io as pio if &#8220;google.colab&#8221; in sys.modules: pio.renderers.default = &#8220;colab&#8221; cards = c1.compute_analyses(display=True) print(f&#8221;Computed {len(cards)} analysis cards.&#8221;) except Exception as e: print(&#8220;Interactive analyses didn&#8217;t render in this environment:&#8221;, e) print(&#8220;(The matplotlib plots above already capture the key results.)&#8221;) print(&#8220;n=== Saving \/ loading the experiment ===&#8221;) try: c1.save_to_json_file(&#8220;ax_study1.json&#8221;) reloaded = Client.load_from_json_file(&#8220;ax_study1.json&#8221;) print(&#8220;Saved to ax_study1.json and reloaded successfully.&#8221;) rp, _, _, _ = reloaded.get_best_parameterization() print(&#8220;Best params from reloaded client match:&#8221;, rp == best_params) except Exception as e: print(&#8220;JSON persistence API differs in this version:&#8221;, e) print(&#8220;See: https:\/\/ax.dev\/docs\/recipes\/experiment-to-json&#8221;) print(&#8220;nDone. You optimized a mixed-type search space with constraints, &#8221; &#8220;traced a Pareto frontier, and persisted in the experiment.&#8221;) We use Ax\u2019s built-in<\/p>","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"pmpro_default_level":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"_pvb_checkbox_block_on_post":false,"footnotes":""},"categories":[52,5,7,1],"tags":[],"class_list":["post-109546","post","type-post","status-publish","format-standard","hentry","category-ai-club","category-committee","category-news","category-uncategorized","pmpro-has-access"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide - YouZum<\/title>\n<meta name=\"description\" content=\"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/youzum.net\/th\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/\" \/>\n<meta property=\"og:locale\" content=\"th_TH\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide - YouZum\" \/>\n<meta property=\"og:description\" content=\"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19\" \/>\n<meta property=\"og:url\" content=\"https:\/\/youzum.net\/th\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/\" \/>\n<meta property=\"og:site_name\" content=\"YouZum\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/DroneAssociationTH\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-08-06T20:26:05+00:00\" \/>\n<meta name=\"author\" content=\"admin NU\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin NU\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 \u0e19\u0e32\u0e17\u0e35\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/\"},\"author\":{\"name\":\"admin NU\",\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/person\/97fa48242daf3908e4d9a5f26f4a059c\"},\"headline\":\"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide\",\"datePublished\":\"2026-08-06T20:26:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/\"},\"wordCount\":623,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/yousum.gpucore.co\/#organization\"},\"articleSection\":[\"AI\",\"Committee\",\"News\",\"Uncategorized\"],\"inLanguage\":\"th\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/\",\"url\":\"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/\",\"name\":\"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide - YouZum\",\"isPartOf\":{\"@id\":\"https:\/\/yousum.gpucore.co\/#website\"},\"datePublished\":\"2026-08-06T20:26:05+00:00\",\"description\":\"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19\",\"breadcrumb\":{\"@id\":\"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/#breadcrumb\"},\"inLanguage\":\"th\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/youzum.net\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/yousum.gpucore.co\/#website\",\"url\":\"https:\/\/yousum.gpucore.co\/\",\"name\":\"YouSum\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/yousum.gpucore.co\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/yousum.gpucore.co\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"th\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/yousum.gpucore.co\/#organization\",\"name\":\"Drone Association Thailand\",\"url\":\"https:\/\/yousum.gpucore.co\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"th\",\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/youzum.net\/wp-content\/uploads\/2024\/11\/tranparent-logo.png\",\"contentUrl\":\"https:\/\/youzum.net\/wp-content\/uploads\/2024\/11\/tranparent-logo.png\",\"width\":300,\"height\":300,\"caption\":\"Drone Association Thailand\"},\"image\":{\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/DroneAssociationTH\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/person\/97fa48242daf3908e4d9a5f26f4a059c\",\"name\":\"admin NU\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"th\",\"@id\":\"https:\/\/yousum.gpucore.co\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/youzum.net\/wp-content\/uploads\/avatars\/2\/1746849356-bpfull.png\",\"contentUrl\":\"https:\/\/youzum.net\/wp-content\/uploads\/avatars\/2\/1746849356-bpfull.png\",\"caption\":\"admin NU\"},\"url\":\"https:\/\/youzum.net\/th\/members\/adminnu\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide - YouZum","description":"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/youzum.net\/th\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/","og_locale":"th_TH","og_type":"article","og_title":"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide - YouZum","og_description":"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19","og_url":"https:\/\/youzum.net\/th\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/","og_site_name":"YouZum","article_publisher":"https:\/\/www.facebook.com\/DroneAssociationTH\/","article_published_time":"2026-08-06T20:26:05+00:00","author":"admin NU","twitter_card":"summary_large_image","twitter_misc":{"Written by":"admin NU","Est. reading time":"8 \u0e19\u0e32\u0e17\u0e35"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/#article","isPartOf":{"@id":"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/"},"author":{"name":"admin NU","@id":"https:\/\/yousum.gpucore.co\/#\/schema\/person\/97fa48242daf3908e4d9a5f26f4a059c"},"headline":"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide","datePublished":"2026-08-06T20:26:05+00:00","mainEntityOfPage":{"@id":"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/"},"wordCount":623,"commentCount":0,"publisher":{"@id":"https:\/\/yousum.gpucore.co\/#organization"},"articleSection":["AI","Committee","News","Uncategorized"],"inLanguage":"th","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/","url":"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/","name":"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide - YouZum","isPartOf":{"@id":"https:\/\/yousum.gpucore.co\/#website"},"datePublished":"2026-08-06T20:26:05+00:00","description":"\u0e01\u0e34\u0e08\u0e01\u0e23\u0e23\u0e21\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27\u0e01\u0e31\u0e1a\u0e42\u0e14\u0e23\u0e19","breadcrumb":{"@id":"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/#breadcrumb"},"inLanguage":"th","potentialAction":[{"@type":"ReadAction","target":["https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/youzum.net\/adaptive-experimentation-with-metas-ax-a-practical-coding-guide\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/youzum.net\/"},{"@type":"ListItem","position":2,"name":"Adaptive Experimentation with Meta\u2019s Ax: A Practical Coding Guide"}]},{"@type":"WebSite","@id":"https:\/\/yousum.gpucore.co\/#website","url":"https:\/\/yousum.gpucore.co\/","name":"YouSum","description":"","publisher":{"@id":"https:\/\/yousum.gpucore.co\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/yousum.gpucore.co\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"th"},{"@type":"Organization","@id":"https:\/\/yousum.gpucore.co\/#organization","name":"Drone Association Thailand","url":"https:\/\/yousum.gpucore.co\/","logo":{"@type":"ImageObject","inLanguage":"th","@id":"https:\/\/yousum.gpucore.co\/#\/schema\/logo\/image\/","url":"https:\/\/youzum.net\/wp-content\/uploads\/2024\/11\/tranparent-logo.png","contentUrl":"https:\/\/youzum.net\/wp-content\/uploads\/2024\/11\/tranparent-logo.png","width":300,"height":300,"caption":"Drone Association Thailand"},"image":{"@id":"https:\/\/yousum.gpucore.co\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/DroneAssociationTH\/"]},{"@type":"Person","@id":"https:\/\/yousum.gpucore.co\/#\/schema\/person\/97fa48242daf3908e4d9a5f26f4a059c","name":"admin NU","image":{"@type":"ImageObject","inLanguage":"th","@id":"https:\/\/yousum.gpucore.co\/#\/schema\/person\/image\/","url":"https:\/\/youzum.net\/wp-content\/uploads\/avatars\/2\/1746849356-bpfull.png","contentUrl":"https:\/\/youzum.net\/wp-content\/uploads\/avatars\/2\/1746849356-bpfull.png","caption":"admin NU"},"url":"https:\/\/youzum.net\/th\/members\/adminnu\/"}]}},"rttpg_featured_image_url":null,"rttpg_author":{"display_name":"admin NU","author_link":"https:\/\/youzum.net\/th\/members\/adminnu\/"},"rttpg_comment":0,"rttpg_category":"<a href=\"https:\/\/youzum.net\/th\/category\/ai-club\/\" rel=\"category tag\">AI<\/a> <a href=\"https:\/\/youzum.net\/th\/category\/committee\/\" rel=\"category tag\">Committee<\/a> <a href=\"https:\/\/youzum.net\/th\/category\/news\/\" rel=\"category tag\">News<\/a> <a href=\"https:\/\/youzum.net\/th\/category\/uncategorized\/\" rel=\"category tag\">Uncategorized<\/a>","rttpg_excerpt":"In this tutorial, we explore adaptive experimentation using Meta\u2019s Ax with the modern Client API. We work through a complete workflow where we tune a RandomForest model on a synthetic classification dataset while balancing predictive accuracy against model footprint. We begin by defining a mixed search space with integer, float, log-scaled, and categorical parameters, then&hellip;","_links":{"self":[{"href":"https:\/\/youzum.net\/th\/wp-json\/wp\/v2\/posts\/109546","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/youzum.net\/th\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/youzum.net\/th\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/youzum.net\/th\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/youzum.net\/th\/wp-json\/wp\/v2\/comments?post=109546"}],"version-history":[{"count":0,"href":"https:\/\/youzum.net\/th\/wp-json\/wp\/v2\/posts\/109546\/revisions"}],"wp:attachment":[{"href":"https:\/\/youzum.net\/th\/wp-json\/wp\/v2\/media?parent=109546"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/youzum.net\/th\/wp-json\/wp\/v2\/categories?post=109546"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/youzum.net\/th\/wp-json\/wp\/v2\/tags?post=109546"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}