|
74 | 74 | ) |
75 | 75 | from ax.utils.testing.mock import mock_botorch_optimize |
76 | 76 | from pandas.testing import assert_frame_equal |
77 | | -from pyre_extensions import assert_is_instance |
| 77 | +from pyre_extensions import assert_is_instance, none_throws |
78 | 78 |
|
79 | 79 | DUMMY_RUN_METADATA_KEY_1 = "test_run_metadata_key_1" |
80 | 80 | DUMMY_RUN_METADATA_KEY_2 = "test_run_metadata_key_2" |
@@ -365,7 +365,7 @@ def test_StatusQuoSetter(self) -> None: |
365 | 365 | sq_parameters["w"] = 3.5 |
366 | 366 | self.experiment.status_quo = Arm(sq_parameters) |
367 | 367 | self.assertEqual(self.experiment.status_quo.parameters["w"], 3.5) |
368 | | - self.assertEqual(self.experiment.status_quo.name, "status_quo_e0") |
| 368 | + self.assertEqual(none_throws(self.experiment.status_quo).name, "status_quo_e0") |
369 | 369 |
|
370 | 370 | # Verify all None values |
371 | 371 | self.experiment.status_quo = Arm({n: None for n in sq_parameters.keys()}) |
@@ -1534,6 +1534,107 @@ def test_to_df(self) -> None: |
1534 | 1534 | ) |
1535 | 1535 | self.assertTrue(df_completed.equals(expected_completed_df)) |
1536 | 1536 |
|
| 1537 | + def test_to_df_with_relativize(self) -> None: |
| 1538 | + """Test the relativize flag in to_df method with status quo.""" |
| 1539 | + # Create an experiment with status quo and completed trials |
| 1540 | + experiment = get_branin_experiment(with_status_quo=True) |
| 1541 | + |
| 1542 | + # Create two completed trials |
| 1543 | + for _ in range(2): |
| 1544 | + sobol_run = get_sobol(search_space=experiment.search_space).gen(n=1) |
| 1545 | + trial = experiment.new_trial(generator_run=sobol_run) |
| 1546 | + trial.mark_running(no_runner_required=True) |
| 1547 | + trial.mark_completed() |
| 1548 | + |
| 1549 | + # Fetch and add status quo data |
| 1550 | + experiment.fetch_data() |
| 1551 | + sq_data = Data( |
| 1552 | + df=pd.DataFrame( |
| 1553 | + [ |
| 1554 | + { |
| 1555 | + "trial_index": i, |
| 1556 | + "arm_name": "status_quo", |
| 1557 | + "metric_name": "branin", |
| 1558 | + "metric_signature": "branin", |
| 1559 | + "mean": 10.0, |
| 1560 | + "sem": 0.1, |
| 1561 | + } |
| 1562 | + for i in range(2) |
| 1563 | + ] |
| 1564 | + ) |
| 1565 | + ) |
| 1566 | + experiment.attach_data(sq_data) |
| 1567 | + |
| 1568 | + # Test without relativization |
| 1569 | + df_no_rel = experiment.to_df(relativize=False) |
| 1570 | + |
| 1571 | + # Test with relativization |
| 1572 | + df_with_rel = experiment.to_df(relativize=True) |
| 1573 | + |
| 1574 | + # Basic structure should be the same |
| 1575 | + self.assertEqual(len(df_with_rel), len(df_no_rel)) |
| 1576 | + self.assertEqual(set(df_with_rel.columns), set(df_no_rel.columns)) |
| 1577 | + |
| 1578 | + # Find metric columns and verify relativization occurred |
| 1579 | + metric_cols = [ |
| 1580 | + col |
| 1581 | + for col in df_no_rel.columns |
| 1582 | + if col |
| 1583 | + not in ["trial_index", "arm_name", "trial_status", "name", "x1", "x2"] |
| 1584 | + ] |
| 1585 | + |
| 1586 | + if metric_cols: |
| 1587 | + metric_name = metric_cols[0] |
| 1588 | + orig_values = df_no_rel[metric_name].dropna() |
| 1589 | + rel_values = df_with_rel[metric_name].dropna() |
| 1590 | + |
| 1591 | + # Values should change for non-status-quo trials |
| 1592 | + non_sq_changed = any( |
| 1593 | + abs(o - r) > 1e-10 for o, r in zip(orig_values, rel_values) if o != 10.0 |
| 1594 | + ) |
| 1595 | + self.assertTrue(non_sq_changed, "Relativization should change some values") |
| 1596 | + |
| 1597 | + def test_to_df_relativize_without_status_quo(self) -> None: |
| 1598 | + """Test that relativize=True has no effect when there's no status quo.""" |
| 1599 | + # Create experiment without status quo |
| 1600 | + experiment = Experiment( |
| 1601 | + name="test_no_sq", |
| 1602 | + search_space=get_search_space(), |
| 1603 | + optimization_config=get_optimization_config(), |
| 1604 | + # No status_quo parameter |
| 1605 | + ) |
| 1606 | + |
| 1607 | + # Add some trials with data |
| 1608 | + trial1 = experiment.new_trial() |
| 1609 | + trial1.add_arm(Arm({"w": 1.0, "x": 2, "y": "foo", "z": True})) |
| 1610 | + trial1.mark_running(no_runner_required=True) |
| 1611 | + |
| 1612 | + # Attach some data |
| 1613 | + data = Data( |
| 1614 | + df=pd.DataFrame( |
| 1615 | + [ |
| 1616 | + { |
| 1617 | + "trial_index": 0, |
| 1618 | + "arm_name": trial1.arm.name if trial1.arm else "unknown", |
| 1619 | + "metric_name": "m1", |
| 1620 | + "metric_signature": "m1", |
| 1621 | + "mean": 10.0, |
| 1622 | + "sem": 1.0, |
| 1623 | + } |
| 1624 | + ] |
| 1625 | + ) |
| 1626 | + ) |
| 1627 | + experiment.attach_data(data) |
| 1628 | + |
| 1629 | + # Both relativize=True and relativize=False should return the same result |
| 1630 | + df_no_relativize = experiment.to_df(relativize=False) |
| 1631 | + # Since there's no status quo, relativize=True should work but have no effect |
| 1632 | + # We need to pass relativize_func even though it won't be used |
| 1633 | + df_with_relativize = experiment.to_df(relativize=True) |
| 1634 | + |
| 1635 | + # DataFrames should be identical when no status quo exists |
| 1636 | + pd.testing.assert_frame_equal(df_no_relativize, df_with_relativize) |
| 1637 | + |
1537 | 1638 |
|
1538 | 1639 | class ExperimentWithMapDataTest(TestCase): |
1539 | 1640 | def setUp(self) -> None: |
|
0 commit comments