So stellen Sie eine unbegrenzte Variable als Zahl zwischen 0 und 1 dar


28

Ich möchte eine Variable als Zahl zwischen 0 und 1 darstellen. Die Variable ist eine nicht negative Ganzzahl ohne inhärente Grenze. Ich ordne 0 zu 0 zu, aber was kann ich 1 oder Zahlen zwischen 0 und 1 zuordnen?

Ich könnte den Verlauf dieser Variablen verwenden, um die Grenzen anzugeben. Dies würde bedeuten, dass ich alte Statistiken neu formulieren muss, wenn sich das Maximum erhöht. Muss ich das tun oder gibt es andere Tricks, die ich kennen sollte?


6
Da jede nicht abnehmende Funktion von ausreicht [0,)[0,1], haben Sie viel Flexibilität. Einige Methoden sind jedoch je nach Anwendung besser als andere. Was ist Ihr Ziel bei der Suche nach einem solchen Ausdruck?
whuber

1
Ich messe Inhalte in vielen verschiedenen Dimensionen und möchte Vergleiche in Bezug auf die Relevanz eines bestimmten Inhalts anstellen können. Außerdem möchte ich Werte über diese Dimensionen hinweg anzeigen, die erklärbar und leicht verständlich sind.
Spencer

1
@Spencer Genau wie messen Sie Inhalt und "Relevanz"? ZB in beliebigen Maßstäben, wie Anzahl, Proportionen, Häufigkeit von Ansichten, Korrelationen mit anderen Inhalten usw. usw. Verschiedene Arten von Messungen profitieren von verschiedenen Arten von Wiederausdrücken.
Whuber

1
Ich messe sie auf beliebigen Skalen. Wie alt ist der Inhalt? Wie viele "Punkte" ein Inhalt erhält. Selbst gemeldetes "Interesse" an der Domain des Inhalts.
Spencer

2
Eine der einfachsten Transformationen, die Sie verwenden können, ist die Konvertierung Ihrer Daten in Quantil-Scores.
charles.y.zheng

Antworten:


34

Ein sehr gebräuchlicher Trick, um dies zu tun (z. B. in der konnektionistischen Modellierung), besteht darin, den Tangens Hyperbolicus als "Quetschfunktion" zu verwenden. Er fügt automatisch alle Zahlen in das Intervall zwischen -1 und 1 ein. Dies schränkt in Ihrem Fall den Bereich von ein 0 bis 1. In rund matlabSie bekommen es über tanh().

Eine weitere Squashing-Funktion ist die logistische Funktion (danke an Simon für den Namen), die durch bereitgestellt wird und den Bereich von 0 bis 1 einschränkt (wobei 0 auf 0,5 abgebildet wird). Sie müssten also das Ergebnis mit 2 multiplizieren und 1 subtrahieren, um Ihre Daten in das Intervall zwischen 0 und 1 einzupassen.f(x)=1/(1+ex)

Hier ist ein einfacher R-Code, der beide Funktionen aufzeichnet (Tanh in Rot, Logistic in Blau), damit Sie sehen können, wie beide Squashs funktionieren:

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")

Danke für deine Antwort. Das löst das Problem der Begrenzung. Für meine Daten geht es sehr schnell auf 1, also muss ich diese Informationen wohl als Nächstes skalieren, um mich auf den interessanten Bereich zu konzentrieren, den ich basierend auf der Historie davon tun könnte, ohne befürchten zu müssen, die Grenze zu verlassen. nur das Limit erreichen.
Russell Gallop

25

Wie oft lautete meine erste Frage " Warum willst du das?". Dann habe ich gesehen, dass du dies bereits in den Kommentaren zu der Frage beantwortet hast: " Ich messe Inhalte über viele verschiedene Dimensionen hinweg und ich möchte es sein Vergleiche in Bezug auf die Relevanz eines bestimmten Inhalts anstellen können. Außerdem möchte ich Werte über diese Dimensionen hinweg anzeigen, die erklärbar und leicht verständlich sind. "

Es gibt keinen Grund, die Daten zu normalisieren, sodass das Maximum 1 und das Minimum Null ist, um dies zu erreichen, und ich bin der Meinung, dass dies im Allgemeinen eine schlechte Idee wäre . Die Max- oder Min-Werte können sehr leicht Ausreißer sein , die für die Bevölkerungsverteilung nicht repräsentativ sind. @osknows Abschiedsanmerkung über die Verwendung von Punktenz ist eine viel bessere Idee . Punkte (auch als Standardwerte bezeichnet) normalisieren jede Variable anhand ihrer Standardabweichung und nicht anhand ihres Bereichs. Die Standardabweichung wird von Ausreißern weniger beeinflusst. Um zzz-scores, es ist vorzuziehen, dass jede Variable eine ungefähr normale Verteilung oder zumindest eine ungefähr symmetrische Verteilung hat (dh keine starke Schräglage aufweist), aber wenn nötig, können Sie zuerst eine geeignete Datentransformation anwenden , um dies zu erreichen; Welche Transformation zu verwenden ist, lässt sich bestimmen, indem die am besten passende Box-Cox-Transformation ermittelt wird .


Es hat also nichts damit zu tun, die Daten auf zu zwingen , und im Allgemeinen stimme ich der Standardisierung zu, wenn der Autor wirklich danach sucht :) Ich habe geantwortet, bevor die Diskussion erschien ist richtig :)[0,1]
Dmitrij Celov

1
mad()rank()ecdf()ecdf(x)ppx1/nx1
Karl Ove Hufthammer

10

Jede Sigmoid-Funktion funktioniert:


erf ist keine sehr praktische Funktion, vorausgesetzt, Sie möchten sie nicht lieber für ihre Ableitung verwenden.

Am Ende habe ich eine einfache Logistikfunktion mit einigen kleinen Änderungen verwendet: (1 / (1 + java.lang.Math.exp (-1 * (factor * i))) - 0.5) * 2. Ich habe einen Faktor von 0.05 ausgewählt, der scheint gut zu funktionieren für i zwischen 0 und ein paar hundert.
Jilles van Gurp

1,0 / (1,0 + exp (-1,69897 * (x-Mittelwert (x)) / sd (x))) ist eine enge Annäherung an pnorm
Chris

3

Zusätzlich zu den guten Vorschlägen von Henrik und Simon Byrne können Sie f (x) = x / (x + 1) verwenden. Zum Vergleich: Die logistische Funktion überträgt die Unterschiede, wenn x größer wird. Das heißt, der Unterschied zwischen f (x) und f (x + 1) ist mit der logistischen Funktion größer als mit f (x) = x / (x + 1). Möglicherweise möchten Sie diesen Effekt nicht.



1

To add to the other answers suggesting pnorm...

For a potentially optimal method for selecting parameters I suggest this approximation for pnorm.

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

pnormish

This is essentially Softmax Normalization.

Reference Pnorm in a pinch


1

There are two ways to implement this that I use commonly. I am always working with realtime data, so this assumes continuous input. Here's some pseudo-code:

Using a trainable minmax:

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]

This function requires that you either perform an initial training phase (by using calibrate()) or that you re-train either at certain intervals or according to certain conditions. For instance, imagine a function like this:

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

peak and trough are normally not receiving values, but if outBounds() receives a value that is more than 1.5 times the current peak or less than the current trough divided by 1.5, then calibrate() is called which allows the function to re-calibrate automatically.

Using an historical minmax:

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

This can all be implemented in Max/MSP/Jitter with the [peak] and [trough] objects for the first example and with [jit.3m] for the second example.
terrace

0

A very simple option is dividing each number in your data by the largest number in your data. If you have many small numbers and a few very large ones, this might not convey the information well. But it's relatively easy; if you think meaningful information is lost when you graph the data like this, you could try one of the more sophisticated techniques that others have suggested.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.