diff --git a/src/c_api/c_api_utils.h b/src/c_api/c_api_utils.h index 11f54cfb9549..7c1538cb132c 100644 --- a/src/c_api/c_api_utils.h +++ b/src/c_api/c_api_utils.h @@ -206,8 +206,14 @@ inline void GenerateFeatureMap(Learner const *learner, // Use the feature names and types from booster. std::vector feature_names; learner->GetFeatureNames(&feature_names); + if (!feature_names.empty()) { + CHECK_EQ(feature_names.size(), n_features) << "Incorrect number of feature names."; + } std::vector feature_types; learner->GetFeatureTypes(&feature_types); + if (!feature_types.empty()) { + CHECK_EQ(feature_types.size(), n_features) << "Incorrect number of feature types."; + } for (size_t i = 0; i < n_features; ++i) { feature_map.PushBack( i, diff --git a/tests/python/test_basic.py b/tests/python/test_basic.py index 7ce87b208642..2d2bec51867c 100644 --- a/tests/python/test_basic.py +++ b/tests/python/test_basic.py @@ -154,6 +154,23 @@ def test_dump(self): dump4j = json.loads(dump4[0]) assert 'gain' in dump4j, "Expected 'gain' to be dumped in JSON." + def test_feature_score(self): + rng = np.random.RandomState(0) + data = rng.randn(100, 2) + target = np.array([0, 1] * 50) + features = ["F0"] + with pytest.raises(ValueError): + xgb.DMatrix(data, label=target, feature_names=features) + + params = {"objective": "binary:logistic"} + dm = xgb.DMatrix(data, label=target, feature_names=["F0", "F1"]) + booster = xgb.train(params, dm, num_boost_round=1) + # no error since feature names might be assigned before the booster seeing data + # and booster doesn't known about the actual number of features. + booster.feature_names = ["F0"] + with pytest.raises(ValueError): + booster.get_fscore() + def test_load_file_invalid(self): with pytest.raises(xgb.core.XGBoostError): xgb.Booster(model_file='incorrect_path')