"""Block-held-out semantic classification, excluding EOG/stim and reading data.""" import os os.environ.setdefault('MPLCONFIGDIR',os.path.abspath('.cache/matplotlib')) import argparse,json,re,time,warnings,joblib from pathlib import Path import mne,numpy as np from scipy.signal import welch from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score,balanced_accuracy_score,f1_score,confusion_matrix from threadpoolctl import threadpool_limits threadpool_limits(1) ROOT=Path('datasets/chisco/derivatives/preprocessed_fif/sub-01/eeg');MAP=json.load(open('datasets/chisco_metadata/json/textmaps.json')) def block(p):return int(re.search(r'run-(\d+)',p.name)[1]) def extract(split,evaluation=False): if split=='test' and not evaluation:raise PermissionError('Chisco final test locked') cache=Path('preprocessing')/f'chisco_sub01_{split}.npz' if cache.exists():return dict(np.load(cache)) allowed={'train':range(1,28),'validation':range(28,37),'test':range(37,46)}[split] xx=[];yy=[];gg=[];words=[];eogs=[];records=[] for p in sorted(ROOT.glob('*task-imagine*.fif'),key=block): if block(p) not in allowed:continue with warnings.catch_warnings(): warnings.simplefilter('ignore');e=mne.read_epochs(p,preload=True,verbose='ERROR') assert e.info['sfreq']==500 and e.tmin==5 and e.tmax==8.3 labels=np.array([MAP.get(w.strip(),-1) for w in e.metadata.Word]);valid=labels>=0 eeg=e.copy().pick('eeg');assert len(eeg.ch_names)==122 # Omit 300 ms after visual cue offset; use imagined-only late window. x=eeg.get_data(copy=True)[valid,:,-1500:]*1e6;x-=x.mean(axis=1,keepdims=True) f,power=welch(x,fs=500,nperseg=500,axis=-1) feat=np.concatenate([np.log(power[:,:,(f>=a)&(f=a)&(fbest[0]:best=(met['balanced_accuracy'],m,c,met) name=f'chisco_sub01_{kind}_blocksplit';joblib.dump(best[1],f'checkpoints/{name}.joblib') r={'name':name,'split':'validation','metrics':best[3],'C':best[2],'search':search,'classes':39,'uniform_chance':1/39,'train_n':int(keep.sum()),'validation_n':len(b['y']),'train_classes':np.bincount(a['y'][keep],minlength=39).tolist(),'validation_classes':np.bincount(b['y'],minlength=39).tolist(),'removed_validation_text_overlap':int((~keep).sum()),'seconds':time.time()-t,'interpretation':'EEG semantic classifier' if kind=='x' else 'EOG artifact control'} json.dump(r,open(f'experiments/{name}.json','w'),indent=2);print(name,best[3]['accuracy'],best[0],flush=True) if __name__=='__main__': from experiment_guard import assert_tuning_open assert_tuning_open() train()