Transformation from [0, 1] to [0, 1] pushing values above x towards 1 and values below x towards 0.

132 Views Asked by At

I have a vector of 64 elements between [0, 1]. Those elements represent weights in a model. I would like to define the value t as the 16th maximum weight (75th percentile) and then push the weights above towards 1 and the weights below towards 0. The goal is to increase the separation, the distinction between 'high' weights and 'low' weights. Defining t is not an issue, but I do not know which transformation I could apply to achieve my goal.

I am also interested in a more general solution where the input vector elements are between [a, b] and where you can control the 'rate' at which elements are pushed towards one side or the other.

At first, I thought using logarithmic scaling would help, but it only pushes every value from [0, 1] towards 1 or towards 0 depending on the implementation. The formula for the log scaling was given to me by user1337:

$$x \mapsto \frac{\ln \left(\frac{a \theta -b}{a-b}+\frac{(1-\theta ) x}{a-b}\right)}{ \ln (\theta) }. $$

1

There are 1 best solutions below

5
On BEST ANSWER

An imperfect idea, but you tagged python, so perhaps you can make it work for your purpose:

$$f(x) = a+(b-a)\frac{\left(\frac{x-a}{b-a}\right)^{cd}}{ \left(\frac{x-a}{b-a}\right)^{cd} + \left(1- \left(\frac{x-a}{b-a}\right)^c \right)^d }$$

S-curve Positives:

  • $f$ maps $[a,b]$ to $[a,b]$ with $f(a)=a$ and $f(b)=b$ (exactly).
  • $d$ allows to tune the "strength".

Negatives:

  • $c$ is fiendishly complex to calculate as a function of $d$ and what you called $t$. So this is only useful if you can approximate $c$ numerically by looking for the $c$ that minimizes $\vert f(t)-t \vert$.