コード例 #1
0
def test_custom_shrinkage(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    def shrinkage_func(group_sizes):
        n = len(group_sizes)
        return np.repeat(1 / n, n)

    shrink_est = GroupedPredictor(
        DummyRegressor(),
        ["Planet", "Country", "City"],
        shrinkage=shrinkage_func,
        use_global_model=False,
    )

    shrinkage_factors = np.array([1, 1, 1]) / 3

    shrink_est.fit(X, y)

    expected_prediction = [
        np.array([means["Earth"], means["NL"], means["Amsterdam"]]) @ shrinkage_factors,
        np.array([means["Earth"], means["NL"], means["Rotterdam"]]) @ shrinkage_factors,
        np.array([means["Earth"], means["BE"], means["Antwerp"]]) @ shrinkage_factors,
        np.array([means["Earth"], means["BE"], means["Brussels"]]) @ shrinkage_factors,
    ]

    assert expected_prediction == shrink_est.predict(X).tolist()
コード例 #2
0
def test_global_model_shrinkage(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    shrink_est_without_global = GroupedPredictor(
        DummyRegressor(),
        ["Planet", "Country", "City"],
        shrinkage="min_n_obs",
        use_global_model=False,
        min_n_obs=2,
    )

    shrink_est_with_global = GroupedPredictor(
        DummyRegressor(),
        ["Country", "City"],
        shrinkage="min_n_obs",
        use_global_model=True,
        min_n_obs=2,
    )

    shrink_est_without_global.fit(X, y)
    # Drop planet because otherwise it is seen as a value column
    shrink_est_with_global.fit(X.drop(columns="Planet"), y)

    pd.testing.assert_series_equal(
        shrink_est_with_global.predict(X.drop(columns="Planet")),
        shrink_est_without_global.predict(X),
    )
コード例 #3
0
def test_shrinkage_single_group(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    shrink_est = GroupedPredictor(
        DummyRegressor(),
        "Country",
        shrinkage="constant",
        use_global_model=True,
        alpha=0.1,
    )

    shrinkage_factors = np.array([0.1, 0.9])

    # Drop planet and city because otherwise they are seen as value columns
    shrink_est.fit(X[["Country"]], y)

    expected_prediction = [
        np.array([means["Earth"], means["NL"]]) @ shrinkage_factors,
        np.array([means["Earth"], means["NL"]]) @ shrinkage_factors,
        np.array([means["Earth"], means["BE"]]) @ shrinkage_factors,
        np.array([means["Earth"], means["BE"]]) @ shrinkage_factors,
    ]

    assert expected_prediction == shrink_est.predict(X[["Country"]]).tolist()
コード例 #4
0
def test_constant_shrinkage(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    shrink_est = GroupedPredictor(
        DummyRegressor(),
        ["Planet", "Country", "City"],
        shrinkage="constant",
        use_global_model=False,
        alpha=0.1,
    )

    shrinkage_factors = np.array([0.01, 0.09, 0.9])

    shrink_est.fit(X, y)

    expected_prediction = [
        np.array([means["Earth"], means["NL"], means["Amsterdam"]]) @ shrinkage_factors,
        np.array([means["Earth"], means["NL"], means["Rotterdam"]]) @ shrinkage_factors,
        np.array([means["Earth"], means["BE"], means["Antwerp"]]) @ shrinkage_factors,
        np.array([means["Earth"], means["BE"], means["Brussels"]]) @ shrinkage_factors,
    ]

    assert expected_prediction == shrink_est.predict(X).tolist()
コード例 #5
0
def test_relative_shrinkage(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    shrink_est = GroupedPredictor(
        DummyRegressor(),
        ["Planet", "Country", "City"],
        shrinkage="relative",
        use_global_model=False,
    )

    shrinkage_factors = np.array([4, 2, 1]) / 7

    shrink_est.fit(X, y)

    expected_prediction = [
        np.array([means["Earth"], means["NL"], means["Amsterdam"]
                  ]) @ shrinkage_factors,
        np.array([means["Earth"], means["NL"], means["Rotterdam"]
                  ]) @ shrinkage_factors,
        np.array([means["Earth"], means["BE"], means["Antwerp"]
                  ]) @ shrinkage_factors,
        np.array([means["Earth"], means["BE"], means["Brussels"]])
        @ shrinkage_factors,
    ]

    for exp, pred in zip(expected_prediction, shrink_est.predict(X).tolist()):
        assert pytest.approx(exp) == pred
コード例 #6
0
def test_bad_shrinkage_value_error():
    with pytest.raises(ValueError) as e:
        df = load_chicken(as_frame=True)
        mod = GroupedPredictor(
            estimator=LinearRegression(), groups="diet", shrinkage="dinosaurhead"
        )
        mod.fit(df[["time", "diet"]], df["weight"])
        assert "shrinkage function" in str(e)
コード例 #7
0
def test_estimator_checks(test_fn):
    clf = GroupedPredictor(
        estimator=LinearRegression(), groups=0, use_global_model=True
    )
    test_fn(GroupedPredictor.__name__ + "_fallback", clf)

    clf = GroupedPredictor(
        estimator=LinearRegression(), groups=0, use_global_model=False
    )
    test_fn(GroupedPredictor.__name__ + "_nofallback", clf)
コード例 #8
0
def test_chickweigt_string_groups():

    df = load_chicken(as_frame=True)
    df["diet"] = ["omgomgomg" + s for s in df["diet"].astype(str)]

    X = df[["time", "diet"]]
    X_np = np.array(X)

    y = df["weight"]

    # This should NOT raise errors
    GroupedPredictor(LinearRegression(), groups=["diet"]).fit(X, y).predict(X)
    GroupedPredictor(LinearRegression(), groups=1).fit(X_np, y).predict(X_np)
コード例 #9
0
def test_missing_check():
    df = load_chicken(as_frame=True)

    X, y = df.drop(columns='weight'), df['weight']
    # create missing value
    X.loc[0, 'chick'] = np.nan
    model = make_pipeline(SimpleImputer(), LinearRegression())

    # Should not raise error, check is disabled
    m = GroupedPredictor(model, groups=['diet'], check_X=False).fit(X, y)
    m.predict(X)

    # Should raise error, check is still enabled
    with pytest.raises(ValueError) as e:
        GroupedPredictor(model, groups=['diet']).fit(X, y)
        assert "contains NaN" in str(e)
コード例 #10
0
def test_invalid_shrinkage(shrinkage_data, wrong_func):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    with pytest.raises(ValueError) as e:
        shrink_est = GroupedPredictor(
            DummyRegressor(),
            ["Planet", "Country", "City"],
            shrinkage=wrong_func,
            use_global_model=False,
        )

        shrink_est.fit(X, y)

        assert "Invalid shrinkage specified." in str(e)
コード例 #11
0
def test_has_decision_function():
    # needed as for example cross_val_score(pipe, X, y, cv=5, scoring="roc_auc", error_score='raise') may fail otherwise, see https://github.com/koaning/scikit-lego/issues/511
    df = load_chicken(as_frame=True)

    X, y = df.drop(columns='weight'), df['weight']
    # This should NOT raise errors
    GroupedPredictor(LogisticRegression(),
                     groups=["diet"]).fit(X, y).decision_function(X)
コード例 #12
0
def test_unexisting_shrinkage_func(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    with pytest.raises(ValueError) as e:
        unexisting_func = "some_highly_unlikely_function_name"

        shrink_est = GroupedPredictor(
            estimator=DummyRegressor(),
            groups=["Planet", "Country"],
            shrinkage=unexisting_func,
        )

        shrink_est.fit(X, y)

        assert "shrinkage function" in str(e)
コード例 #13
0
def test_min_n_obs_shrinkage(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    shrink_est = GroupedPredictor(
        DummyRegressor(),
        ["Planet", "Country", "City"],
        shrinkage="min_n_obs",
        use_global_model=False,
        min_n_obs=2,
    )

    shrink_est.fit(X, y)

    expected_prediction = [means["NL"], means["NL"], means["BE"], means["BE"]]

    assert expected_prediction == shrink_est.predict(X).tolist()
コード例 #14
0
def test_shrinkage_single_group_no_global(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    with pytest.raises(ValueError) as e:
        shrink_est = GroupedPredictor(
            DummyRegressor(),
            "Country",
            shrinkage="constant",
            use_global_model=False,
            alpha=0.1,
        )
        shrink_est.fit(X, y)

        assert (
            "Cannot do shrinkage with a single group if use_global_model is False"
            in str(e))
コード例 #15
0
def test_chickweight_can_do_fallback():
    df = load_chicken(as_frame=True)
    mod = GroupedPredictor(estimator=LinearRegression(), groups="diet")
    mod.fit(df[["time", "diet"]], df["weight"])
    assert set(mod.estimators_.keys()) == {1, 2, 3, 4}
    to_predict = pd.DataFrame({"time": [21, 21], "diet": [5, 6]})
    assert mod.predict(to_predict).shape == (2,)
    assert mod.predict(to_predict)[0] == mod.predict(to_predict)[1]
コード例 #16
0
def test_custom_shrinkage_wrong_return_type(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    def shrinkage_func(group_sizes):
        return group_sizes

    with pytest.raises(ValueError) as e:
        shrink_est = GroupedPredictor(
            DummyRegressor(),
            ["Planet", "Country", "City"],
            shrinkage=shrinkage_func,
            use_global_model=False,
        )

        shrink_est.fit(X, y)

        assert "should return an np.ndarray" in str(e)
コード例 #17
0
def test_custom_shrinkage_raises_error(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    def shrinkage_func(group_sizes):
        raise KeyError("This function is bad and you should feel bad")

    with pytest.raises(ValueError) as e:
        shrink_est = GroupedPredictor(
            DummyRegressor(),
            ["Planet", "Country", "City"],
            shrinkage=shrinkage_func,
            use_global_model=False,
        )

        shrink_est.fit(X, y)

        assert "you should feel bad" in str(
            e) and "while checking the shrinkage function" in str(e)
コード例 #18
0
def test_custom_shrinkage_wrong_length(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    def shrinkage_func(group_sizes):
        n = len(group_sizes)
        return np.repeat(1 / n, n + 1)

    with pytest.raises(ValueError) as e:
        shrink_est = GroupedPredictor(
            DummyRegressor(),
            ["Planet", "Country", "City"],
            shrinkage=shrinkage_func,
            use_global_model=False,
        )

        shrink_est.fit(X, y)

        assert ".shape should be " in str(e)
コード例 #19
0
def test_chickweight_can_do_fallback_proba():
    df = load_chicken(as_frame=True)
    y = np.where(df.weight > df.weight.mean(), 1, 0)
    mod = GroupedPredictor(estimator=LogisticRegression(), groups="diet")
    mod.fit(df[["time", "diet"]], y)
    assert set(mod.estimators_.keys()) == {1, 2, 3, 4}
    to_predict = pd.DataFrame({"time": [21, 21], "diet": [5, 6]})
    assert mod.predict_proba(to_predict).shape == (2, 2)
    assert (mod.predict_proba(to_predict)[0] == mod.predict_proba(to_predict)
            [1]).all()
コード例 #20
0
def test_min_n_obs_shrinkage_too_little_obs(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    too_big_n_obs = X.shape[0] + 1

    shrink_est = GroupedPredictor(
        DummyRegressor(),
        ["Planet", "Country", "City"],
        shrinkage="min_n_obs",
        use_global_model=False,
        min_n_obs=too_big_n_obs,
    )

    with pytest.raises(ValueError) as e:
        shrink_est.fit(X, y)

        assert (
            f"There is no group with size greater than or equal to {too_big_n_obs}"
            in str(e))
コード例 #21
0
def test_chickweight_raise_error_group_col_missing():
    df = load_chicken(as_frame=True)
    mod = GroupedPredictor(estimator=LinearRegression(), groups="diet")
    mod.fit(df[["time", "diet"]], df["weight"])
    with pytest.raises(ValueError) as e:
        mod.predict(df[["time", "chick"]])
        assert "not in columns" in str(e)
コード例 #22
0
def test_chickweight_raise_error_value_col_missing():
    df = load_chicken(as_frame=True)
    mod = GroupedPredictor(estimator=LinearRegression(), groups="diet")
    mod.fit(df[["time", "diet"]], df["weight"])

    with pytest.raises(ValueError):
        # Former test not valid anymore because we don't check for value columns
        # mod.predict(df[["diet", "chick"]])
        mod.predict(df[["diet"]])
コード例 #23
0
def test_fallback_can_raise_error():
    df = load_chicken(as_frame=True)
    mod = GroupedPredictor(
        estimator=LinearRegression(),
        groups="diet",
        use_global_model=False,
        shrinkage=None,
    )
    mod.fit(df[["time", "diet"]], df["weight"])
    to_predict = pd.DataFrame({"time": [21, 21], "diet": [5, 6]})
    with pytest.raises(ValueError) as e:
        mod.predict(to_predict)
        assert "found a group" in str(e)
コード例 #24
0
def test_predict_missing_group_column(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    shrink_est = GroupedPredictor(
        DummyRegressor(),
        ["Planet", "Country", "City"],
        shrinkage="constant",
        use_global_model=False,
        alpha=0.1,
    )

    shrink_est.fit(X, y)

    with pytest.raises(ValueError) as e:
        shrink_est.predict(X.drop(columns=["Country"]))
        assert "group columns" in str(e)
コード例 #25
0
def test_unseen_groups_shrinkage(shrinkage_data):
    df, means = shrinkage_data

    X, y = df.drop(columns="Target"), df["Target"]

    shrink_est = GroupedPredictor(
        DummyRegressor(), ["Planet", "Country", "City"], shrinkage="constant", alpha=0.1
    )

    shrink_est.fit(X, y)

    unseen_group = pd.DataFrame(
        {"Planet": ["Earth"], "Country": ["DE"], "City": ["Hamburg"]}
    )

    with pytest.raises(ValueError) as e:
        shrink_est.predict(X=pd.concat([unseen_group] * 4, axis=0))
        assert "found a group" in str(e)
コード例 #26
0
def test_predict_missing_value_column(shrinkage_data):
    df, means = shrinkage_data

    value_column = "predictor"

    X, y = df.drop(columns="Target"), df["Target"]
    X = X.assign(**{value_column: np.random.normal(size=X.shape[0])})

    shrink_est = GroupedPredictor(
        LinearRegression(),
        ["Planet", "Country", "City"],
        shrinkage="constant",
        use_global_model=False,
        alpha=0.1,
    )

    shrink_est.fit(X, y)

    with pytest.raises(ValueError) as e:
        shrink_est.predict(X.drop(columns=[value_column]))
        assert "columns to use" in str(e)
コード例 #27
0

def create_features(df):
    return df.copy().assign(time_index=df.index)


df = load_data().pipe(create_features)

##############################################################
# Grouped predictor
# Create separate model for separate groups.
##############################################################
features = ["day", "mnth", "year", "season", "holiday", "weekday"]
group_features = ["season"]

regressor = GroupedPredictor(LinearRegression(), groups=group_features)

pipeline = Pipeline([("grab_cols", ColumnSelector(features)),
                     ("regression", regressor)])
pipeline.fit(df, df.rentals)
y_hat = pipeline.predict(df)

# Lets try to shuffle the features
y_hat_shuffled_features = pipeline.predict(
    df[["holiday", "weekday", "day", "mnth", "year", "season"]])

assert all(y_hat == y_hat_shuffled_features
           ), "Shuffling feature order leads to different results."

# Notice that not having a columns throws an error.
pipeline.predict(df.drop("year", axis=1))
コード例 #28
0
def test_chickweight_df1_keys():
    df = load_chicken(as_frame=True)
    mod = GroupedPredictor(estimator=LinearRegression(), groups="diet")
    mod.fit(df[["time", "diet"]], df["weight"])
    assert set(mod.estimators_.keys()) == {1, 2, 3, 4}
コード例 #29
0
def test_chickweight_np_keys():
    df = load_chicken(as_frame=True)
    mod = GroupedPredictor(estimator=LinearRegression(), groups=[1, 2])
    mod.fit(df[["time", "chick", "diet"]].values, df["weight"].values)
    # there should still only be 50 groups on this dataset
    assert len(mod.estimators_.keys()) == 50
コード例 #30
0
def test_chickweight_df2_keys():
    df = load_chicken(as_frame=True)
    mod = GroupedPredictor(estimator=LinearRegression(), groups="chick")
    mod.fit(df[["time", "chick"]], df["weight"])
    assert set(mod.estimators_.keys()) == set(range(1, 50 + 1))