Cómo representar una variable ilimitada como número entre 0 y 1

28

Quiero representar una variable como un número entre 0 y 1. La variable es un número entero no negativo sin límite inherente. Asigno 0 a 0, pero ¿qué puedo asignar a 1 o números entre 0 y 1?

Podría usar el historial de esa variable para proporcionar los límites. Esto significaría que tengo que reformular las estadísticas antiguas si el máximo aumenta. ¿Tengo que hacer esto o hay otros trucos que debería saber?

Russell Gallop
fuente
66
Debido a que cualquier función no decreciente de hará el truco, tienes mucha flexibilidad. Pero algunos métodos serán mejores que otros, dependiendo de la aplicación. ¿Cuál es su propósito al buscar una nueva expresión? [0,)[0,1]
whuber
1
Estoy midiendo el contenido en muchas dimensiones diferentes y quiero poder hacer comparaciones en términos de cuán relevante es un determinado contenido. Además, quiero mostrar valores en estas dimensiones que sean explicables y fáciles de entender.
Spencer
1
@Spencer Exactamente, ¿cómo estás midiendo el contenido y la "relevancia"? Por ejemplo, en escalas arbitrarias, como recuentos, proporciones, frecuencias de vistas, correlaciones con otros contenidos, etc. etc. Los diferentes tipos de mediciones se benefician de diferentes tipos de reexpresiones.
whuber
1
Los estoy midiendo en escalas arbitrarias. Qué edad tiene el contenido. Cuántos "puntos" se recibe una pieza de contenido. "Interés" autoinformado en el dominio del contenido.
Spencer
2
Una de las transformaciones más simples que podría usar es convertir sus datos en puntajes cuantiles.
charles.y.zheng

Respuestas:

34

Un truco muy común para hacerlo (por ejemplo, en el modelado conexionista) es usar la tangente hiperbólica tanh como la "función de aplastamiento". Se ajusta automáticamente a todos los números en el intervalo entre -1 y 1. Lo que en su caso restringe el rango de 0 a 1. En ry matlablo obtienes a través de tanh().

Otra función de aplastamiento es la función logística (gracias a Simon por el nombre), proporcionada por , que restringe el rango de 0 a 1 (con 0 asignado a .5). Por lo tanto, tendría que multiplicar el resultado por 2 y restar 1 para ajustar sus datos en el intervalo entre 0 y 1.f(x)=1/(1+ex)

Aquí hay un código R simple que traza ambas funciones (tanh en rojo, logística en azul) para que pueda ver cómo ambos aplastan:

x <- seq(0,20,0.001)
plot(x,tanh(x),pch=".", col="red", ylab="y")
points(x,(1 / (1 + exp(-x)))*2-1, pch=".",col="blue")
Henrik
fuente
Gracias por tu respuesta. Eso resuelve el problema de los límites. Para mis datos, va a 1 muy rápidamente para mis datos, así que supongo que lo siguiente que debo hacer es escalar esta información para concentrarme en el rango interesante que podría hacer en función de la historia sin temor a abandonar el límite, Solo tocando el límite.
Russell Gallop
25

Como siempre, mi primera pregunta iba a ser " por qué quieres hacer esto", luego vi que ya respondiste esto en los comentarios a la pregunta: " Estoy midiendo contenido en muchas dimensiones diferentes y quiero ser capaz de hacer comparaciones en términos de cuán relevante es un determinado contenido. Además, quiero mostrar valores a través de estas dimensiones que sean explicables y fáciles de entender " .

No hay ninguna razón para normalizar los datos para que el máximo sea 1 y el mínimo sea cero para lograr esto, y mi opinión es que esta sería una mala idea en general . Los valores máximos o mínimos podrían fácilmente ser valores atípicos que no representan la distribución de la población. La observación de despedida de @osknows sobre el uso de -scoresz es una idea mucho mejor . puntajes z (también conocidos como puntajes estándar) normalizan cada variable usando su desviación estándar en lugar de su rango. La desviación estándar está menos influenciada por los valores atípicos. Para usar zzz-puntos, es preferible que cada variable tenga una distribución más o menos normal, o al menos una distribución más o menos simétrica (es decir, no sea muy sesgada), pero si es necesario, puede aplicar primero una transformación de datos adecuada para lograr esto; qué transformación usar podría determinarse encontrando la mejor transformación de Box-Cox .

una parada
fuente
[0,1]
1
Si a uno le preocupan los valores atípicos, podría considerar usar la desviación absoluta media (de la mediana) en lugar de la desviación estándar. En R, usa la mad()función. Y si uno está preocupado por la asimetría, puede usar los rangos de los datos en lugar de las observaciones originales. En R, esto sería rank(), pero si uno va a usar esto en nuevos datos, ecdf()sería una mejor alternativa ( ecdf(x)devuelve una nueva función que básicamente da el valor al p -quantile deppx1/nx1
Karl Ove Hufthammer
10

Cualquier función sigmoidea funcionará:

Simon Byrne
fuente
erf no es una función muy útil, siempre que no desee usarla más bien para su derivada.
Terminé usando una función logística simple con algunos pequeños ajustes: (1 / (1 + java.lang.Math.exp (-1 * (factor * i))) - 0.5) * 2. Escogí un factor de 0.05 que parece funcionar bien para i entre 0 y unos pocos cientos.
Jilles van Gurp
1.0 / (1.0 + exp (-1.69897 * (x-mean (x)) / sd (x))) es una aproximación cercana a pnorm
Chris
3

Además de las buenas sugerencias de Henrik y Simon Byrne, puede usar f (x) = x / (x + 1). A modo de comparación, la función logística exagerará las diferencias a medida que x crezca. Es decir, la diferencia entre f (x) y f (x + 1) será mayor con la función logística que con f (x) = x / (x + 1). Puede o no querer ese efecto.


fuente
1

Mi publicación anterior tiene un método para clasificar entre 0 y 1. Consejos sobre la correlación de entrada del clasificador

Sin embargo, en la clasificación que he usado, Tmin / Tmax usa la muestra min / max, pero es posible que la población min / max sea más apropiada. También busque puntajes z

osknows
fuente
1

Para agregar a las otras respuestas que sugieren pnorm ...

Para un método potencialmente óptimo para seleccionar parámetros, sugiero esta aproximación para pnorm.

1.0/(1.0+exp(-1.69897*(x-mean(x))/sd(x)))

pnormish

Esto es esencialmente la normalización de Softmax.

Pnorm de referencia en una pizca

Chris
fuente
1

Hay dos formas de implementar esto que uso comúnmente. Siempre estoy trabajando con datos en tiempo real, por lo que esto supone una entrada continua. Aquí hay un pseudocódigo:

Usando un minmax entrenable:

define function peak:
    // keeps the highest value it has received

define function trough:
    // keeps the lowest value it has received

define function calibrate:
    // toggles whether peak() and trough() are receiving values or not

define function scale:
    // maps input range [trough.value() to peak.value()] to [0.0 to 1.0]

Esta función requiere que realices una fase de entrenamiento inicial (mediante el uso calibrate()) o que vuelvas a entrenar a ciertos intervalos o de acuerdo con ciertas condiciones. Por ejemplo, imagine una función como esta:

define function outBounds (val, thresh):
    if val > (thresh*peak.value()) || val < (trough.value() / thresh):
        calibrate()

pico y valle normalmente no reciben valores, pero si outBounds()recibe un valor que es más de 1.5 veces el pico actual o menor que el canal actual dividido por 1.5, entonces calibrate()se llama lo que permite que la función se recalibre automáticamente.

Usando un mínimo histórico:

var arrayLength = 1000
var histArray[arrayLength]

define historyArray(f):
    histArray.pushFront(f) //adds f to the beginning of the array

define max(array):
    // finds maximum element in histArray[]
    return max

define min(array):
    // finds minimum element in histArray[]
    return min

define function scale:
    // maps input range [min(histArray) to max(histArray)] to [0.0 to 1.0]

main()
historyArray(histArray)
scale(min(histArray), max(histArray), histArray[0])
// histArray[0] is the current element
terraza
fuente
Todo esto se puede implementar en Max / MSP / Jitter con los objetos [peak] y [trough] para el primer ejemplo y con [jit.3m] para el segundo ejemplo.
terraza
0

Una opción muy simple es dividir cada número en sus datos por el número más grande en sus datos. Si tiene muchos números pequeños y algunos muy grandes, esto podría no transmitir bien la información. Pero es relativamente fácil; Si cree que se pierde información significativa cuando grafica los datos de esta manera, puede probar una de las técnicas más sofisticadas que otros han sugerido.

DanB
fuente