2023-07-21 11:41:16 +02:00
|
|
|
import pickle
|
2023-07-20 09:03:22 +02:00
|
|
|
import numpy as np
|
|
|
|
from sklearn.linear_model import LogisticRegression
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import pandas as pd
|
|
|
|
|
|
|
|
import quapy as qp
|
2023-07-21 11:41:16 +02:00
|
|
|
from quapy.method.aggregative import EMQ, DistributionMatching, PACC, HDy, OneVsAllAggregative
|
2023-07-20 09:03:22 +02:00
|
|
|
from method_kdey import KDEy
|
2023-07-21 11:41:16 +02:00
|
|
|
from method_dirichlety import DIRy
|
2023-07-20 09:03:22 +02:00
|
|
|
from quapy.model_selection import GridSearchQ
|
2023-07-21 11:41:16 +02:00
|
|
|
from quapy.protocol import UPP
|
2023-07-20 09:03:22 +02:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
|
|
qp.environ['SAMPLE_SIZE'] = qp.datasets.LEQUA2022_SAMPLE_SIZE['T1B']
|
|
|
|
qp.environ['N_JOBS'] = -1
|
2023-07-21 11:41:16 +02:00
|
|
|
result_dir = f'results_lequa'
|
|
|
|
optim = 'mae'
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-21 11:41:16 +02:00
|
|
|
os.makedirs(result_dir, exist_ok=True)
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-21 11:41:16 +02:00
|
|
|
hyper_LR = {
|
|
|
|
'classifier__C': np.logspace(-3,3,7),
|
|
|
|
'classifier__class_weight': ['balanced', None]
|
|
|
|
}
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-24 16:28:21 +02:00
|
|
|
for method in ['KDE', 'PACC', 'SLD', 'DM', 'HDy-OvA', 'DIR']:
|
2023-07-21 11:41:16 +02:00
|
|
|
|
|
|
|
#if os.path.exists(result_path):
|
|
|
|
# print('Result already exit. Nothing to do')
|
|
|
|
# sys.exit(0)
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-21 11:41:16 +02:00
|
|
|
result_path = f'{result_dir}/{method}'
|
|
|
|
if os.path.exists(result_path+'.dataframe'):
|
|
|
|
print(f'result file {result_path} already exist; skipping')
|
|
|
|
continue
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-21 11:41:16 +02:00
|
|
|
with open(result_path+'.csv', 'at') as csv:
|
|
|
|
csv.write(f'Method\tDataset\tMAE\tMRAE\tKLD\n')
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-21 11:41:16 +02:00
|
|
|
dataset = 'T1B'
|
|
|
|
train, val_gen, test_gen = qp.datasets.fetch_lequa2022(dataset)
|
2023-07-24 16:28:21 +02:00
|
|
|
print(f'init {dataset} #instances: {len(train)}')
|
2023-07-21 11:41:16 +02:00
|
|
|
if method == 'KDE':
|
|
|
|
param_grid = {
|
|
|
|
'bandwidth': np.linspace(0.001, 0.2, 21),
|
|
|
|
'classifier__C': np.logspace(-4,4,9),
|
|
|
|
'classifier__class_weight': ['balanced', None]
|
|
|
|
}
|
|
|
|
quantifier = KDEy(LogisticRegression(), target='max_likelihood')
|
2023-07-24 16:28:21 +02:00
|
|
|
elif method == 'KDE-debug':
|
|
|
|
param_grid = None
|
|
|
|
qp.environ['N_JOBS'] = 1
|
|
|
|
quantifier = KDEy(LogisticRegression(), target='max_likelihood', bandwidth=0.02)
|
|
|
|
#train = train.sampling(280, *[1./train.n_classes]*(train.n_classes-1))
|
2023-07-21 11:41:16 +02:00
|
|
|
elif method == 'DIR':
|
|
|
|
param_grid = hyper_LR
|
|
|
|
quantifier = DIRy(LogisticRegression())
|
|
|
|
elif method == 'SLD':
|
|
|
|
param_grid = hyper_LR
|
|
|
|
quantifier = EMQ(LogisticRegression())
|
|
|
|
elif method == 'PACC':
|
|
|
|
param_grid = hyper_LR
|
|
|
|
quantifier = PACC(LogisticRegression())
|
|
|
|
elif method == 'HDy-OvA':
|
|
|
|
param_grid = {
|
2023-07-24 16:28:21 +02:00
|
|
|
'binary_quantifier__classifier__C': np.logspace(-3,3,9),
|
2023-07-21 11:41:16 +02:00
|
|
|
'binary_quantifier__classifier__class_weight': ['balanced', None]
|
|
|
|
}
|
|
|
|
quantifier = OneVsAllAggregative(HDy(LogisticRegression()))
|
|
|
|
elif method == 'DM':
|
|
|
|
param_grid = {
|
|
|
|
'nbins': [5,10,15],
|
|
|
|
'classifier__C': np.logspace(-4,4,9),
|
|
|
|
'classifier__class_weight': ['balanced', None]
|
|
|
|
}
|
|
|
|
quantifier = DistributionMatching(LogisticRegression())
|
|
|
|
else:
|
|
|
|
raise NotImplementedError('unknown method', method)
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-24 16:28:21 +02:00
|
|
|
if param_grid is not None:
|
|
|
|
modsel = GridSearchQ(quantifier, param_grid, protocol=val_gen, refit=False, n_jobs=-1, verbose=1, error=optim)
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-24 16:28:21 +02:00
|
|
|
modsel.fit(train)
|
|
|
|
print(f'best params {modsel.best_params_}')
|
|
|
|
pickle.dump(modsel.best_params_, open(f'{result_dir}/{method}_{dataset}.hyper.pkl', 'wb'), pickle.HIGHEST_PROTOCOL)
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-24 16:28:21 +02:00
|
|
|
quantifier = modsel.best_model()
|
|
|
|
else:
|
|
|
|
print('debug mode... skipping model selection')
|
|
|
|
quantifier.fit(train)
|
2023-07-20 09:03:22 +02:00
|
|
|
|
2023-07-21 11:41:16 +02:00
|
|
|
report = qp.evaluation.evaluation_report(quantifier, protocol=test_gen, error_metrics=['mae', 'mrae', 'kld'], verbose=True)
|
|
|
|
means = report.mean()
|
|
|
|
report.to_csv(result_path+'.dataframe')
|
|
|
|
csv.write(f'{method}\tLeQua-T1B\t{means["mae"]:.5f}\t{means["mrae"]:.5f}\t{means["kld"]:.5f}\n')
|
|
|
|
csv.flush()
|
|
|
|
|
|
|
|
df = pd.read_csv(result_path+'.csv', sep='\t')
|
2023-07-20 09:03:22 +02:00
|
|
|
|
|
|
|
pd.set_option('display.max_columns', None)
|
|
|
|
pd.set_option('display.max_rows', None)
|
|
|
|
pv = df.pivot_table(index='Dataset', columns="Method", values=["MAE", "MRAE"])
|
|
|
|
print(pv)
|