OSCR

Large language models poorly capture how word order shapes representations of sentence meaning in the human brain

Code ↔ Paper

14 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 14 matches
  1. [1] § Results › fMRI results ↔ 2_Analyse_fmri.ipynb, lines 613 to 687 · score 0.83 · angular gyrus, somatosensory cortex, posterior cingulate, language network, visual cortex, frontal · Report a mismatch
  2. [2] § Methods › Stimuli and computational models › Transformer models ↔ 1_Analyse_models.ipynb, lines 169 to 259 · score 0.77 · SentBERT, AMRbart, DefSent, OpenAI, InferSent, ERNIE · Report a mismatch
  3. [3] § Methods › Stimuli and computational models › Transformer models ↔ 2_Analyse_fmri.ipynb, lines 351 to 416 · score 0.76 · SentBERT, AMRBart, DefSent, OpenAI, InferSent, ERNIE · Report a mismatch
  4. [4] § Methods › Searchlight RSA ↔ Code-3-GLMSingle/4_compute_second_level_1mean.py, lines 27 to 66 · score 0.75 · threshold free cluster, cortical mask, enhancement, FWHM, smoothed · Report a mismatch
  5. [5] § Results › fMRI results ↔ 1_Analyse_models.ipynb, lines 169 to 259 · score 0.74 · AMRbart, Length sim, Length min, VerbNet CN, RSA matrices, Llama · Report a mismatch
  6. [6] § Methods › fMRI data collection › Experimental task ↔ Code-1-stimuli/2_Prepare_stimuli_PsychoPy.ipynb, lines 49 to 185 · score 0.72 · inter stimulus interval, longer sentences, 7 s, quadratic, 2 s · Report a mismatch
  7. [7] § Methods › Representational similarity analysis › Voxel selection ↔ 5_ROI_correlations.ipynb, lines 135 to 177 · score 0.70 · Glasser atlas, posterior cingulate, ROIs, Dorsolateral, dorsomedial, precuneus · Report a mismatch
  8. [8] § Methods › Representational similarity analysis › Voxel selection ↔ 2_Analyse_fmri.ipynb, lines 613 to 687 · score 0.68 · somatosensory cortex, posterior cingulate, visual cortex, Dorsolateral, dorsomedial, precuneus · Report a mismatch
  9. [9] § Methods › fMRI data collection › GLM model ↔ Code-3-GLMSingle/1_compute_GLMsingle_Fodor2024_nii.py, lines 213 to 220 · score 0.68 · fithrf glmdenoise rr, GLMsingle, Beta · Report a mismatch
  10. [10] § Results › fMRI results ↔ 2_Analyse_fmri.ipynb, lines 790 to 861 · score 0.63 · posterior cingulate, language network, visual cortex, RSA matrices, somatosensory, dorsolateral · Report a mismatch
  11. [11] § Results › Behavioural results ↔ 3_Analyse_behavioural.ipynb, lines 415 to 485 · score 0.62 · split half reliability, Spearman Brown, scores, behavioural, sentence pair · Report a mismatch
  12. [12] § Methods › fMRI data collection › Participants ↔ Code-2-preprocessing/3.1_Extract_motion_data.ipynb, lines 1 to 35 · score 0.53 · head motion, fMRI, framewise · Report a mismatch
  13. [13] § Methods › Searchlight RSA ↔ Code-3-GLMSingle/3_compute_searchlight_RSA.py, lines 61 to 67 · score 0.51 · mne rsa, searchlight, mask, voxels · Report a mismatch
  14. [14] § Methods › Stimuli and computational models › Graph models ↔ 2_Analyse_fmri.ipynb, lines 897 to 993 · score 0.50 · AMR WLK, AMR Smatch, graph, analyse, correlations, models · Report a mismatch

Paper

Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Jupyter notebook · 1,259 lines · 72 KB · Apache-2.0 · 5 matches

  1. # %%
  2. ## Script for analysis of neuroimaging data from Representations of Sentence Meaning in the Brain
  3. # Run with python 3.10 fMRI env
  4. # James Fodor 2024
  5. # load libraries
  6. import numpy as np
  7. import matplotlib.pyplot as plt
  8. import seaborn as sns
  9. import json
  10. import itertools
  11. import pandas as pd
  12. import os
  13. import pickle
  14. from random import choices
  15. from scipy import stats
  16. from scipy.optimize import curve_fit
  17. from sklearn.metrics import r2_score
  18. from sklearn.linear_model import LinearRegression
  19. from scipy.stats import pearsonr
  20. from scipy.stats import spearmanr
  21. from matplotlib.ticker import FormatStrFormatter
  22. from joblib import Parallel, delayed
  23. # load custom functions from library
  24. import voxels_processing as vp
  25. # set display options
  26. np.set_printoptions(precision=3, threshold=6000, linewidth=220, suppress=True, floatmode='fixed')
  27. sns.set()
  28. # %%
  29. import importlib
  30. importlib.reload(vp)
  31. # %% [markdown]
  32. # ### Load stimuli data and similarities
  33. # %%
  34. ## Load sentence stimuli and specify key parameters for analysis
  35. # set key parameters for loading data
  36. dataset_name = 'Fodor2024-final108' # dataset name
  37. repeats = [0,1,2,3] # stimulus repeats to include in analysis
  38. num_sets = 6 # the number of sets of related sentences
  39. timing = 'mid' # start, end, mid
  40. corr_method = 'spearman' # spearman or pearson correlation
  41. similarity_type = 'cosine' # options: 'cosine' or 'diemsim' or 'all'
  42. controls_type = 1 # 1=sentence lengths only, 2=sentence lengths and minimum lengths, 3=visual cortex
  43. accuracy_threshold = 0.73 # minimum accuracy on comprehension questions to include subjects (0.73 is default)
  44. movement_threshold = 4.01 # maximum head movement (mean FD) to include subjects (4.01 is default)
  45. # load sentences set
  46. all_sentences = np.loadtxt(dataset_name+'_sentences.txt', delimiter=';', dtype='str', encoding='utf-8')
  47. all_sentences_indices = np.arange(len(all_sentences))
  48. sent_pairs_all = list(itertools.combinations(all_sentences_indices, 2))
  49. sent_pair_ids_all = np.arange(len(sent_pairs_all))
  50. num_stimuli = all_sentences_indices.shape[0]
  51. sent_pair_ids_diag = vp.get_pairs_in_diag(all_sentences_indices, num_sets)
  52. num_repeats = len(repeats)
  53. # Load sentence pair types
  54. sentpair_types_list = np.loadtxt('Fodor2024-final108_types-brief.txt', dtype=int)
  55. sent_pair_ids_modsub = [idx for idx,type in enumerate(sentpair_types_list) if type==6]
  56. sent_pair_ids_diffs = [idx for idx,type in enumerate(sentpair_types_list) if type==5]
  57. sent_pair_ids_swaps = [idx for idx,type in enumerate(sentpair_types_list) if type==4]
  58. sent_pair_ids_subs = [idx for idx,type in enumerate(sentpair_types_list) if type==3]
  59. sent_pair_ids_mods = [idx for idx,type in enumerate(sentpair_types_list) if type==2]
  60. sent_pair_ids_sames = [idx for idx,type in enumerate(sentpair_types_list) if type==1]
  61. sent_pair_ids_key = [idx for idx,type in enumerate(sentpair_types_list) if type in [2,3,4,5]]
  62. # print summary
  63. print('Stimuli:',num_stimuli)
  64. print('Timing:',timing)
  65. print('Num repeats:',num_repeats)
  66. print('All pairs:',len(sent_pair_ids_all))
  67. print('Diag pairs:',len(sent_pair_ids_diag))
  68. print('Control type:',controls_type)
  69. # %%
  70. ## Load fmri neuro data
  71. # Load metadata for experimental subjects
  72. subject_data_raw = np.loadtxt('Fodor2024-subject_data.txt', delimiter=';', dtype='str', encoding='utf-8', skiprows=1)
  73. subject_data_dict = {sbj_data[0]:(sbj_data[1:]).astype('float') for sbj_data in subject_data_raw}
  74. all_subjects = list(subject_data_dict.keys())
  75. print('Loaded '+str(len(all_subjects))+' experimental subjects')
  76. # Generate list of voxel sets for analysis
  77. voxel_sets = []
  78. for stability_level in ['0.04','0.07']:
  79. voxel_set_dict = vp.get_voxel_set_dict(stability_level)
  80. for voxel_set in voxel_set_dict:
  81. voxel_sets += voxel_set_dict[voxel_set]
  82. voxel_sets = list(set(voxel_sets))
  83. voxel_sets.sort()
  84. default_voxel_set = 'LanROI-all-stable-0.07-norm'
  85. # Specify voxel averaging and voxel subset options (for looping over later)
  86. av_types = ['mean']
  87. pair_subsets = ['all','diag']
  88. other_parms = []
  89. for av_type in av_types:
  90. for pair in pair_subsets:
  91. other_parms.append(av_type+'_'+pair)
  92. # Collect subsets of sentences pairs for similarity analyses
  93. similarity_subsets = {'all':sent_pair_ids_all, 'diag':sent_pair_ids_diag}
  94. print('Voxel sets:',len(voxel_sets))
  95. # Load neuro similarities
  96. fmri_sims_base = 'Data-fmri/similarities/'
  97. neuro_sims_storage = dict(zip(all_subjects, [{type:{} for type in av_types} for x in all_subjects])) # blank empty dictionary for storage
  98. for sbj_id in list(subject_data_dict.keys()):
  99. for av_type in av_types:
  100. for voxel_set in voxel_sets:
  101. neuro_sims_path = fmri_sims_base+timing+'_3s/'+'sub-'+sbj_id+'-sims/'
  102. with open(neuro_sims_path+'sub-'+sbj_id+'_similarities-'+av_type+'-'+voxel_set+'.txt', encoding='latin-1') as file:
  103. neuro_sims_storage[sbj_id][av_type][voxel_set] = np.array([float(line.rstrip('\n')) for line in file])
  104. # Specify which experimental subjects to include
  105. included_subjects = [sbj_id for sbj_id in list(subject_data_dict.keys()) if subject_data_dict[sbj_id][0] >= accuracy_threshold and subject_data_dict[sbj_id][1] <= movement_threshold]
  106. print('Including '+str(len(included_subjects))+' experimental subjects')
  107. # Compute the average similarities over participants and store in dictionary
  108. mean_subj_sims = {type:{} for type in av_types}
  109. for av_type in av_types:
  110. for voxel_set in voxel_sets:
  111. voxelset_sims = [neuro_sims_storage[sbj_id][av_type][voxel_set] for sbj_id in included_subjects]
  112. mean_subj_sims[av_type][voxel_set] = np.mean(voxelset_sims, axis=0)
  113. neuro_sims_storage['mean'] = mean_subj_sims
  114. all_subjects = list(subject_data_dict.keys()) + ['mean'] # include mean subject data
  115. # %%
  116. ## Load model similarities and control variables
  117. # Load model similarities
  118. model_sims_base = 'Data-models/similarities/'
  119. model_sims_storage = vp.load_model_sims(model_sims_base, dataset_name, normalisation=True, sim_type=similarity_type)
  120. model_sims_storage['transformers_norml_'+similarity_type] = np.random.rand(len(sent_pair_ids_all)) # blank entry for averaged transformers so they are in the dictionary
  121. all_models = list(model_sims_storage.keys())
  122. print('Loaded '+str(len(all_models))+' computational models')
  123. # Load control variables
  124. model_sims_storage['visual_sims'] = neuro_sims_storage['mean']['mean']['Glasser-primary_visual-stable-0.07-norm'] # visual similarities control
  125. control_vars = vp.get_control_vars(controls_type, model_sims_storage)
  126. print('Using '+str(controls_type)+' control variables')
  127. # %% [markdown]
  128. # ### Compute all brain-model correlations
  129. # %%
  130. ## Compute model-neuro correlations for all participants and all models
  131. # Specity file locations for saving/loading correlations
  132. neuro_coors_filename = "Data-analysis/"+dataset_name+"_"+timing+"_control-"+str(controls_type)+"_subs-"+str(len(included_subjects))+"_corrs_"+corr_method
  133. neuro_pcoors_filename = "Data-analysis/"+dataset_name+"_"+timing+"_control-"+str(controls_type)+"_subs-"+str(len(included_subjects))+"_pcorrs_"+corr_method
  134. # Load pre-computed correlations if present
  135. try:
  136. with open(neuro_coors_filename+"_simpleav.pickle", "rb") as file:
  137. neuro_corrs_allsubjs = pickle.load(file)
  138. with open(neuro_pcoors_filename+"_simpleav.pickle", "rb") as file:
  139. neuro_pcorrs_allsubjs = pickle.load(file)
  140. # Determine which models are missing computed data
  141. presaved_models = list(neuro_corrs_allsubjs['05']['mean_all'][default_voxel_set].keys())
  142. missing_models = []
  143. for model in model_sims_storage.keys():
  144. if model not in presaved_models:
  145. missing_models.append(model)
  146. print('Missing data for:',missing_models)
  147. # Define new dictionary if files not found
  148. except FileNotFoundError:
  149. missing_models = list(model_sims_storage.keys()) # if no files, all models are missing
  150. neuro_corrs_allsubjs = dict(zip(all_subjects, [{params:{voxel_set:{} for voxel_set in voxel_sets} for params in other_parms} for x in all_subjects]))
  151. neuro_pcorrs_allsubjs = dict(zip(all_subjects, [{params:{voxel_set:{} for voxel_set in voxel_sets} for params in other_parms} for x in all_subjects]))
  152. print('File not found, will create after computing correlations')
  153. # Compute correlations for each set of voxels and each subject only for missing models
  154. if len(missing_models)>0:
  155. for sbj_id in all_subjects: # compute correlations for all subjects, but only INCLUDED subjects are used for averages
  156. for parms in other_parms:
  157. # unpack parameters
  158. av_type,subset = parms.split('_')
  159. sim_subset = similarity_subsets[subset]
  160. # parallel computation of correlations for all voxel sets
  161. results = Parallel(n_jobs=14)(
  162. delayed(vp.calc_neuro_model_correlations)(neuro_sims_storage[sbj_id][av_type][voxel_set], model_sims_storage, control_vars, missing_models, sim_subset, method=corr_method, shuffle=False)
  163. for voxel_set in voxel_sets)
  164. # store results for missing models with all the other loaded models in the dictionary
  165. for idx,voxel_set in enumerate(voxel_sets):
  166. for new_model in list(results[idx][0].keys()):
  167. neuro_corrs_allsubjs[sbj_id][parms][voxel_set][new_model] = results[idx][0][new_model] # store raw correlations
  168. neuro_pcorrs_allsubjs[sbj_id][parms][voxel_set][new_model] = results[idx][1][new_model] # store partial correlations
  169. print('Computed correlations for subject',sbj_id)
  170. # Select which transformer models to average together as per the pre-registration
  171. transformers_to_average = ['ernie_12','amrbart_12','sentbert_mpnet','openai','defsent_cls']
  172. transformer_mean = 'transformers_norml_'+similarity_type
  173. # Compute and store average results for key transformers of interest
  174. for parms in other_parms:
  175. av_type,sim_subset = parms.split('_')
  176. for voxel_set in voxel_sets:
  177. for sbj_id in all_subjects:
  178. transformers_corr = [neuro_corrs_allsubjs[sbj_id][parms][voxel_set][transformer+'_norml_'+similarity_type] for transformer in transformers_to_average]
  179. transformers_pcorr = [neuro_pcorrs_allsubjs[sbj_id][parms][voxel_set][transformer+'_norml_'+similarity_type] for transformer in transformers_to_average]
  180. neuro_corrs_allsubjs[sbj_id][parms][voxel_set][transformer_mean] = np.mean(transformers_corr)
  181. neuro_pcorrs_allsubjs[sbj_id][parms][voxel_set][transformer_mean] = np.mean(transformers_pcorr)
  182. # Save all results
  183. print('Correlations computed for',len(all_subjects),'participants and',len(model_sims_storage.keys()),'models')
  184. print('Control variables:',controls_type)
  185. if len(missing_models)>0:
  186. with open(neuro_coors_filename+"_simpleav.pickle", "wb") as file:
  187. pickle.dump(neuro_corrs_allsubjs, file)
  188. with open(neuro_pcoors_filename+"_simpleav.pickle", "wb") as file:
  189. pickle.dump(neuro_pcorrs_allsubjs, file)
  190. print('Saved',str(len(missing_models)),'new models')
  191. # %%
  192. ## Reorganise individual subject results into new dictionaries for averaging and plotting
  193. # Initialize dictionaries for storing results
  194. neuro_corrs_listsubs = dict(zip(all_models, [{params:{voxel_set:[] for voxel_set in voxel_sets} for params in other_parms} for x in all_models]))
  195. neuro_pcorrs_listsubs = dict(zip(all_models, [{params:{voxel_set:[] for voxel_set in voxel_sets} for params in other_parms} for x in all_models]))
  196. # loop over all smooth types, voxel sets, and subjects to store results in new dictionaries
  197. for model_name in all_models:
  198. for parms in other_parms:
  199. av_type,sim_subset = parms.split('_')
  200. for voxel_set in voxel_sets:
  201. for sbj_id in included_subjects: # only over INCLUDED subjects
  202. neuro_corrs_listsubs[model_name][parms][voxel_set].append(neuro_corrs_allsubjs[sbj_id][parms][voxel_set][model_name])
  203. neuro_pcorrs_listsubs[model_name][parms][voxel_set].append(neuro_pcorrs_allsubjs[sbj_id][parms][voxel_set][model_name])
  204. # error check to make sure number of subjects is correct for each model and voxel set
  205. length_subs = len(neuro_pcorrs_listsubs[model_name][parms][voxel_set])
  206. if length_subs != len(included_subjects):
  207. print('Warning: subjects for model',model_name,'parms',parms,'voxel_set',voxel_set,'is',length_subs,'but should be',len(included_subjects))
  208. print(len(neuro_pcorrs_listsubs[transformer_mean]['mean_all'][default_voxel_set]), 'participants included in average')
  209. # %%
  210. ## Compute model-neuro correlations for all participants and all models
  211. # Prepare parameters for bootstrapping
  212. num_bootstraps = 100
  213. samples_list = np.arange(num_bootstraps)
  214. samples = [choices(included_subjects, k=len(included_subjects)) for k in np.arange(num_bootstraps)]
  215. # Load pre-computed correlations if present
  216. try:
  217. with open(neuro_coors_filename+"_bootstrap.pickle", "rb") as file:
  218. neuro_corrs_bootstraps = pickle.load(file)
  219. with open(neuro_pcoors_filename+"_bootstrap.pickle", "rb") as file:
  220. neuro_pcorrs_bootstraps = pickle.load(file)
  221. # Determine which models are missing computed data
  222. presaved_models = list(neuro_corrs_bootstraps[0]['mean_all'][default_voxel_set].keys())
  223. missing_models = []
  224. for model in model_sims_storage.keys():
  225. if model not in presaved_models:
  226. missing_models.append(model)
  227. print('Missing data for:',missing_models)
  228. # Define new dictionary if files not found
  229. except FileNotFoundError:
  230. missing_models = list(model_sims_storage.keys()) # if no files, all models are missing
  231. neuro_corrs_bootstraps = dict(zip(samples_list, [{params:{voxel_set:{} for voxel_set in voxel_sets} for params in other_parms} for x in samples_list]))
  232. neuro_pcorrs_bootstraps = dict(zip(samples_list, [{params:{voxel_set:{} for voxel_set in voxel_sets} for params in other_parms} for x in samples_list]))
  233. print('File not found, will create after computing correlations')
  234. # Compute correlations for each set of voxels and each subject only for missing models
  235. if len(missing_models)>0:
  236. for num,sample in enumerate(samples): # compute correlations for all subjects, but only INCLUDED subjects are used for averages
  237. for parms in other_parms:
  238. # unpack parameters
  239. av_type,subset = parms.split('_')
  240. sim_subset = similarity_subsets[subset]
  241. # parallel computation of correlations for all voxel sets
  242. results = Parallel(n_jobs=14)(
  243. delayed(vp.calc_neuro_model_correlations)(np.mean([neuro_sims_storage[sbj_id][av_type][voxel_set] for sbj_id in sample], axis=0), model_sims_storage, control_vars, missing_models, sim_subset, method=corr_method, shuffle=False)
  244. for voxel_set in voxel_sets)
  245. # store results for missing models with all the other loaded models in the dictionary
  246. for idx,voxel_set in enumerate(voxel_sets):
  247. for new_model in list(results[idx][0].keys()):
  248. neuro_corrs_bootstraps[num][parms][voxel_set][new_model] = results[idx][0][new_model] # store raw correlations
  249. neuro_pcorrs_bootstraps[num][parms][voxel_set][new_model] = results[idx][1][new_model] # store partial correlations
  250. if (num%10)==0:
  251. print('Computed',num,'out of',num_bootstraps)
  252. # Select which transformer models to average together as per the pre-registration
  253. transformers_to_average = ['ernie_12','amrbart_12','sentbert_mpnet','openai','defsent_cls']
  254. transformer_mean = 'transformers_norml_'+similarity_type
  255. # Compute and store average results for key transformers of interest
  256. for parms in other_parms:
  257. av_type,sim_subset = parms.split('_')
  258. for voxel_set in voxel_sets:
  259. for sample_id in samples_list:
  260. transformers_corr = [neuro_corrs_bootstraps[sample_id][parms][voxel_set][transformer+'_norml_'+similarity_type] for transformer in transformers_to_average]
  261. transformers_pcorr = [neuro_pcorrs_bootstraps[sample_id][parms][voxel_set][transformer+'_norml_'+similarity_type] for transformer in transformers_to_average]
  262. neuro_corrs_bootstraps[sample_id][parms][voxel_set][transformer_mean] = np.mean(transformers_corr)
  263. neuro_pcorrs_bootstraps[sample_id][parms][voxel_set][transformer_mean] = np.mean(transformers_pcorr)
  264. # Save all results
  265. if len(missing_models)>0:
  266. print(num_bootstraps,'bootstraps performed for',len(samples[0]), 'participants')
  267. print('Control variables:',controls_type)
  268. if len(missing_models)>0:
  269. with open(neuro_coors_filename+"_bootstrap.pickle", "wb") as file:
  270. pickle.dump(neuro_corrs_bootstraps, file)
  271. with open(neuro_pcoors_filename+"_bootstrap.pickle", "wb") as file:
  272. pickle.dump(neuro_pcorrs_bootstraps, file)
  273. print('Saved',str(len(missing_models)),'new models')
  274. # %%
  275. ## Reorganise bootstrap results into new dictionaries for averaging and plotting
  276. # Initialize dictionaries for storing results
  277. neuro_corrs_listboots = dict(zip(all_models, [{params:{voxel_set:[] for voxel_set in voxel_sets} for params in other_parms} for x in all_models]))
  278. neuro_pcorrs_listboots = dict(zip(all_models, [{params:{voxel_set:[] for voxel_set in voxel_sets} for params in other_parms} for x in all_models]))
  279. # loop over all smooth types, voxel sets, and subjects to store results in new dictionaries
  280. for model_name in all_models:
  281. for parms in other_parms:
  282. av_type,sim_subset = parms.split('_')
  283. for voxel_set in voxel_sets:
  284. for sample_id in samples_list: # only over INCLUDED subjects
  285. neuro_corrs_listboots[model_name][parms][voxel_set].append(neuro_corrs_bootstraps[sample_id][parms][voxel_set][model_name])
  286. neuro_pcorrs_listboots[model_name][parms][voxel_set].append(neuro_pcorrs_bootstraps[sample_id][parms][voxel_set][model_name])
  287. print(len(neuro_pcorrs_listboots[transformer_mean]['mean_all'][default_voxel_set]), 'bootstrap samples included in average')
  288. # %% [markdown]
  289. # ### Plot results averaged over all subjects
  290. # %%
  291. ## Define model subsets for plotting
  292. models_subset = 1
  293. if models_subset==1: # main models for paper
  294. models_shortnames = ['conceptnet_mean_random','conceptnet_mean','transformers','conceptnet_weights-fixed_struct-low_verbnet','AMR_smatch', 'Prolific']
  295. included_models = vp.get_included_models(model_sims_storage, models_shortnames)
  296. model_names = ['Random', 'Mean-CN', 'Transformer', 'Verbnet-CN', 'AMR-Smatch', 'Human']
  297. width_space = 0.13
  298. fig_width = 13
  299. fig_height = 6
  300. subset_name = 'rsmb'
  301. elif models_subset==2: # all models
  302. models_shortnames = ['random', 'conceptnet_mean', 'conceptnet_mult_mod', 'conceptnet_conv_mod', 'glove', 'infersent', 'transformers', 'ernie_12', 'llama3_32', 'amrbart_12',
  303. 'universal', 'defsent_cls', 'sentbert_mpnet', 'openai', 'S3BERT_global',
  304. 'benepar_subtree', 'CFG_subtree', 'AMR', 'conceptnet_weights-fixed_struct-low_verbnet', 'rated']
  305. included_models = vp.get_included_models(model_sims_storage, models_shortnames)
  306. model_names = ['Random', 'CN-Mean', 'CN-Mult', 'CN-Conv', 'Glove', 'Infersent', 'Transformers', 'Ernie-12', 'Llama3-32', 'AMRBart-12',
  307. 'USE', 'DefSent', 'SentBERT', 'OpenAI', 'S3BERT',
  308. 'Benepar-sub', 'CFG-sub', 'AMR-CN', 'AMR-Smatch', 'AMR-WLK', 'Verbnet-CN', 'GPT4', 'Human']
  309. width_space = 0.06
  310. fig_width = 32
  311. fig_height = 4.4
  312. subset_name = 'fullset'
  313. elif models_subset==3: # hybrid versions
  314. models_shortnames = ['verbnet']
  315. included_models = vp.get_included_models(model_sims_storage, models_shortnames)
  316. model_names = ['CN-equal-low', 'CN-equal-none', 'CN-fixed-low', 'CN-fixed-none', 'CN-STS3k-low', 'CN-STS3k-none', 'DS-equal-low', 'DS-equal-none', 'DS-fixed-low', 'DS-fixed-none', 'DS-STS3k-low', 'DS-STS3k-none']
  317. width_space = 0.09
  318. fig_width = 20
  319. fig_height = 5
  320. subset_name = 'hybrid'
  321. elif models_subset==4: # ernie layers
  322. models_shortnames = ['conceptnet_mean_norml', 'conceptnet_weights-fixed_struct-low_verbnet'] + ['ernie_'+str(i)+'_' for i in range(0,13)]
  323. included_models = vp.get_included_models(model_sims_storage, models_shortnames)
  324. model_names = ['CN', 'VN'] + [''+str(i) for i in range(0,13)]
  325. width_space = 0.11
  326. fig_width = 15
  327. fig_height = 5
  328. subset_name = 'ernie'
  329. elif models_subset==5: # llama 3 layers
  330. models_shortnames = ['conceptnet_mean_norml', 'conceptnet_weights-fixed_struct-low_verbnet'] + ['llama3_'+str(i)+'_' for i in range(0,33)]
  331. included_models = vp.get_included_models(model_sims_storage, models_shortnames)
  332. model_names = ['CN', 'VN'] + [''+str(i) for i in range(0,33)]
  333. width_space = 0.09
  334. fig_width = 19.25
  335. fig_height = 4
  336. subset_name = 'llama'
  337. elif models_subset==6: # amrbart layers
  338. models_shortnames = ['conceptnet_mean_norml', 'conceptnet_weights-fixed_struct-low_verbnet'] + ['amrbart_'+str(i)+'_' for i in range(0,13)]
  339. included_models = vp.get_included_models(model_sims_storage, models_shortnames)
  340. model_names = ['CN', 'VN'] + [''+str(i) for i in range(0,13)]
  341. width_space = 0.11
  342. fig_width = 15
  343. fig_height = 5
  344. subset_name = 'amrbart'
  345. print('Number of included models:',len(included_models))
  346. print('Number of model labels:',len(model_names))
  347. # %%
  348. ## Plot barplot for averaged correlation of similarities
  349. # Select which data to plot
  350. av_type = 'mean' # mean, tstat
  351. voxel_set = 'standard' # standard, extended, stability, lanROIs, cortexROIs
  352. stability_level = '0.07' # 0.04, 0.07, 0.10
  353. show_dots = True # show individual datapoints as dots; if false show error bars instead
  354. control_vars = vp.get_control_vars(controls_type, model_sims_storage)
  355. # Print details
  356. print('Including',len(included_subjects),'participants')
  357. print('Control variables:',controls_type)
  358. print('Stability:',stability_level)
  359. print('Timing:',timing)
  360. print('Similarity type:',similarity_type)
  361. # Specify locations of y-axis ticks
  362. if timing=='end':
  363. y_axes = [[(-0.005,0.305),(-0.205,0.205)],[(-0.005,0.305),(-0.41,0.21)]]
  364. y_ticks = [[np.arange(0.0,0.35,0.05),np.arange(-0.40,0.30,0.05)],[np.arange(0,0.35,0.05),np.arange(-0.40,0.40,0.05)]]
  365. elif timing=='mid':
  366. y_axes = [[(-0.005,0.355),(-0.41,0.41)],[(-0.005,0.355),(-0.43,0.41)]]
  367. y_ticks = [[np.arange(0.0,0.45,0.05),np.arange(-0.50,0.50,0.10)],[np.arange(0,0.45,0.05),np.arange(-0.50,0.50,0.10)]]
  368. # Load location of horizonal p-value signifier bars
  369. with open("Data-analysis/Graph_params.json", "r") as file:
  370. hbar_params = json.load(file)
  371. hbar_height = hbar_params[timing]['controls_'+str(controls_type)]['hbar_height'] # height of bars above axis
  372. hbar_gap = hbar_params[timing]['controls_'+str(controls_type)]['hbar_gap'] # gap between horizontal bars
  373. blue_adjust = hbar_params[timing]['controls_'+str(controls_type)]['blue_adjust'] # adjustments to individual blue bars
  374. green_adjust = hbar_params[timing]['controls_'+str(controls_type)]['green_adjust'] # adjustments to individual green bars
  375. # Set additional graph params
  376. sns.set(font_scale=0.8, style="darkgrid", rc={"grid.linewidth": 0.5})
  377. errorbar_parms = {'elinewidth': 0.9, 'capthick': 0.7}
  378. lwidth = 0.7 # line width
  379. height_gap = 0.5
  380. # Set legend parameters
  381. legend_location = 'upper left'
  382. legend_size = 7
  383. if subset_name=='llama': # needs thinner graph
  384. legend_location = 'upper right'
  385. if subset_name=='fullset': # bigger legend
  386. legend_size = 8.5
  387. # Initialise storage for p-values (* p<0.05/3, ** p<0.01/3, *** p<0.001/3, **** p<0.0001/3)
  388. p_value_storage = {}
  389. # Loop over methods of averaging over participants
  390. for mainplot,method in enumerate(['simple-average','group-average']):
  391. # Create plot and define properties
  392. fig = plt.figure(figsize=(fig_width,fig_height), dpi=600)
  393. print('\n'+method)
  394. # Initialise storage
  395. size=7
  396. p_values_0 = {subset:np.zeros(size,dtype=object) for subset in pair_subsets} # these store the 'randm to mean-CN' comparison
  397. p_values_a = {subset:np.zeros(size,dtype=object) for subset in pair_subsets} # these store the 'mean-CN to transformers' comparison
  398. p_values_b = {subset:np.zeros(size,dtype=object) for subset in pair_subsets} # these store the 'transformers to CN-CN' comparison
  399. p_values_c = {subset:np.zeros(size,dtype=object) for subset in pair_subsets} # these store the 'transformers to CN-CN' comparison
  400. corr_means = {subset:np.zeros(size,dtype=object) for subset in pair_subsets}
  401. corr_stderrs = {subset:np.zeros(size,dtype=object) for subset in pair_subsets}
  402. corr_alldata = {subset:np.zeros(size,dtype=object) for subset in pair_subsets}
  403. # Loop over sentence pair subsets to be plotted
  404. for subplot,subset in enumerate(pair_subsets):
  405. subplot_index = subplot
  406. if subplot in [0,1]:
  407. subplot = subplot
  408. else:
  409. subplot = subplot-2
  410. sim_subset = similarity_subsets[subset]
  411. # Loop over voxel sets to be plotted
  412. for vox_idx,voxels in enumerate(voxel_set_dict[voxel_set]):
  413. if method=='simple-average':
  414. # compute means and standard deviations
  415. corr_alldata[subset][vox_idx] = [neuro_pcorrs_listsubs[included_model][av_type+'_'+subset][voxels] for included_model in included_models] # store data
  416. corr_means[subset][vox_idx] = np.mean(corr_alldata[subset][vox_idx],axis=1)
  417. corr_stdev = np.std(corr_alldata[subset][vox_idx],axis=1)
  418. corr_stderrs[subset][vox_idx] = stats.t.ppf(1-0.025, len(included_subjects))*(corr_stdev/np.sqrt(len(included_subjects)))
  419. print(subset,voxels)
  420. # get p-values for random-mean difference
  421. p_values_0[subset][vox_idx] = stats.ttest_rel(corr_alldata[subset][vox_idx][0], corr_alldata[subset][vox_idx][1]).pvalue
  422. # get p-values for mean-transformer difference
  423. t_test_results = stats.ttest_rel(corr_alldata[subset][vox_idx][2], corr_alldata[subset][vox_idx][1])
  424. p_values_a[subset][vox_idx] = t_test_results.pvalue
  425. mean_diff = np.mean(np.array(corr_alldata[subset][vox_idx][2])-np.array(corr_alldata[subset][vox_idx][1]))
  426. print(' mean/transformer: diff={:.3f}, t={:.3f}, p={:.5f}'.format(mean_diff,t_test_results[0],t_test_results[1]))
  427. # get p-values for transformer-hybrid difference
  428. t_test_results = stats.ttest_rel(corr_alldata[subset][vox_idx][3], corr_alldata[subset][vox_idx][2])
  429. p_values_b[subset][vox_idx] = t_test_results.pvalue
  430. mean_diff = np.mean(np.array(corr_alldata[subset][vox_idx][3])-np.array(corr_alldata[subset][vox_idx][2]))
  431. print(' transformer/hybrid: diff={:.3f}, t={:.3f}, p={:.5f}'.format(mean_diff,t_test_results[0],t_test_results[1]))
  432. # get p-values for transformer-hybrid difference
  433. t_test_results = stats.ttest_rel(corr_alldata[subset][vox_idx][4], corr_alldata[subset][vox_idx][3])
  434. p_values_c[subset][vox_idx] = t_test_results.pvalue
  435. mean_diff = np.mean(np.array(corr_alldata[subset][vox_idx][4])-np.array(corr_alldata[subset][vox_idx][3]))
  436. print(' hybrid/graph: diff={:.3f}, t={:.3f}, p={:.5f}'.format(mean_diff,t_test_results[0],t_test_results[1]))
  437. elif method=='group-average':
  438. # compute means and standard deviations
  439. corr_alldata[subset][vox_idx] = [neuro_pcorrs_listboots[included_model][av_type+'_'+subset][voxels] for included_model in included_models] # store data
  440. if voxels=='Glasser-primary_visual-stable-0.07-norm' and controls_type==3:
  441. adjust_factor = 0.0005 # adjust visual control bars to make them invisible on graph as partial corr doesn't work for perfect multicollinearity
  442. else:
  443. adjust_factor = 1
  444. corr_means[subset][vox_idx] = [adjust_factor*neuro_pcorrs_allsubjs['mean'][av_type+'_'+subset][voxels][included_model] for included_model in included_models]
  445. conf_int = [np.percentile(neuro_pcorrs_listboots[included_model][av_type+'_'+subset][voxels],[2.5,97.5]) for included_model in included_models]
  446. corr_stderrs[subset][vox_idx] = np.ptp(conf_int,axis=1)/2
  447. print(subset,voxels)
  448. # bootstrapping for random-mean difference
  449. diff_data = np.array(corr_alldata[subset][vox_idx][1])-np.array(corr_alldata[subset][vox_idx][0])
  450. t_stat = np.mean(diff_data)/np.std(diff_data)
  451. abs_pvalue = 1-stats.t.cdf(t_stat, len(included_subjects))
  452. p_values_0[subset][vox_idx] = min(abs_pvalue, 1-abs_pvalue) # display correct p-value
  453. # bootstrapping for mean-transformer difference
  454. diff_data = np.array(corr_alldata[subset][vox_idx][2])-np.array(corr_alldata[subset][vox_idx][1])
  455. t_stat = np.mean(diff_data)/np.std(diff_data)
  456. abs_pvalue = 1-stats.t.cdf(t_stat, len(included_subjects))
  457. p_values_a[subset][vox_idx] = min(abs_pvalue, 1-abs_pvalue)
  458. print(' mean/transformer: diff={:.3f}, t={:.3f}, p={:.5f}'.format(np.mean(diff_data),t_stat,p_values_a[subset][vox_idx]))
  459. # bootstrapping for transformer-hybrid difference
  460. diff_data = np.array(corr_alldata[subset][vox_idx][3])-np.array(corr_alldata[subset][vox_idx][2])
  461. t_stat = np.mean(diff_data)/np.std(diff_data)
  462. abs_pvalue = 1-stats.t.cdf(t_stat, len(included_subjects))
  463. p_values_b[subset][vox_idx] = min(abs_pvalue, 1-abs_pvalue)
  464. print(' transformer/hybrid diff: diff={:.3f}, t={:.3f}, p={:.5f}'.format(np.mean(diff_data),t_stat,p_values_b[subset][vox_idx]))
  465. # bootstrapping for hybrid-smatch difference
  466. diff_data = np.array(corr_alldata[subset][vox_idx][4])-np.array(corr_alldata[subset][vox_idx][3])
  467. t_stat = np.mean(diff_data)/np.std(diff_data)
  468. abs_pvalue = 1-stats.t.cdf(t_stat, len(included_subjects))
  469. p_values_c[subset][vox_idx] = min(abs_pvalue, 1-abs_pvalue)
  470. print(' hybrid/graph: diff={:.3f}, t={:.3f}, p={:.5f}'.format(np.mean(diff_data),t_stat,p_values_c[subset][vox_idx]))
  471. # Create subplot
  472. fig_axis = fig.add_subplot(int(str(22)+str(subplot_index+1)))
  473. bar_x_locs = np.arange(len(included_models))
  474. if voxel_set=='standard':
  475. bar_width = 0.35
  476. dot_size = 0.4
  477. errorbar_cap = bar_width*5
  478. fig.subplots_adjust(wspace=width_space, hspace=height_gap)
  479. if show_dots and method=='simple-average':
  480. fig_axis.bar(x=bar_x_locs-1*bar_width/2, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, label='Cortex excl V1-V4')
  481. fig_axis.bar(x=bar_x_locs+1*bar_width/2, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, label='Language network')
  482. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-1*bar_width/2], corr_alldata[subset][0], c='darkslateblue', s=dot_size)
  483. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+1*bar_width/2], corr_alldata[subset][1], c='darkslateblue', s=dot_size)
  484. else:
  485. fig_axis.bar(x=bar_x_locs-1*bar_width/2, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][0], error_kw=errorbar_parms, capsize=errorbar_cap, label='Cortex excl V1-V4')
  486. fig_axis.bar(x=bar_x_locs+1*bar_width/2, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][1], error_kw=errorbar_parms, capsize=errorbar_cap, label='Language network')
  487. plt.legend(loc=legend_location, prop={'size': legend_size})
  488. elif voxel_set=='extended':
  489. bar_width = 0.30
  490. errorbar_cap = bar_width*5
  491. fig.subplots_adjust(wspace=width_space, hspace=height_gap)
  492. if show_dots and method=='simple-average':
  493. fig_axis.bar(x=bar_x_locs-1*bar_width, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, label='Cortex excl V1-V4')
  494. fig_axis.bar(x=bar_x_locs-0*bar_width, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, label='LanExtend')
  495. fig_axis.bar(x=bar_x_locs+1*bar_width, height=corr_means[subset][2], width=bar_width, linewidth=lwidth, label='LanROI')
  496. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-1*bar_width], corr_alldata[subset][0], c='darkslateblue', s=dot_size)
  497. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-0*bar_width], corr_alldata[subset][1], c='darkslateblue', s=dot_size)
  498. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+1*bar_width], corr_alldata[subset][2], c='darkslateblue', s=dot_size)
  499. else:
  500. fig_axis.bar(x=bar_x_locs-1*bar_width, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][0], error_kw=errorbar_parms, capsize=errorbar_cap, label='Cortex excl V1-V4')
  501. fig_axis.bar(x=bar_x_locs-0*bar_width, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][1], error_kw=errorbar_parms, capsize=errorbar_cap, label='LanExtend')
  502. fig_axis.bar(x=bar_x_locs+1*bar_width, height=corr_means[subset][2], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][2], error_kw=errorbar_parms, capsize=errorbar_cap, label='LanROI')
  503. plt.legend(loc=legend_location, prop={'size': legend_size})
  504. elif voxel_set=='stability':
  505. bar_width = 0.20
  506. dot_size = 0.4
  507. errorbar_cap = bar_width*5
  508. fig.subplots_adjust(wspace=width_space, hspace=height_gap)
  509. if show_dots and method=='simple-average':
  510. fig_axis.bar(x=bar_x_locs-3*bar_width/2, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, label='all voxels')
  511. fig_axis.bar(x=bar_x_locs-1*bar_width/2, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, label='stability>0.04')
  512. fig_axis.bar(x=bar_x_locs+1*bar_width/2, height=corr_means[subset][2], width=bar_width, linewidth=lwidth, label='stability>0.07')
  513. fig_axis.bar(x=bar_x_locs+3*bar_width/2, height=corr_means[subset][3], width=bar_width, linewidth=lwidth, label='stability>0.10')
  514. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-3*bar_width/2], corr_alldata[subset][0], c='darkslateblue', s=dot_size)
  515. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-1*bar_width/2], corr_alldata[subset][1], c='darkslateblue', s=dot_size)
  516. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+1*bar_width/2], corr_alldata[subset][2], c='darkslateblue', s=dot_size)
  517. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+3*bar_width/2], corr_alldata[subset][3], c='darkslateblue', s=dot_size)
  518. else:
  519. fig_axis.bar(x=bar_x_locs-3*bar_width/2, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][0], error_kw=errorbar_parms, capsize=errorbar_cap, label='all voxels')
  520. fig_axis.bar(x=bar_x_locs-1*bar_width/2, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][1], error_kw=errorbar_parms, capsize=errorbar_cap, label='stability>0.04')
  521. fig_axis.bar(x=bar_x_locs+1*bar_width/2, height=corr_means[subset][2], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][2], error_kw=errorbar_parms, capsize=errorbar_cap, label='stability>0.07')
  522. fig_axis.bar(x=bar_x_locs+3*bar_width/2, height=corr_means[subset][3], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][3], error_kw=errorbar_parms, capsize=errorbar_cap, label='stability>0.10')
  523. plt.legend(loc=legend_location, prop={'size': legend_size})
  524. elif voxel_set=='lanROIs':
  525. bar_width = 0.15
  526. dot_size = 0.2
  527. errorbar_cap = bar_width*5
  528. fig.subplots_adjust(wspace=width_space, hspace=height_gap)
  529. if show_dots and method=='simple-average':
  530. fig_axis.bar(x=bar_x_locs-5*bar_width/2, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Anterior Temporal')
  531. fig_axis.bar(x=bar_x_locs-3*bar_width/2, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Posterior Temporal')
  532. fig_axis.bar(x=bar_x_locs-1*bar_width/2, height=corr_means[subset][2], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Angular Gyrus')
  533. fig_axis.bar(x=bar_x_locs+1*bar_width/2, height=corr_means[subset][3], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Medial Frontal Gyrus')
  534. fig_axis.bar(x=bar_x_locs+3*bar_width/2, height=corr_means[subset][4], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Inferior Frontal Gyrus')
  535. fig_axis.bar(x=bar_x_locs+5*bar_width/2, height=corr_means[subset][5], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Inferior Frontal Gyrus Orbital')
  536. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-5*bar_width/2], corr_alldata[subset][0], c='darkslateblue', s=dot_size)
  537. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-3*bar_width/2], corr_alldata[subset][1], c='darkslateblue', s=dot_size)
  538. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-1*bar_width/2], corr_alldata[subset][2], c='darkslateblue', s=dot_size)
  539. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+1*bar_width/2], corr_alldata[subset][3], c='darkslateblue', s=dot_size)
  540. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+3*bar_width/2], corr_alldata[subset][4], c='darkslateblue', s=dot_size)
  541. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+5*bar_width/2], corr_alldata[subset][5], c='darkslateblue', s=dot_size)
  542. else:
  543. fig_axis.bar(x=bar_x_locs-5*bar_width/2, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][0], error_kw=errorbar_parms, capsize=errorbar_cap, label='Anterior Temporal')
  544. fig_axis.bar(x=bar_x_locs-3*bar_width/2, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][1], error_kw=errorbar_parms, capsize=errorbar_cap, label='Posterior Temporal')
  545. fig_axis.bar(x=bar_x_locs-1*bar_width/2, height=corr_means[subset][2], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][2], error_kw=errorbar_parms, capsize=errorbar_cap, label='Angular Gyrus')
  546. fig_axis.bar(x=bar_x_locs+1*bar_width/2, height=corr_means[subset][3], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][3], error_kw=errorbar_parms, capsize=errorbar_cap, label='Medial Frontal Gyrus')
  547. fig_axis.bar(x=bar_x_locs+3*bar_width/2, height=corr_means[subset][4], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][4], error_kw=errorbar_parms, capsize=errorbar_cap, label='Inferior Frontal Gyrus')
  548. fig_axis.bar(x=bar_x_locs+5*bar_width/2, height=corr_means[subset][5], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][5], error_kw=errorbar_parms, capsize=errorbar_cap, label='Inferior Frontal Gyrus Orbital')
  549. if method=='simple-average' and subset=='all': # add legend
  550. plt.legend(loc=legend_location, prop={'size': legend_size})
  551. elif voxel_set=='cortexROIs':
  552. bar_width = 0.12
  553. dot_size = 1.6
  554. errorbar_cap = bar_width*5
  555. fig.subplots_adjust(wspace=width_space, hspace=height_gap)
  556. if show_dots and method=='simple-average':
  557. fig_axis.bar(x=bar_x_locs-3*bar_width, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Dorsomedial PFC')
  558. fig_axis.bar(x=bar_x_locs-2*bar_width, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Dorsolateral PFC')
  559. fig_axis.bar(x=bar_x_locs-1*bar_width, height=corr_means[subset][2], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Posterior cingulate')
  560. fig_axis.bar(x=bar_x_locs-0*bar_width, height=corr_means[subset][3], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Precuneus')
  561. fig_axis.bar(x=bar_x_locs+1*bar_width, height=corr_means[subset][4], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Somatosensory cortex')
  562. fig_axis.bar(x=bar_x_locs+2*bar_width, height=corr_means[subset][5], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Visual cortex')
  563. fig_axis.bar(x=bar_x_locs+3*bar_width, height=corr_means[subset][6], width=bar_width, linewidth=lwidth, capsize=errorbar_cap, label='Language network')
  564. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-3*bar_width], corr_alldata[subset][0], c='darkslateblue', s=dot_size, edgecolors='none')
  565. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-2*bar_width], corr_alldata[subset][1], c='darkslateblue', s=dot_size, edgecolors='none')
  566. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-1*bar_width], corr_alldata[subset][2], c='darkslateblue', s=dot_size, edgecolors='none')
  567. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs-0*bar_width], corr_alldata[subset][3], c='darkslateblue', s=dot_size, edgecolors='none')
  568. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+1*bar_width], corr_alldata[subset][4], c='darkslateblue', s=dot_size, edgecolors='none')
  569. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+2*bar_width], corr_alldata[subset][5], c='darkslateblue', s=dot_size, edgecolors='none')
  570. fig_axis.scatter([np.ones(len(included_subjects)) * bar_loc for bar_loc in bar_x_locs+3*bar_width], corr_alldata[subset][6], c='darkslateblue', s=dot_size, edgecolors='none')
  571. else:
  572. fig_axis.bar(x=bar_x_locs-3*bar_width, height=corr_means[subset][0], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][0], error_kw=errorbar_parms, capsize=errorbar_cap, label='Dorsomedial PFC')
  573. fig_axis.bar(x=bar_x_locs-2*bar_width, height=corr_means[subset][1], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][1], error_kw=errorbar_parms, capsize=errorbar_cap, label='Dorsolateral PFC')
  574. fig_axis.bar(x=bar_x_locs-1*bar_width, height=corr_means[subset][2], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][2], error_kw=errorbar_parms, capsize=errorbar_cap, label='Posterior cingulate')
  575. fig_axis.bar(x=bar_x_locs-0*bar_width, height=corr_means[subset][3], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][3], error_kw=errorbar_parms, capsize=errorbar_cap, label='Precuneus')
  576. fig_axis.bar(x=bar_x_locs+1*bar_width, height=corr_means[subset][4], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][4], error_kw=errorbar_parms, capsize=errorbar_cap, label='Somatosensory cortex')
  577. fig_axis.bar(x=bar_x_locs+2*bar_width, height=corr_means[subset][5], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][5], error_kw=errorbar_parms, capsize=errorbar_cap, label='Visual cortex')
  578. fig_axis.bar(x=bar_x_locs+3*bar_width, height=corr_means[subset][6], width=bar_width, linewidth=lwidth, yerr=corr_stderrs[subset][6], error_kw=errorbar_parms, capsize=errorbar_cap, label='Language network')
  579. if method=='simple-average' and subset=='all': # add legend
  580. plt.legend(loc=legend_location, prop={'size': legend_size})
  581. if len(included_models) <= 6 and len(voxel_set_dict[voxel_set]) < 3: # only include horizonal p-value lines if we're plotting the smaller subset of models
  582. # plot the blue lines
  583. base_height = np.array(corr_means[subset][0])+hbar_height[mainplot][subplot]
  584. vp.barplot_annotate_brackets(1, 2, p_values_a[subset][0], bar_x_locs-bar_width/2, base_height+blue_adjust[mainplot][subplot][0], colour='#4c72b0', ymax=y_axes[mainplot][subplot][1], multi_test=3, fs=8, width=0.8)
  585. vp.barplot_annotate_brackets(2, 3, p_values_b[subset][0], bar_x_locs-bar_width/2, base_height+blue_adjust[mainplot][subplot][1], colour='#4c72b0', ymax=y_axes[mainplot][subplot][1], multi_test=3, fs=8, width=0.8)
  586. vp.barplot_annotate_brackets(3, 4, p_values_c[subset][0], bar_x_locs-bar_width/2, base_height+blue_adjust[mainplot][subplot][2], colour='#4c72b0', ymax=y_axes[mainplot][subplot][1], multi_test=3, fs=8, width=0.8)
  587. # plot the green lines
  588. base_height = np.array(corr_means[subset][1])+hbar_gap[mainplot][subplot]
  589. vp.barplot_annotate_brackets(1, 2, p_values_a[subset][1], bar_x_locs+bar_width/2, base_height+hbar_height[mainplot][subplot]+green_adjust[mainplot][subplot][0], colour='#dd8452', ymax=y_axes[mainplot][subplot][1], multi_test=3, fs=8, width=0.8)
  590. vp.barplot_annotate_brackets(2, 3, p_values_b[subset][1], bar_x_locs+bar_width/2, base_height+hbar_height[mainplot][subplot]+green_adjust[mainplot][subplot][1], colour='#dd8452', ymax=y_axes[mainplot][subplot][1], multi_test=3, fs=8, width=0.8)
  591. vp.barplot_annotate_brackets(3, 4, p_values_c[subset][1], bar_x_locs+bar_width/2, base_height+hbar_height[mainplot][subplot]+green_adjust[mainplot][subplot][2], colour='#dd8452', ymax=y_axes[mainplot][subplot][1], multi_test=3, fs=8, width=0.8)
  592. # Add labels
  593. plt.title('fMRI '+method+' '+subset+' pairs (n='+str(len(included_subjects))+')')
  594. # Specify axis labels
  595. fig_axis.set_ylabel(corr_method+' correlation')
  596. fig_axis.set_xticks(np.arange(len(included_models)), model_names)
  597. fig_axis.tick_params(axis='both',pad=-1) # set distance between ticks and tick labels
  598. fig_axis.set_yticks(y_ticks[mainplot][subplot])
  599. fig_axis.set_ylim(y_axes[mainplot][subplot])
  600. fig_axis.yaxis.set_major_formatter(FormatStrFormatter('%.2f')) # always show two decimal places
  601. # needs some adjustments to fit all models in
  602. if subset_name in ['fullset','hybrid']:
  603. fig_axis.tick_params(axis='x', labelrotation=35)
  604. fig_axis.set_xlim(-1, len(included_models))
  605. # Store p-values
  606. p_value_storage[method] = (p_values_a,p_values_b,p_values_c)
  607. # Save figure
  608. figure_name = 'Figures\\Fodor2024-'+timing+'_control-'+str(controls_type)+'_subs-'+str(len(included_subjects))+'_models-'+subset_name+'_voxels-'+voxel_set+'_type-'+method+'_corr-'+corr_method+'_sims-'+similarity_type+'.png'
  609. plt.savefig(figure_name, bbox_inches='tight')
  610. plt.show()
  611. # %% [markdown]
  612. # ### Table of all results
  613. # %%
  614. ## Prepare results for printing
  615. # Subject and models to show results
  616. bootstrap = True
  617. pair_set = 'all' #diag, all
  618. # Print initial lines
  619. print('Bootstrapping:',bootstrap)
  620. print('Correlation type:',corr_method)
  621. print('Control variables:',controls_type)
  622. print('Type:',pair_set,'with',corr_method,'correlation')
  623. # Loop over all smooth types, all model names, and all voxel sets
  624. # Note: partical_corr function ignores control variables when they are perfectly correlated with the dependent variable, hence the high correlations shown below for 'sent_min' and 'length_diff'
  625. data_store = {parm:[] for parm in other_parms} # initialise empty dict
  626. for parms in other_parms:
  627. for model in included_models:
  628. new_row = []
  629. for voxel_set in voxel_sets:
  630. if bootstrap: # show data for group-averaged mean bootstrapped over subjects
  631. corr_mean = neuro_pcorrs_allsubjs['mean'][parms][voxel_set][model]
  632. conf_int = np.percentile(neuro_pcorrs_listboots[model][parms][voxel_set],[2.5,97.5])
  633. new_row.append(corr_mean)
  634. else: # show data averaged over individual subjects
  635. new_row.append(neuro_pcorrs_listsubs[model][parms][voxel_set])
  636. data_store[parms].append(new_row)
  637. data_store = {parm:np.array(data_store[parm]) for parm in other_parms}
  638. print('Shape:',data_store[parms].shape)
  639. # %%
  640. ## Table displaying all results
  641. # Apply the function to wrap the column headers
  642. data_store_pd = pd.DataFrame(data_store['mean_'+pair_set], index=included_models, columns=voxel_sets)
  643. data_selected_pd = data_store_pd.loc[:, np.array(voxel_set_dict['cortexROIs'])]
  644. # Display styled pandas df
  645. df_styled = data_selected_pd.style.format("{:.4f}").set_properties(**{'width': '100px'})
  646. df_styled
  647. # %% [markdown]
  648. # ### Additional plots
  649. # %%
  650. ## Select what to plot
  651. subject = 'mean'
  652. parms = 'mean_all'
  653. stability_level = '0.07'
  654. voxel_set = 'cortexROIs'
  655. # %%
  656. ## Print histogram of neuro similarities
  657. # Specify voxel sets to plot
  658. voxel_sets_for_plot = voxel_set_dict[voxel_set]
  659. voxel_sets_names = ['dorsomedial PFC', 'dorsolateral PFC', 'posterior cingulate','precuneus', 'primary sensory', 'primary visual', 'lanROI']
  660. # Define plot
  661. fig = plt.figure(figsize=(10,4), facecolor='white', dpi=150)
  662. fig.subplots_adjust(wspace=0.3, hspace=0.3)
  663. sns.set(font_scale=0.7)
  664. # Generate subplots
  665. for subplot in np.arange(len(voxel_sets_for_plot)):
  666. plot_num = int(str(24)+str(subplot+1))
  667. fig_axis = fig.add_subplot(plot_num)
  668. fig_axis.hist(neuro_sims_storage[subject][av_type][voxel_sets_for_plot[subplot]], bins=30)
  669. fig_axis.set(xlabel=voxel_sets_names[subplot])
  670. fig_axis.set_xlim(-0.3,0.3)
  671. # plt.savefig('Data\\'+dataset_name+'-GLMSbetas_sub-'+str(subject)+'_similarities.png', bbox_inches='tight')
  672. plt.show()
  673. # %%
  674. ## Plot RSA matrices after regressing out control variables
  675. # Choose what to plot
  676. control_var_sets = [1,2,3]
  677. normalise_sims = True
  678. group_norm = 1 # normalise sims across the whole set of voxel subsets
  679. voxel_sets_for_plot = voxel_set_dict[voxel_set]
  680. voxel_sets_names = ['Dorsomedial PFC', 'Dorsolateral PFC', 'Posterior cingulate','Precuneus', 'Somatosensory','Visual cortex','Language network']
  681. # Storage for all resids
  682. combined_sims_resids_dict = {}
  683. combined_names = []
  684. # Loop over all sets of control variables to compute and store resids
  685. for graph_control in control_var_sets:
  686. # Choose controls to use
  687. control_vars = vp.get_control_vars(graph_control, model_sims_storage)
  688. # Regress out control variables from neuro sims
  689. neuro_sims_resids = {voxels:[] for voxels in voxel_sets_for_plot} # create storage dict
  690. for sub_id in included_subjects:
  691. neuro_sims_resid, _ = vp.regress_out_controls(neuro_sims_storage[subject][av_type], control_vars)
  692. [neuro_sims_resids[voxels].append(neuro_sims_resid[voxels]) for voxels in voxel_sets_for_plot]
  693. neuro_sims_resids_mean = {voxels:np.mean(neuro_sims_resids[voxels],axis=0) for voxels in voxel_sets_for_plot} # average over subjects
  694. # Store resids in dictionary
  695. for idx,voxels in enumerate(voxel_sets_for_plot):
  696. combined_sims_resids_dict[voxels+'_'+str(graph_control)] = neuro_sims_resids_mean[voxels]
  697. combined_names.append(voxel_sets_names[idx]) #+'_'+str(graph_control))
  698. # Normalisation here adjusts the scale for plotting; doesn't affect correlations
  699. if normalise_sims == True:
  700. percentile_vis_cutoff = 1
  701. if subject=='mean':
  702. neuro_sims_storage_norml = vp.normalise_similarities(combined_sims_resids_dict, percentile_vis_cutoff, group_norm)
  703. else:
  704. neuro_sims_storage_norml = vp.normalise_similarities(neuro_sims_storage[subject][av_type], percentile_vis_cutoff, group_norm)
  705. min_sim = 0
  706. max_sim = 1
  707. elif normalise_sims == False: # no normalisation condition
  708. neuro_sims_storage_norml = combined_sims_resids_dict
  709. min_sim =-0.2
  710. max_sim = 0.3
  711. # Define plot
  712. fig = plt.figure(figsize=(17,4.05*len(control_var_sets)), dpi=680)
  713. fig.subplots_adjust(wspace=-0.57, hspace=0.09)
  714. sns.set(font_scale=0.8)
  715. # Generate subplots
  716. corr_matrices = []
  717. for idx,voxels in enumerate(combined_sims_resids_dict.keys()):
  718. plot_num = (2*len(control_var_sets),len(voxel_sets_for_plot),idx+1)
  719. corr_matrix = vp.mask_based_utri2mat(neuro_sims_storage_norml[voxels][sent_pair_ids_all], 108)
  720. corr_matrices.append(corr_matrix)
  721. if (idx+1)%len(voxel_sets_for_plot)==0:
  722. show_colorbar=True
  723. else:
  724. show_colorbar=False
  725. if idx<len(voxel_sets_for_plot):
  726. vp.add_heatmap_subplot(fig, plot_num, corr_matrix, '', '', combined_names[idx], colorbar=show_colorbar, min=min_sim, max=max_sim)
  727. else:
  728. vp.add_heatmap_subplot(fig, plot_num, corr_matrix, '', '', '', colorbar=show_colorbar, min=min_sim, max=max_sim)
  729. # np.savetxt('Data\\'+dataset_name+'-GLMSbetas_sub-'+str(subject)+'_RSA-'+voxels+'.txt', corr_matrices[0], fmt='%.4f')
  730. # Save results
  731. figure_name = 'Figures\\Fodor2024-'+timing+'_control-'+str('all')+'_subs-'+str(len(included_subjects))+'_sims-'+similarity_type+'groupnorm-'+str(group_norm)+'_RSAs.png'
  732. # plt.savefig(figure_name, bbox_inches='tight')
  733. plt.show()
  734. # %% [markdown]
  735. # ### Scatterplots
  736. # %%
  737. ## Plot scatterplots with different voxel sets
  738. # Select what to plot
  739. send_pairs_to_plot = sent_pair_ids_diag # subsets: sent_pair_ids_all, sent_pair_ids_diag
  740. model_to_plot = 'parse-GPT4_embed-conceptnet_weights-fixed_struct-low_verbnet'
  741. # Choose controls to use
  742. graph_control=2
  743. control_vars = vp.get_control_vars(graph_control, model_sims_storage)
  744. # Normalise similarities
  745. model_sims_resid, _ = vp.regress_out_controls(model_sims_storage, control_vars)
  746. model_sims_storage_norml = vp.normalise_similarities(model_sims_resid, 0)
  747. neuro_sims_resid, _ = vp.regress_out_controls(neuro_sims_storage[subject]['mean'], control_vars)
  748. neuro_sims_storage_norml = vp.normalise_similarities(neuro_sims_resid, 0)
  749. # Generate figure
  750. fig = plt.figure(figsize=(14,4), facecolor='white', dpi=150)
  751. fig.subplots_adjust(wspace=0.3, hspace=0.2)
  752. sns.set(font_scale=0.7) # set font size for labels
  753. # Loop over voxel sets and generate subplots
  754. for i,voxels in enumerate(voxel_sets_for_plot):
  755. xs = model_sims_storage_norml[model_to_plot][send_pairs_to_plot]
  756. ys = np.array(neuro_sims_storage_norml[voxels])[send_pairs_to_plot]
  757. plot_num = (2,5,i+1)
  758. colours = 'b' # just use a default colour
  759. vp.add_scatterplot_subplot(fig, xs, ys, colours, plot_num, subject, voxel_sets_names[i], x_min=0, y_min=0, y_max=1, size=1.2)
  760. plt.show()
  761. # %%
  762. ## Plot scatterplots versus models
  763. # Select what to plot and parameters
  764. model_set = 'fullset'
  765. if model_set=='rsmb':
  766. models_shortnames = ['conceptnet_mean_norml','openai','conceptnet_weights-fixed_struct-low_verbnet','AMR_smatch']
  767. included_models = vp.get_included_models(model_sims_storage, models_shortnames)
  768. model_names = ['Mean-CN', 'OpenAI', 'Verbnet-CN', 'AMR-Smatch']
  769. num_per_row = 4
  770. fig_width = 7
  771. elif model_set=='fullset':
  772. models_shortnames = ['random', 'conceptnet_mean_norml', 'conceptnet_mult_mod', 'conceptnet_conv_mod', 'glove', 'infersent',
  773. 'ernie_12', 'llama3_32', 'amrbart_12', 'universal', 'defsent_cls', 'sentbert_mpnet', 'openai',
  774. 'S3BERT_global', 'benepar_subtree', 'CFG_subtree', 'AMR', 'conceptnet_weights-fixed_struct-low_verbnet', 'rated']
  775. included_models = vp.get_included_models(model_sims_storage, models_shortnames)
  776. model_names = ['Random', 'CN-Mean', 'CN-Mult', 'CN-Conv', 'Glove', 'Infersent',
  777. 'Ernie-12', 'Llama3-32', 'AMRBart-12', 'USE', 'DefSent', 'SentBERT', 'OpenAI',
  778. 'S3BERT', 'Benepar-sub', 'CFG-sub', 'AMR-CN', 'AMR-Smatch', 'AMR-WLK', 'Verbnet-CN', 'GPT4', 'Human']
  779. num_per_row = 6
  780. fig_width = 10.5
  781. sent_pairs_to_plot = np.intersect1d(sent_pair_ids_all,sent_pair_ids_all) # subsets: sent_pair_ids_all, sent_pair_ids_diag
  782. sent_pairs_for_line = np.intersect1d(sent_pair_ids_all,sent_pair_ids_diag)
  783. stability_level = '0.07'
  784. voxel_set = 'LanROI-all-stable-'+stability_level+'-norm'
  785. # Choose controls to use
  786. graph_control = 3
  787. control_vars = vp.get_control_vars(graph_control, model_sims_storage)
  788. # Print description
  789. print('Results for control='+str(graph_control)+' and '+str(len(sent_pairs_to_plot))+' sent pairs')
  790. # Prepare colors for type categories
  791. type_colors = ['red', 'darkblue', 'blue','royalblue', 'deepskyblue', 'mediumseagreen', 'darkgreen']
  792. type_labels = ['', 'Same', 'Modified', 'Substituted', 'Modified & Subs', 'Swapped', 'Different']
  793. # Normalise data for plotting
  794. model_sims_storage_norml = vp.normalise_similarities(model_sims_storage, 0)
  795. neuro_sims_resid, _ = vp.regress_out_controls(neuro_sims_storage['mean']['mean'], control_vars)
  796. neuro_sims_storage_norml = vp.normalise_similarities(neuro_sims_resid, 0.1)
  797. # Produce figure
  798. fig = plt.figure(figsize=(fig_width,4.2*len(included_models)), facecolor='white', dpi=700)
  799. fig.subplots_adjust(wspace=0.15, hspace=0.4)
  800. dot_size = 1.2
  801. sns.set(font_scale=0.6, rc={"grid.linewidth": 0.5}) # set font size for labels
  802. for i,model in enumerate(included_models):
  803. # Add a single scatterplot subplot
  804. plot_num = (2*len(included_models),num_per_row,i+1)
  805. fig_axis = fig.add_subplot(*plot_num)
  806. fig_axis.set_title(model_names[i], pad=4)
  807. fig_axis.set_xlim(0,1)
  808. fig_axis.set_xticks(np.arange(0,1.01,0.2))
  809. fig_axis.set_ylim(0,1)
  810. fig_axis.tick_params(axis='both', which='major', pad=-2, labelsize=6)
  811. if i%num_per_row==0: # for the every fourth only
  812. fig_axis.set(ylabel='neuro sims', xlabel='model sims')
  813. else: # for all other subplots
  814. fig_axis.set(xlabel='model sims')
  815. fig_axis.set_yticklabels([])
  816. # Add jitters to model data
  817. jit_size = 0.02
  818. jitters = np.random.uniform(-jit_size, jit_size, len(sent_pair_ids_all))
  819. model_sims_norml_jittered = ((model_sims_storage_norml[model]+jitters)+jit_size)/(1+2*jit_size) # renormalise after jitter
  820. # Plot data
  821. ys = np.array(neuro_sims_storage_norml[voxel_set])[sent_pairs_to_plot].reshape(-1, 1)
  822. xs = model_sims_norml_jittered[sent_pairs_to_plot].reshape(-1, 1)
  823. colours = [type_colors[v] for v in sentpair_types_list[sent_pairs_to_plot]]
  824. fig_axis.scatter(xs, ys, c=colours, marker='o', s=dot_size, edgecolor='none')
  825. # Add regression line and diagonal line
  826. xs_raw = model_sims_storage_norml[model][sent_pairs_for_line].reshape(-1, 1)
  827. ys_raw = np.array(neuro_sims_storage_norml[voxel_set])[sent_pairs_for_line].reshape(-1, 1)
  828. OLS_reg = LinearRegression(fit_intercept=True).fit(xs_raw, ys_raw)
  829. reg_scorr = spearmanr(ys_raw.reshape(-1), xs_raw.reshape(-1))[0]
  830. reg_pcorr = pearsonr(ys_raw.reshape(-1), xs_raw.reshape(-1))[0]
  831. plot_xs = np.arange(0,1,0.001).reshape(-1, 1)
  832. pred_ys = OLS_reg.predict(plot_xs)
  833. plt.plot(plot_xs, pred_ys, color='red', linewidth=0.7) # add reg line
  834. # Print correlations
  835. # plt.text(0.03, 0.90, 'Corr: {:.3f}'.format(reg_scorr))
  836. print(model+' spearman: {:.3f}'.format(spearmanr(ys_raw.reshape(-1), xs_raw.reshape(-1))[0]))
  837. print(model+' pearson: {:.3f}'.format(pearsonr(ys_raw.reshape(-1), xs_raw.reshape(-1))[0]))
  838. # Add legend
  839. legend_elements = [plt.Line2D([0], [0], marker='o', color='w', label=label, markerfacecolor=color, markersize=10)
  840. for color, label in zip(type_colors[1:], type_labels[1:])]
  841. plt.legend(handles=legend_elements, title='Pair types', bbox_to_anchor=(1.1,1))
  842. # Save and display results
  843. plt.savefig('Figures\\Fodor2024-'+timing+'_control-'+str(graph_control)+'_subs-'+str(len(included_subjects))+'_models-'+model_set+'_sims-'+similarity_type+'_scatterplots.png', bbox_inches='tight')
  844. plt.show()
  845. # %% [markdown]
  846. # ### Subject-wise results
  847. # %%
  848. ## Show specified correlations for each subject
  849. # Specify parameters
  850. parms = 'mean_all'
  851. voxel_set = 'LanROI-all-stable-'+stability_level+'-norm'
  852. model_name = 'parse-GPT4_embed-conceptnet_weights-fixed_struct-low_verbnet'
  853. model_label = 'Verbnet-CN'
  854. # Prepare subject data
  855. subject_corrs = []
  856. noneng_subject_corrs = []
  857. eng_subject_corrs = []
  858. noneng_subjects = ['06','07','14','16','21','23','31','34','36','38','39','40','43'] # participant ID from non-English majority countries
  859. eng_subjects = [idx for idx in all_subjects if idx not in noneng_subjects]
  860. for sbj_id in all_subjects:
  861. if sbj_id in included_subjects:
  862. subject_corrs.append(neuro_pcorrs_allsubjs[sbj_id][parms][voxel_set][model_name])
  863. for sbj_id in noneng_subjects:
  864. if sbj_id in included_subjects:
  865. noneng_subject_corrs.append(neuro_pcorrs_allsubjs[sbj_id][parms][voxel_set][model_name])
  866. for sbj_id in eng_subjects:
  867. if sbj_id in included_subjects:
  868. eng_subject_corrs.append(neuro_pcorrs_allsubjs[sbj_id][parms][voxel_set][model_name])
  869. print('Average corr all: {:.3}'.format(np.mean(subject_corrs)))
  870. print('Average corr noneng: {:.3}'.format(np.mean(noneng_subject_corrs)))
  871. print('Average corr eng: {:.3}'.format(np.mean(eng_subject_corrs)))
  872. # Generate plot
  873. sns.set(font_scale=1.1)
  874. fig = plt.figure(figsize=(25,3))
  875. plt.bar(x=np.arange(len(included_subjects)), height=subject_corrs, width=0.5, capsize=2)
  876. plt.xticks(np.arange(len(included_subjects)), included_subjects)
  877. plt.ylabel(model_label+' correlation')
  878. plt.xlabel('subject ID')
  879. plt.show()
  880. # Perform t-test for eng and noneng participants
  881. test_output = stats.ttest_ind(noneng_subject_corrs, eng_subject_corrs, equal_var=False)
  882. print(test_output)
  883. # %%
  884. ## Plot barplot for averaged correlation of similarities
  885. # Select which data to plot
  886. av_type = 'mean' # mean, tstat
  887. plot_type = 'by_stability' #by_subset, by_stability
  888. voxel_sets_for_plot = voxel_set_dict['cortexROIs']
  889. voxel_sets_names = ['Dorsomedial PFC', 'Dorsolateral PFC', 'Posterior cingulate','Precuneus', 'Somatosensory','Visual cortex','Language network']
  890. stabilities = ['','-stable-0.04','-stable-0.07','-stable-0.1']
  891. # Choose controls to use
  892. graph_control=3
  893. control_vars = vp.get_control_vars(graph_control, model_sims_storage)
  894. # Create plot and define properties
  895. sns.set(font_scale=0.8, style="darkgrid", rc={"grid.linewidth": 0.5})
  896. errorbar_parms = {'elinewidth': 0.9, 'capthick': 0.7}
  897. fig = plt.figure(figsize=(3.8*len(voxel_sets_for_plot),7), dpi=600)
  898. # Print description
  899. print('Results for control='+str(graph_control)+' and '+str(len(sent_pairs_to_plot))+' sent pairs')
  900. # Version where we arrange by pair subset
  901. if plot_type == 'by_subset':
  902. # Set fixed params
  903. stability_level = '0.07'
  904. bar_width = 0.30
  905. # Load data
  906. participant_data = {key:neuro_sims_storage[key][av_type]['LanROI-all-stable-'+stability_level+'-norm'] for key in all_subjects}
  907. # Initialise storage
  908. corrs_all = {subset:np.zeros(len(voxel_sets_for_plot),dtype=object) for subset in pair_subsets}
  909. corrs_mean = {subset:np.zeros(len(voxel_sets_for_plot),dtype=object) for subset in pair_subsets}
  910. # Loop over subsets to be plotted
  911. for subplot,subset in enumerate(pair_subsets):
  912. sim_subset = similarity_subsets[subset]
  913. # Loop over voxel sets to be plotted
  914. for vox_idx,voxels in enumerate(voxel_sets_for_plot):
  915. # get correlations of all participants RSA with the group-averaged-less-one RSA
  916. corrs_with_mean_less_one_dict = {}
  917. for sbj_id in list(participant_data.keys()):
  918. mean_less_one = np.mean([neuro_sims_storage[sbj][av_type][voxels] for sbj in participant_data.keys() if sbj not in [sbj_id,'mean']],axis=0)
  919. corrs_with_mean_less_one_dict[sbj_id] = list(vp.calc_neuro_model_correlations(mean_less_one, participant_data, control_vars, [sbj_id], sim_subset, method=corr_method, shuffle=False)[2].values())[0][1]
  920. corrs_with_mean_list = [corrs_with_mean_less_one_dict[sbj] for sbj in included_subjects]
  921. corrs_all[subset][vox_idx] = np.array(corrs_with_mean_list) # data for all participants
  922. corrs_mean[subset][vox_idx] = np.mean(corrs_with_mean_list) # average over participants
  923. # Create subplot
  924. fig_axis = fig.add_subplot(int(str(22)+str(subplot+1)))
  925. bar_x_locs = np.arange(len(corrs_all[subset]))
  926. fig_axis.bar(x=bar_x_locs-bar_width/2, linewidth=0.7, height=corrs_mean[pair_subsets[0]], width=bar_width, label='All sentence pairs')
  927. fig_axis.bar(x=bar_x_locs+bar_width/2, linewidth=0.7, height=corrs_mean[pair_subsets[1]], width=bar_width, label='Diag sentence pairs')
  928. for idx,_ in enumerate(voxel_sets_for_plot):
  929. fig_axis.scatter([np.ones(len(corrs_with_mean_list)) * bar_loc for bar_loc in bar_x_locs-bar_width/2][idx], corrs_all[pair_subsets[0]][idx], c='darkslateblue', s=1)
  930. fig_axis.scatter([np.ones(len(corrs_with_mean_list)) * bar_loc for bar_loc in bar_x_locs+bar_width/2][idx], corrs_all[pair_subsets[1]][idx], c='darkslateblue', s=1)
  931. fig_axis.set_xticks(np.arange(len(corrs_all['all'])), voxel_sets_names)
  932. # Version where we arrange by stability threshold
  933. elif plot_type == 'by_stability':
  934. # Set fixed params
  935. subset = 'all'
  936. bar_width = 0.20
  937. sim_subset = similarity_subsets[subset]
  938. # Initialise storage
  939. corrs_all = {subset:np.zeros(len(voxel_sets_for_plot),dtype=object) for subset in stabilities}
  940. corrs_mean = {subset:np.zeros(len(voxel_sets_for_plot),dtype=object) for subset in stabilities}
  941. # Loop over all stability scores
  942. for subplot,stability in enumerate(stabilities):
  943. # Load data
  944. participant_data = {key:neuro_sims_storage[key][av_type]['Glasser-cortex_novis'+stability+'-norm'] for key in all_subjects}
  945. # Loop over voxel sets to be plotted
  946. for vox_idx,voxels in enumerate(voxel_sets_for_plot):
  947. # get correlations of all participants RSA with the group-averaged-less-one RSA
  948. corrs_with_mean_less_one_dict = {}
  949. for sbj_id in list(participant_data.keys()):
  950. mean_less_one = np.mean([neuro_sims_storage[sbj][av_type][voxels] for sbj in participant_data.keys() if sbj not in [sbj_id,'mean']],axis=0)
  951. corrs_with_mean_less_one_dict[sbj_id] = vp.calc_neuro_model_correlations(mean_less_one, participant_data, control_vars, [sbj_id], sim_subset, method=corr_method, shuffle=False)[1][sbj_id]
  952. corrs_with_mean_list = [corrs_with_mean_less_one_dict[sbj] for sbj in included_subjects]
  953. corrs_mean[stability][vox_idx] = np.mean(corrs_with_mean_list) # average over participants
  954. corrs_all[stability][vox_idx] = np.array(corrs_with_mean_list) # data for all participants
  955. # Create subplot
  956. fig_axis = fig.add_subplot(int(str(22)+str(subplot+1)))
  957. bar_x_locs = np.arange(len(corrs_all[stability]))
  958. fig_axis.bar(x=bar_x_locs-(3/2)*bar_width, linewidth=0.7, height=corrs_mean[stabilities[0]], width=bar_width, label='all voxels')
  959. fig_axis.bar(x=bar_x_locs-(1/2)*bar_width, linewidth=0.7, height=corrs_mean[stabilities[1]], width=bar_width, label='stability>0.04')
  960. fig_axis.bar(x=bar_x_locs+(1/2)*bar_width, linewidth=0.7, height=corrs_mean[stabilities[2]], width=bar_width, label='stability>0.07')
  961. fig_axis.bar(x=bar_x_locs+(3/2)*bar_width, linewidth=0.7, height=corrs_mean[stabilities[3]], width=bar_width, label='stability>0.10')
  962. for idx,_ in enumerate(voxel_sets_for_plot):
  963. fig_axis.scatter([np.ones(len(corrs_with_mean_list)) * bar_loc for bar_loc in bar_x_locs-(3/2)*bar_width][idx], corrs_all[stabilities[0]][idx], c='darkslateblue', s=1)
  964. fig_axis.scatter([np.ones(len(corrs_with_mean_list)) * bar_loc for bar_loc in bar_x_locs-(1/2)*bar_width][idx], corrs_all[stabilities[1]][idx], c='darkslateblue', s=1)
  965. fig_axis.scatter([np.ones(len(corrs_with_mean_list)) * bar_loc for bar_loc in bar_x_locs+(1/2)*bar_width][idx], corrs_all[stabilities[2]][idx], c='darkslateblue', s=1)
  966. fig_axis.scatter([np.ones(len(corrs_with_mean_list)) * bar_loc for bar_loc in bar_x_locs+(3/2)*bar_width][idx], corrs_all[stabilities[3]][idx], c='darkslateblue', s=1)
  967. fig_axis.set_xticks(np.arange(len(corrs_all[stability])), voxel_sets_names)
  968. # Add labels
  969. plt.title('Individual correlations with group-average brain RSA (n='+str(len(included_subjects))+')')
  970. plt.legend(loc='upper left')
  971. print('Corrs all:',corrs_mean[''])
  972. # Specify axis labels
  973. fig_axis.set_ylabel(corr_method+' correlation')
  974. fig_axis.set_yticks(np.arange(0,0.81,0.1))
  975. fig_axis.set_ylim(0,0.81)
  976. fig_axis.tick_params(axis='both',pad=-1.3) # set distance between ticks and tick labels
  977. # Save figure
  978. figure_name = 'Figures\\Fodor2024-'+timing+'_control-'+str(graph_control)+'_subs-'+str(len(included_subjects))+'_group_corr.png'
  979. plt.savefig(figure_name, bbox_inches='tight')
  980. plt.show()
  981. # %%
  982. ## Compute pairwise correlations between subjects
  983. # compute correlations for each participant
  984. np.seterr(divide='ignore', invalid='ignore') # ignore errors resulting from correlation of each subject with themselves
  985. participant_data = {key:neuro_sims_storage[key][av_type][voxel_set] for key in included_subjects}
  986. subjectwise_corrs_all = {}
  987. for sbj_id in included_subjects:
  988. subjectwise_corrs = vp.calc_neuro_model_correlations(neuro_sims_storage[sbj_id][av_type][voxel_set], participant_data, control_vars, list(participant_data.keys()), sim_subset, method=corr_method, shuffle=False)[0]
  989. subjectwise_corrs_all[sbj_id] = subjectwise_corrs
  990. # pairwise average between participants
  991. sbj_pairs_all = list(itertools.combinations(included_subjects, 2))
  992. pairwise_corrs = []
  993. for sbj_pair in sbj_pairs_all:
  994. pairwise_corrs.append(subjectwise_corrs_all[sbj_pair[0]][sbj_pair[1]])
  995. print(voxel_set+' average pairwise correlation: {:.3f}'.format(np.mean(pairwise_corrs)))
  996. # %%
  997. ## Data quality plot
  998. # Select data to use
  999. accuracy_threshold = 0.4
  1000. movement_threshold = 10
  1001. subjects_for_plot = [sbj_id for sbj_id in subject_data_dict.keys() if subject_data_dict[sbj_id][0] >= accuracy_threshold and subject_data_dict[sbj_id][1] <= movement_threshold]
  1002. models_shortnames = ['conceptnet_mean_norml','openai','conceptnet_weights-fixed_struct-low_verbnet','AMR_smatch']
  1003. models_to_plot = vp.get_included_models(model_sims_storage, models_shortnames)
  1004. model_names = ['Mean-CN', 'OpenAI', 'Verbnet-CN', 'AMR-Smatch']
  1005. pairs_subset = 'diag' # all, diag
  1006. voxel_set = 'Glasser-cortex_novis-stable-'+stability_level+'-norm'
  1007. # voxel_set = 'LanROI-all-stable-'+stability_level+'-norm'
  1008. # Create plot
  1009. sns.set(font_scale=1.2)
  1010. fig = plt.figure(figsize=(4*len(models_to_plot),3.5), facecolor='white', dpi=200)
  1011. fig.subplots_adjust(wspace=0.4, hspace=0.2)
  1012. for i,model_name in enumerate(models_to_plot):
  1013. # Get plot number
  1014. plot_num = (1,len(models_to_plot),i+1)
  1015. # Storage arrays
  1016. correlations = []
  1017. partial_correlations = []
  1018. accuracies = []
  1019. motions = []
  1020. # Loop over all subjects to extract correlation and accuracy data
  1021. for sbj_id in subjects_for_plot:
  1022. corr = neuro_corrs_allsubjs[sbj_id]['mean_'+pairs_subset][voxel_set][model_name]
  1023. pcorr = neuro_pcorrs_allsubjs[sbj_id]['mean_'+pairs_subset][voxel_set][model_name]
  1024. acc = subject_data_dict[sbj_id][0]
  1025. motion = subject_data_dict[sbj_id][1]
  1026. correlations.append(corr)
  1027. partial_correlations.append(pcorr)
  1028. accuracies.append(acc)
  1029. motions.append(motion)
  1030. # Fit regression model
  1031. Xs = np.array(accuracies)
  1032. ys = np.array(correlations)
  1033. fit_type = 'linear'
  1034. def fit_func(Xs, a, b):
  1035. if fit_type=='exp':
  1036. out = a * np.exp(-b * Xs) # exponential fit
  1037. elif fit_type=='linear':
  1038. out = a * Xs + b # linear fit
  1039. return out
  1040. params, cov = curve_fit(fit_func, Xs, ys, p0=[0,-6])
  1041. y_pred = fit_func(Xs, *params) # get predicted y-valus
  1042. r_square = r2_score(ys, y_pred) # get r-square
  1043. # Add model points and line to plot
  1044. x_points = np.arange(0.5,1.0,step=0.01)
  1045. fig_axis = fig.add_subplot(*plot_num)
  1046. plt.plot(x_points, fit_func(x_points,*params), color='red', linewidth=1.5) # add reg line
  1047. plt.scatter(accuracies, correlations, s=7)
  1048. # Add labels
  1049. plt.title(model_names[i])
  1050. plt.ylabel('Model-fMRI correlation')
  1051. plt.ylim(-0.4,0.2)
  1052. plt.xlabel('Question Accuracy')
  1053. plt.text(0.5, 0.14, 'Corr: {:.3f}'.format(np.corrcoef(Xs,ys)[0][1]), fontsize=14)
  1054. # Print information
  1055. print('Subjects:',len(subjects_for_plot))
  1056. print('Model:',model_name)
  1057. print('Pairs:',pairs_subset)
  1058. print('Stability:',stability_level)
  1059. print('Control variables:',controls_type)
  1060. print('Timing:',timing)
  1061. # Save figure
  1062. figure_name = 'Figures\\Fodor2024-'+timing+'_control-'+str(controls_type)+'_voxels-'+voxel_set[0:6]+'_corr-'+corr_method+'_sims-'+similarity_type+'_question_corr.png'
  1063. plt.savefig(figure_name, bbox_inches='tight')
  1064. plt.show()
  1065. # %%

2_Analyse_fmri.ipynb at commit bd23377, under Apache-2.0 · at the source

Overview

Authors: James Fodor1, Carsten Murawski1, Shinsuke Suzuki2
  1. The Centre for Brain, Mind and Markets, Faculty of Business and Economics, The University of Melbourne, Melbourne, Australia
  2. Faculty of Social Data Science, Hitotsubashi University, Kunitachi, Japan
Journal: eLife, volume 14, article RP108442
Dates: published online 23 October 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI · PMCID PMC13694100
Status: code verified (how the code is found and verified)
Categories: human (organism)
Methods: Connectivity, Statistics, Machine learning, fMRI & imaging
Keywords: Human
Citations: not cited yet (Europe PMC); 126 references in the paper

Abstract

Large language models based on the transformer architecture are now capable of producing human-like language. But do they encode and process linguistic meaning in a human-like way? Here, we address this question by analysing 7T fMRI data from 30 participants reading 108 sentences each. These sentences are carefully designed to disentangle sentence structure from word meaning, thereby testing whether transformer representations of sentence meaning resemble those formed by the brain. Using representational similarity analysis, we compared representations from eight transformers and eleven other semantic models to brain activity in language regions of interest. We found that while transformer models match brain representations better than models that completely ignore word order, all transformers poorly match human brain representations of sentences that require sensitivity to structural relations such as semantic roles (who did what to whom). Further, transformers were significantly inferior to models explicitly designed to encode the structural relations between words. Our results provide insight into the nature of sentence representation in the brain, highlighting the critical role of sentence structure. They also cast doubt on the claim that transformers represent sentence meaning similarly to the human brain.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 14 matches between paragraphs and lines of code.

Fods12/sentence-meaning-in-the-brain

License: Apache-2.0
State: the link answers, verified on 24 October 2026
Evidence: files inventoried
Commit: bd233772317b21435e05fa133a1aa50208e9fa19, 19 October 2026
Languages: Jupyter (12), Python (6), Shell (4)
Size: 35,331 files, 22 scripts
Software Heritage: not archived
Found in: “Data availability”
Holds: 12 notebooks
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: NumPy (18 files), Matplotlib (9 files), pandas (9 files), seaborn (8 files), NiBabel (6 files), Nilearn (5 files), SciPy (5 files), scikit-learn (3 files), Pingouin (2 files), AFNI (1 file), GLMsingle (1 file)
Availability: 1 check, the latest on 24 October 2026: the link answers
  • 24 October 2026: the link answers
24 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 22 scripts, each with its path and the digest of its content;
  • 14 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Data availability

Our fMRI dataset is available for download on OpenNeuro: https://openneuro.org/datasets/ds007393. All code used is available at https://github.com/Fods12/sentence-meaning-in-the-brain (copy archived Fodor, 2026).

The following dataset was generated:

Fodor J, Murawski C, Suzuki S. 2026. Representations of Sentence Meaning in the Human Brain (RSMB) Dataset. OpenNeuro. ds007393

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 24 October 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 3 authors, 1 keyword, 119 references.

Cite

This paper

Fodor, J., Murawski, C., & Suzuki, S. (2026). Large language models poorly capture how word order shapes representations of sentence meaning in the human brain. eLife, 14, RP108442.

BibTeX

@article{fodor2026large,
author = {Fodor, James and Murawski, Carsten and Suzuki, Shinsuke},
title = {{Large language models poorly capture how word order shapes representations of sentence meaning in the human brain}},
journal = {eLife},
year = {2026},
month = oct,
volume = {14},
pages = {RP108442},
publisher = {eLife Sciences Publications, Ltd},
issn = {2050-084X},
pmcid = {PMC13694100}
}

RIS

TY - JOUR
AU - Fodor, James
AU - Murawski, Carsten
AU - Suzuki, Shinsuke
TI - Large language models poorly capture how word order shapes representations of sentence meaning in the human brain
T2 - eLife
J2 - eLife
PY - 2026
DA - 2026/10/24
VL - 14
SP - RP108442
SN - 2050-084X
PB - eLife Sciences Publications, Ltd
LA - en
ER -

CSL-JSON

{
"id": "pmcid:PMC13694100",
"type": "article-journal",
"title": "Large language models poorly capture how word order shapes representations of sentence meaning in the human brain",
"container-title": "eLife",
"author": [
{
"family": "Fodor",
"given": "James"
},
{
"family": "Murawski",
"given": "Carsten"
},
{
"family": "Suzuki",
"given": "Shinsuke"
}
],
"container-title-short": "eLife",
"volume": "14",
"page": "RP108442",
"PMCID": "PMC13694100",
"ISSN": "2050-084X",
"publisher": "eLife Sciences Publications, Ltd",
"language": "en",
"issued": {
"date-parts": [
[
2026,
10,
24
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.7554/elife.108442 [code]
Large language models poorly capture how word order shapes representations of sentence meaning in the human brain.
Journal: eLife
In common: GLMsingle, AFNI, Pingouin, 8 other tools, OpenNeuro ds007393, 119 references
[2] doi:10.1038/s41467-024-49173-5 [code]
Shared functional specialization in transformer-based language models and the human brain.
Journal: Nature communications
In common: AFNI, Nilearn, NiBabel, 6 other tools, 18 references
[3] doi:10.1038/s41467-024-50310-3 [code]
Modeling short visual events through the BOLD moments video fMRI dataset and metadata.
Journal: Nature communications
In common: GLMsingle, Nilearn, NiBabel, 5 other tools, 19 references
[4] doi:10.1162/nol_a_00125 [code]
Information-Restricted Neural Language Models Reveal Different Brain Regions' Sensitivity to Semantics, Syntax, and Context.
Journal: Neurobiology of language (Cambridge, Mass.)
In common: Nilearn, NiBabel, seaborn, 5 other tools, 11 references
[5] doi:10.7554/elife.82566 [code]
Statistical inference on representational geometries.
Journal: eLife
In common: Nilearn, NiBabel, seaborn, 5 other tools, 16 references
[6] doi:10.1016/j.neuroimage.2025.121617 [code]
Time-resolved functional connectivity during visuomotor graph learning.
Journal: NeuroImage
In common: AFNI, Nilearn, NiBabel, 5 other tools, 15 references
[7] doi:10.1038/s41467-026-71428-6 [code]
Binding items to contexts through conjunctive neural representations with the method of loci.
Journal: Nature communications
In common: Nilearn, NiBabel, seaborn, 5 other tools, 14 references
[8] doi:10.1371/journal.pbio.3003174 [code]
Neural evidence that humans reuse strategies to solve new tasks.
Journal: PLoS biology
In common: Nilearn, seaborn, scikit-learn, 4 other tools, 16 references
[9] doi:10.1016/j.neuroimage.2023.120109 [code]
Benchmarking explanation methods for mental state decoding with deep learning models.
Journal: NeuroImage
In common: AFNI, Nilearn, NiBabel, 6 other tools, 13 references
[10] doi:10.1038/s41467-024-55459-5 [code]
Network structure influences the strength of learned neural representations.
Journal: Nature communications
In common: Nilearn, NiBabel, seaborn, 5 other tools, 14 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/repo/github.com/fods12/sentence-meaning-in-the-brain.svg)](https://openscicode.org/badge/repo/github.com/fods12/sentence-meaning-in-the-brain)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/repo/github.com/fods12/sentence-meaning-in-the-brain.svg
   :target: https://openscicode.org/badge/repo/github.com/fods12/sentence-meaning-in-the-brain
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/repo/github.com/fods12/sentence-meaning-in-the-brain"><img src="https://openscicode.org/badge/repo/github.com/fods12/sentence-meaning-in-the-brain.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

On GitHub, open the README, choose Edit (the pencil), paste the snippet under the title, then "Commit changes".

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.