!pip install fairtfm
Collecting fairtfm

  Downloading fairtfm-1.0.0-py3-none-any.whl.metadata (5.3 kB)

Collecting torch>=2.9 (from fairtfm)

  Downloading torch-2.14.0-cp310-cp310-macosx_14_0_arm64.whl.metadata (38 kB)

Requirement already satisfied: numpy>=1.24.0 in ./.venv/lib/python3.10/site-packages (from fairtfm) (2.2.6)

Requirement already satisfied: pandas>=2.0.0 in ./.venv/lib/python3.10/site-packages (from fairtfm) (2.3.0)

Requirement already satisfied: scikit-learn>=1.3.0 in ./.venv/lib/python3.10/site-packages (from fairtfm) (1.6.1)

Collecting fairlearn>=0.13.0 (from fairtfm)

  Downloading fairlearn-0.14.0-py3-none-any.whl.metadata (7.3 kB)

Collecting huggingface_hub>=0.20 (from fairtfm)

  Downloading huggingface_hub-1.30.0-py3-none-any.whl.metadata (16 kB)

Collecting narwhals>=1.14.0 (from fairlearn>=0.13.0->fairtfm)

  Downloading narwhals-2.26.0-py3-none-any.whl.metadata (15 kB)

Requirement already satisfied: scipy>=1.9.3 in ./.venv/lib/python3.10/site-packages (from fairlearn>=0.13.0->fairtfm) (1.15.3)

Collecting click<9.0.0,>=8.4.2 (from huggingface_hub>=0.20->fairtfm)

  Using cached click-8.5.0-py3-none-any.whl.metadata (2.6 kB)

Collecting filelock>=3.10.0 (from huggingface_hub>=0.20->fairtfm)

  Downloading filelock-3.32.6-py3-none-any.whl.metadata (2.0 kB)

Collecting fsspec>=2023.5.0 (from huggingface_hub>=0.20->fairtfm)

  Using cached fsspec-2026.7.0-py3-none-any.whl.metadata (10 kB)

Collecting hf-xet<2.0.0,>=1.5.2 (from huggingface_hub>=0.20->fairtfm)

  Using cached hf_xet-1.6.0-cp38-abi3-macosx_11_0_arm64.whl.metadata (4.9 kB)

Requirement already satisfied: httpx<1,>=0.23.0 in ./.venv/lib/python3.10/site-packages (from huggingface_hub>=0.20->fairtfm) (0.28.1)

Requirement already satisfied: packaging>=20.9 in ./.venv/lib/python3.10/site-packages (from huggingface_hub>=0.20->fairtfm) (25.0)

Requirement already satisfied: pyyaml>=5.1 in ./.venv/lib/python3.10/site-packages (from huggingface_hub>=0.20->fairtfm) (6.0.2)

Collecting tqdm>=4.42.1 (from huggingface_hub>=0.20->fairtfm)

  Using cached tqdm-4.70.0-py3-none-any.whl.metadata (57 kB)

Requirement already satisfied: typing-extensions>=4.1.0 in ./.venv/lib/python3.10/site-packages (from huggingface_hub>=0.20->fairtfm) (4.14.0)

Requirement already satisfied: anyio in ./.venv/lib/python3.10/site-packages (from httpx<1,>=0.23.0->huggingface_hub>=0.20->fairtfm) (4.9.0)

Requirement already satisfied: certifi in ./.venv/lib/python3.10/site-packages (from httpx<1,>=0.23.0->huggingface_hub>=0.20->fairtfm) (2025.4.26)

Requirement already satisfied: httpcore==1.* in ./.venv/lib/python3.10/site-packages (from httpx<1,>=0.23.0->huggingface_hub>=0.20->fairtfm) (1.0.9)

Requirement already satisfied: idna in ./.venv/lib/python3.10/site-packages (from httpx<1,>=0.23.0->huggingface_hub>=0.20->fairtfm) (3.10)

Requirement already satisfied: h11>=0.16 in ./.venv/lib/python3.10/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->huggingface_hub>=0.20->fairtfm) (0.16.0)

Requirement already satisfied: python-dateutil>=2.8.2 in ./.venv/lib/python3.10/site-packages (from pandas>=2.0.0->fairtfm) (2.9.0.post0)

Requirement already satisfied: pytz>=2020.1 in ./.venv/lib/python3.10/site-packages (from pandas>=2.0.0->fairtfm) (2025.2)

Requirement already satisfied: tzdata>=2022.7 in ./.venv/lib/python3.10/site-packages (from pandas>=2.0.0->fairtfm) (2025.2)

Requirement already satisfied: six>=1.5 in ./.venv/lib/python3.10/site-packages (from python-dateutil>=2.8.2->pandas>=2.0.0->fairtfm) (1.17.0)

Requirement already satisfied: joblib>=1.2.0 in ./.venv/lib/python3.10/site-packages (from scikit-learn>=1.3.0->fairtfm) (1.5.1)

Requirement already satisfied: threadpoolctl>=3.1.0 in ./.venv/lib/python3.10/site-packages (from scikit-learn>=1.3.0->fairtfm) (3.6.0)

Collecting setuptools>=77.0.3 (from torch>=2.9->fairtfm)

  Using cached setuptools-84.0.0-py3-none-any.whl.metadata (6.6 kB)

Collecting sympy>=1.13.3 (from torch>=2.9->fairtfm)

  Using cached sympy-1.14.0-py3-none-any.whl.metadata (12 kB)

Collecting networkx>=2.5.1 (from torch>=2.9->fairtfm)

  Using cached networkx-3.4.2-py3-none-any.whl.metadata (6.3 kB)

Requirement already satisfied: jinja2 in ./.venv/lib/python3.10/site-packages (from torch>=2.9->fairtfm) (3.1.6)

Collecting mpmath<1.4,>=1.1.0 (from sympy>=1.13.3->torch>=2.9->fairtfm)

  Using cached mpmath-1.3.0-py3-none-any.whl.metadata (8.6 kB)

Requirement already satisfied: exceptiongroup>=1.0.2 in ./.venv/lib/python3.10/site-packages (from anyio->httpx<1,>=0.23.0->huggingface_hub>=0.20->fairtfm) (1.3.0)

Requirement already satisfied: sniffio>=1.1 in ./.venv/lib/python3.10/site-packages (from anyio->httpx<1,>=0.23.0->huggingface_hub>=0.20->fairtfm) (1.3.1)

Requirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib/python3.10/site-packages (from jinja2->torch>=2.9->fairtfm) (3.0.2)

Downloading fairtfm-1.0.0-py3-none-any.whl (15 kB)

Downloading fairlearn-0.14.0-py3-none-any.whl (135 kB)

Downloading huggingface_hub-1.30.0-py3-none-any.whl (796 kB)

   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 796.8/796.8 kB 3.9 MB/s eta 0:00:00

Using cached click-8.5.0-py3-none-any.whl (125 kB)

Using cached hf_xet-1.6.0-cp38-abi3-macosx_11_0_arm64.whl (3.9 MB)

Downloading filelock-3.32.6-py3-none-any.whl (100 kB)

Using cached fsspec-2026.7.0-py3-none-any.whl (206 kB)

Downloading narwhals-2.26.0-py3-none-any.whl (474 kB)

Downloading torch-2.14.0-cp310-cp310-macosx_14_0_arm64.whl (127.2 MB)

   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 127.2/127.2 MB 9.4 MB/s eta 0:00:0000:0100:01

Using cached networkx-3.4.2-py3-none-any.whl (1.7 MB)

Using cached setuptools-84.0.0-py3-none-any.whl (818 kB)

Using cached sympy-1.14.0-py3-none-any.whl (6.3 MB)

Using cached mpmath-1.3.0-py3-none-any.whl (536 kB)

Using cached tqdm-4.70.0-py3-none-any.whl (80 kB)

Installing collected packages: mpmath, tqdm, sympy, setuptools, networkx, narwhals, hf-xet, fsspec, filelock, click, torch, fairlearn, huggingface_hub, fairtfm

  Attempting uninstall: setuptools━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  2/14 [sympy]

    Found existing installation: setuptools 57.4.0━━━━━━━━━━━━  2/14 [sympy]

    Uninstalling setuptools-57.4.0:━━━━━━━━━━━━━━━━━━━━━━━━━━━  2/14 [sympy]

      Successfully uninstalled setuptools-57.4.0━━━━━━━━━━━━━━━━━━  3/14 [setuptools]

   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 14/14 [fairtfm]2/14 [huggingface_hub]

Successfully installed click-8.5.0 fairlearn-0.14.0 fairtfm-1.0.0 filelock-3.32.6 fsspec-2026.7.0 hf-xet-1.6.0 huggingface_hub-1.30.0 mpmath-1.3.0 narwhals-2.26.0 networkx-3.4.2 setuptools-84.0.0 sympy-1.14.0 torch-2.14.0 tqdm-4.70.0



[notice] A new release of pip is available: 25.1.1 -> 26.2.1

[notice] To update, run: pip install --upgrade pip
from fairtfm import FairTFMClassifier
from fairlearn.datasets import fetch_adult
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, LabelEncoder

from sklearn.linear_model import LogisticRegression
import pandas as pd
X_raw, y = fetch_adult(as_frame=True, return_X_y=True)
X_raw.head(5)
age workclass fnlwgt education education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country
0 25 Private 226802 11th 7 Never-married Machine-op-inspct Own-child Black Male 0 0 40 United-States
1 38 Private 89814 HS-grad 9 Married-civ-spouse Farming-fishing Husband White Male 0 0 50 United-States
2 28 Local-gov 336951 Assoc-acdm 12 Married-civ-spouse Protective-serv Husband White Male 0 0 40 United-States
3 44 Private 160323 Some-college 10 Married-civ-spouse Machine-op-inspct Husband Black Male 7688 0 40 United-States
4 18 NaN 103497 Some-college 10 Never-married NaN Own-child White Female 0 0 30 United-States
s = X_raw['sex']
X = X_raw.drop(columns=['sex'])
X = pd.get_dummies(X, drop_first=True)
 
y = LabelEncoder().fit_transform(y)
s = LabelEncoder().fit_transform(s)





X_train, X_test, y_train, y_test, s_train, s_test = train_test_split(X, y, s, test_size=0.3, random_state=42)

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# subsample for faster inference
train_sample_size, test_sample_size = 1000, 500 
y_train = y_train[:train_sample_size] 
s_train = s_train[:train_sample_size]
X_train = X_train[:train_sample_size]
X_test = X_test[:test_sample_size]
y_test = y_test[:test_sample_size]
s_test = s_test[:test_sample_size]
lr = LogisticRegression()

lr.fit(X_train, y_train)
y_prob = lr.predict_proba(X_test)[:, 1]
y_pred = (y_prob >= 0.5).astype(int)
from fairlearn.metrics import demographic_parity_difference 
from sklearn.metrics import accuracy_score, roc_auc_score
acc= accuracy_score(y_test, y_pred)
dp_diff = demographic_parity_difference(y_test, y_pred, sensitive_features=s_test)
auc = roc_auc_score(y_test, y_prob)

print(f"Accuracy: {acc:.4f}")
print(f"Demographic Parity Difference: {dp_diff:.4f}")
print(f"AUC: {auc:.4f}")
Accuracy: 0.8240
Demographic Parity Difference: 0.0823
AUC: 0.8661