Imbalanced classification data can let a model improve overall accuracy while ignoring rare labels. scikit-learn classifiers that support class_weight can give each class a different loss contribution during fitting, which makes the minority class visible to the optimizer without changing the original rows.

LogisticRegression is a compact baseline for this weighting pattern because its class_weight parameter accepts either a class-to-weight dictionary or balanced. The balanced mode calculates weights from the training labels, so the smaller class receives a larger weight before fit() solves the model.

Fit the weighted model from the training split only, then judge it with class-aware metrics such as recall, F1-score, and balanced accuracy. A weighted classifier can lower plain accuracy while improving minority recall, so compare the report with the unweighted baseline before keeping the setting.

Steps to train a weighted scikit-learn classifier:

  1. Create a Python script for the weighted classifier run.
    train_weighted_classifier.py
    from collections import Counter
     
    import numpy as np
    from sklearn.datasets import make_classification
    from sklearn.linear_model import LogisticRegression
    from sklearn.metrics import balanced_accuracy_score, classification_report
    from sklearn.model_selection import train_test_split
    from sklearn.utils.class_weight import compute_class_weight
     
     
    X, y = make_classification(
        n_samples=1200,
        n_features=6,
        n_informative=4,
        n_redundant=0,
        weights=[0.92, 0.08],
        class_sep=0.65,
        flip_y=0.02,
        random_state=42,
    )
     
    X_train, X_test, y_train, y_test = train_test_split(
        X,
        y,
        test_size=0.25,
        stratify=y,
        random_state=42,
    )
     
    classes = np.unique(y_train)
    class_weights = compute_class_weight(
        class_weight="balanced",
        classes=classes,
        y=y_train,
    )
    weight_map = {
        int(label): round(float(weight), 3)
        for label, weight in zip(classes, class_weights)
    }
    class_counts = {
        int(label): int(count)
        for label, count in sorted(Counter(y_train).items())
    }
     
    print(f"Training class counts: {class_counts}")
    print(f"Balanced class weights: {weight_map}")
     
    models = {
        "unweighted": LogisticRegression(max_iter=1000, random_state=42),
        "balanced": LogisticRegression(
            class_weight="balanced",
            max_iter=1000,
            random_state=42,
        ),
    }
     
    for name, model in models.items():
        model.fit(X_train, y_train)
        predictions = model.predict(X_test)
        score = balanced_accuracy_score(y_test, predictions)
        print()
        print(f"{name} classifier")
        print(f"class_weight: {model.get_params()['class_weight']}")
        print(f"balanced accuracy: {score:.3f}")
        print(
            classification_report(
                y_test,
                predictions,
                target_names=["majority 0", "minority 1"],
                digits=3,
                zero_division=0,
            )
        )

    compute_class_weight() prints the same inverse-frequency weights that class_weight="balanced" applies during fitting.

  2. Run the training script.
    $ python train_weighted_classifier.py
    Training class counts: {0: 817, 1: 83}
    Balanced class weights: {0: 0.551, 1: 5.422}
    
    unweighted classifier
    class_weight: None
    balanced accuracy: 0.550
                  precision    recall  f1-score   support
    
      majority 0      0.915     0.993     0.952       272
      minority 1      0.600     0.107     0.182        28
    
        accuracy                          0.910       300
       macro avg      0.758     0.550     0.567       300
    weighted avg      0.886     0.910     0.880       300
    
    
    balanced classifier
    class_weight: balanced
    balanced accuracy: 0.589
                  precision    recall  f1-score   support
    
      majority 0      0.927     0.750     0.829       272
      minority 1      0.150     0.429     0.222        28
    
        accuracy                          0.720       300
       macro avg      0.539     0.589     0.526       300
    weighted avg      0.855     0.720     0.773       300
  3. Check that the minority label receives the larger class weight.

    The training split has 817 rows for class 0 and 83 rows for class 1, so balanced weighting assigns class 1 a much larger loss weight.

  4. Verify the weighted report changes the minority-class row before keeping the setting.

    The weighted run raises minority 1 recall from 0.107 to 0.429, but plain accuracy falls from 0.910 to 0.720. Keep the weighted model only when that tradeoff matches the project cost of missed minority cases.