[Python] All Hyperparameters being fetched Strings instead of their actual data types

Discussão em 'Python' iniciado por Stack, Fevereiro 16, 2025.

  1. Stack

    Stack Membro Participativo

    I wrote the following fast API code to train a classification model: However, all hyperparameters are being received as strings, even when they should be integers, floats, or booleans.

    Fast API Code:

    class Parameter(BaseModel):
    key: str
    selectedValue: Union[str, int, float, bool, List[Union[str, int, float, bool]]]

    class Model(BaseModel):
    modelCategory: str
    modelName: str
    parameters: Optional[List[Parameter]] = None

    class HyperparameterTuningRequest(BaseModel):
    models: List[Model]

    @app.post("/tune_hyperparameters/")
    def hyperparameter_tuning(request: HyperparameterTuningRequest):
    for model in request.models:
    if model.parameters:
    for param in model.parameters:
    print(f"Parameter Key: {param.key}")
    print(f"Parameter Value: {param.selectedValue}")
    print(f"Parameter Type: {type(param.selectedValue)}") # Always prints <class 'str'>


    classification code:

    #Boolean conversion

    def convert_to_bool(value):
    if isinstance(value, bool):
    return value
    if isinstance(value, str):
    return value.lower() == 'true'
    if isinstance(value, int):
    return bool(value)
    return False

    def convert_to_float(value, param_name, default_value):
    try:
    float_value = float(value)
    if param_name == 'l1_ratio':
    if 0 <= float_value <= 1:
    return float_value
    return default_value
    elif float_value <= 0:
    return default_value
    return float_value
    except (ValueError, TypeError):
    return default_value

    if modelCategory == "Classification" and "Logistic Regression" in modelName:
    # if trial is not None: # Optuna mode
    if optunaFlag: # Optuna mode

    params = {
    'solver': trial.suggest_categorical('solver', ['lbfgs', 'saga']), # Limiting to most compatible solvers
    'penalty': trial.suggest_categorical('penalty', ['l2']), # Limiting to most compatible penalty
    'C': trial.suggest_float('C', 1e-4, 1e4, log=True),
    'tol': trial.suggest_float('tol', 1e-6, 1e-3, log=True),
    'max_iter': trial.suggest_int('max_iter', 100, 1000),
    'fit_intercept': trial.suggest_categorical('fit_intercept', [True, False]),
    'random_state': trial.suggest_int('random_state', 1, 1000),
    'dual': False,
    'l1_ratio': None
    }
    # print("Optuna suggested params:", params)
    return params

    else: # Manual mode
    # Default hyperparameters - only used when no user parameters provided
    default_params = {
    'penalty': 'l2',
    'dual': False,
    'tol': 1e-4,
    'C': 1.0,
    'fit_intercept': True,
    'intercept_scaling': 1.0,
    'class_weight': 'balanced',
    'random_state': 42,
    'solver': 'lbfgs',
    'max_iter': 100,
    'multi_class': 'auto',
    'verbose': 0,
    'warm_start': False,
    'n_jobs': None,
    'l1_ratio': None
    }

    hyperparams = default_params.copy()

    if parameters:
    for key, value in parameters.items():
    if value is not None and value != "null":
    param_value = value.get('value') if isinstance(value, dict) else value

    # Special handling for null/None values
    if param_value == "null" or param_value == "None":
    hyperparams[key] = None
    continue

    if param_value is not None:
    if key in ['dual', 'fit_intercept', 'warm_start']:
    hyperparams[key] = convert_to_bool(param_value)
    elif key in ['C', 'tol', 'intercept_scaling']:
    hyperparams[key] = convert_to_float(param_value, key, default_params[key])
    elif key == 'l1_ratio':
    hyperparams[key] = convert_to_float(param_value, key, None)
    elif key in ['max_iter', 'verbose']:
    hyperparams[key] = convert_to_int(param_value)
    elif key == 'random_state':
    hyperparams[key] = None if param_value == "null" else convert_to_int(param_value)
    else:
    hyperparams[key] = param_value

    return hyperparams


    I'm explicitly converting each hyperparameter to it's actual data type, but when I check the data types of the HPs fetched from the postman payload, it shows all the values as strings. Can someone help me figure out the issue?

    Here's my payload:

    "parameters":
    [
    {
    "key": "penalty",
    "selectedValue": "l2",
    "_id": "67a608e3a069a0fdf9096478"
    },
    {
    "key": "dual",
    "selectedValue": "False",
    "_id": "67a608e3a069a0fdf9096479"
    },
    {
    "key": "tol",
    "selectedValue": 0.001,
    "_id": "67a608e3a069a0fdf909647a"
    },
    {
    "key": "C",
    "selectedValue": 1,
    "_id": "67a608e3a069a0fdf909647b"
    },
    {
    "key": "fit_intercept",
    "selectedValue": "True",
    "_id": "67a608e3a069a0fdf909647c"
    },
    {
    "key": "intercept_scaling",
    "selectedValue": 1,
    "_id": "67a608e3a069a0fdf909647d"
    },
    {
    "key": "class_weight",
    "selectedValue": "balanced",
    "_id": "67a608e3a069a0fdf909647e"
    },
    {
    "key": "solver",
    "selectedValue": "lbfgs",
    "_id": "67a608e3a069a0fdf909647f"
    },
    {
    "key": "max_iter",
    "selectedValue": 100,
    "_id": "67a608e3a069a0fdf9096480"
    },
    {
    "key": "multi_class",
    "selectedValue": "auto",
    "_id": "67a608e3a069a0fdf9096481"
    },
    {
    "key": "n_jobs",
    "selectedValue": "None",
    "_id": "67a608e3a069a0fdf9096482"
    },
    {
    "key": "random_state",
    "selectedValue": 42,
    "_id": "67a608e3a069a0fdf9096483"
    },
    {
    "key": "warm_start",
    "selectedValue": "False",
    "_id": "67a608e3a069a0fdf9096484"
    },
    {
    "key": "verbose",
    "selectedValue": 1,
    "_id": "67a608e3a069a0fdf9096485"
    },
    {
    "key": "l1_ratio",
    "selectedValue": "None",
    "_id": "67a608e3a069a0fdf9096486"
    }
    ]

    Continue reading...

Compartilhe esta Página