<jupyter_start><jupyter_text>The Adult Dataset (Binary Classification with Synthetic Data)The adult dataset is a classic imbalanced classification task dataset. The final column specifies whether the person makes <= 50k a year, or more.Here we see MWEM stretched - we are forced to carefully select our feature dependence (via the "splits" feature) to acheive a reasonable data synthesis.We show that by either specifying a max_bin_count, or by dropping continuous columns, we can greatly speed up performance.<jupyter_code>import os
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import ComplementNB
from sklearn.linear_model import RidgeClassifier

import utils

from opendp.smartnoise.synthesizers.mwem import MWEMSynthesizer

from load_data import load_data
datasets = load_data(['adult'])

adult = datasets['adult']['data']
adult_cat_ord = datasets['adult']['data'].copy()

cat_ord_columns = ['workclass',
                       'marital-status', 
                       'occupation', 
                       'relationship', 
                       'race',
                       'gender',
                       'native-country',
                       'income',
                       'education',
                       'age',
                       'education-num',
                       'hours-per-week',
                  'earning-class']

for c in adult_cat_ord.columns.values:
    if not c in cat_ord_columns:
        adult_cat_ord = adult_cat_ord.drop([c], axis=1)
synth = MWEMSynthesizer(500, 0.1, 30, 15, splits=[[0,1,2],[3,4,5],[6,7,8],[9,10],[11,12],[13,14]], max_bin_count=400)
synth.fit(datasets['adult']['data'])

synth_cat_ord = MWEMSynthesizer(500, 0.1, 30, 15, split_factor=3)
synth_cat_ord.fit(adult_cat_ord)
sample_size = len(adult)
synthetic = synth.sample(int(sample_size))
synthetic_cat_ord = synth_cat_ord.sample(int(sample_size))
utils.test_real_vs_synthetic_data(adult, synthetic, RidgeClassifier, tsne=True, box=True, describe=True)
utils.test_real_vs_synthetic_data(adult_cat_ord, synthetic_cat_ord, ComplementNB, tsne=True, box=True, describe=True)<jupyter_output>Trained on Real Data
              precision    recall  f1-score   support

           0       0.89      0.63      0.74      1874
           1       0.41      0.78      0.54       626

    accuracy                           0.67      2500
   macro avg       0.65      0.70      0.64      2500
weighted avg       0.77      0.67      0.69      2500

Accuracy real: 0.6664

Trained on Synthetic Data
              precision    recall  f1-score   support

           0       0.75      0.95      0.84      1874
           1       0.26      0.05      0.09       626

    accuracy                           0.72      2500
   macro avg       0.50      0.50      0.46      2500
weighted avg       0.63      0.72      0.65      2500

Accuracy synthetic: 0.7248

Random Guessing
              precision    recall  f1-score   support

           0       0.48      0.49      0.49      1246
           1       0.49      0.48      0.48      1254

    accuracy                           0.48      2500
   macro avg [...]
{'fraction_non_alphanumeric': 0.082256539552474, 'fraction_numerical': 0.06712890009454775, 'mean_word_length': 1.8933454876937101, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '624277', 'license': 'MIT', 'n_tokens_mistral': 1094, 'n_tokens_neox': 933, 'n_words': 259, 'path': 'data/synthesis/mwem_sample/Adult Dataset Classification (Binary).ipynb', 'repo_name': 'huwd/smartnoise-samples', 'size': '3173'}