Open jorjasso opened 4 years ago
I think it is related to a zero variance problem. adding a small value to index causing the problem will work? something like this:
def avoid_zero_var(x,y):
diff = y - x
idx=diff==0
x[idx]=x[idx]+0.0000001
return x
I just investigated this. This problem seems to occur if there is zero variance in the second dimension diff
and diff.shape[1]
is uneven. In that case, the code meant to avert numerical problems fails because sample[:nscores_2]
has length k
whereas sample[nscores_2:]
has length k+1
.
The problematic code in multiple.py
currently looks like this:
nscores_2 = nscores // 2
(…)
sample[:nscores_2] = _random_state.uniform(-rope, rope, nscores_2)
sample[nscores_2:] = -sample[:nscores_2]
I'm not entirely sure how to handle the situation if nscores
is uneven as I can't right now find the statistical argument that motivated the currently-used heuristic of “fixing” the variance by sampling from a uniform. Maybe one of the original authors has an idea?
Thanks for finding this. @benavoli, @gcorani any suggestions? One option is to just set the middle element to 0, but I've no idea if this is OK (that is: more statistically broken than the existing solution).
Also, shouldn't the mean of the sample be kept? Right now, it is discarded which may lead to significant distortions: E.g. consider one learning task where performance has zero variance but one of the algorithms under consideration performs well whereas the other does not—in that case, substituting the sample with a uniform sample from the rope seems rather inappropriate?
Idea: Draw nscores // 2
samples from a shifted half-normal with a certain (minimal) variance and then mirror that at the mean of the original sample. If nscores
is uneven, set the mean as the central element.
A rough draft:
import scipy.stats as sst
def fix(diff, scale=1e-5):
n_instances, n_scores = diff.shape
n_scores_2 = n_scores // 2
for sample in diff:
if np.var(sample) == 0:
mean = np.mean(sample)
if n_scores % 2 == 0:
sample[:n_scores_2] = sst.halfnorm.rvs(
loc=mean,
scale=scale,
size=n_scores_2,
random_state=_random_state)
sample[n_scores_2:] = mean - (sample[:n_scores_2] - mean)
else:
sample[:n_scores_2] = sst.halfnorm.rvs(
loc=mean,
scale=scale,
size=n_scores_2,
random_state=_random_state)
sample[n_scores_2] = mean
sample[n_scores_2 + 1:] = mean - (sample[:n_scores_2] - mean)
return diff
The question is then how to choose the scale
parameter sensibly. Any suggestions? Is this overall idea viable/better than the fix implemented right now? If you like this (and make some suggestion as to how to choose the scale
parameter), I may create a PR.
@gcorani, thanks for answering previous comments. You're welcome to continue. :)
@dpaetzel, this library is an adaptation of (mostly) R and Julia code by @gcorani and @benavoli. I do not feel confident at changing anything (except, of course, inconsequential refactoring). Therefore, I actually wouldn't mind transferring this repository to more capable hands. I can stay on board as "Python consultant". :)
@dpaetzel @janezd I do not have really enough time to understand in detail the comment about shifted half-normal or implemeting it . I guess the best is that @dpaetzel implements the modification in his own copy of the code. Perhaps sooner or later we could have a chat so that he shows us which kind of work he is doing with the Bayesian tests.
Thank you both for responding!
I do not feel confident at changing anything (except, of course, inconsequential refactoring).
@janezd, I understand that all too well. :slightly_smiling_face: If this issue arises again some time and you need me to elaborate on the idea I described above, feel free to get in touch.
I guess the best is that @dpaetzel implements the modification in his own copy of the code.
@gcorani, OK, I guess, I'll do that.
which kind of work he is doing with the Bayesian tests.
To be honest, I just wanted to properly evaluate some ML experiments I performed (for which I did not use CV—hence the other issues I opened earlier). I then noticed this issue being open for quite some time and thought that it may be worth investigating it shortly. :slightly_smiling_face:
Hi,
I am running the hierarchical model version of
two_on_multiple
on two cross-validation matricesx
andy
. I am running the test many times without problems, but for some matrices I am having a value error.Reproducing code: