Как представить неограниченную переменную в виде числа от 0 до 1


28

Я хочу представить переменную как число от 0 до 1. Переменная является неотрицательным целым числом без внутренней границы. Я отображаю 0 на 0, но что я могу сопоставить 1 или числам от 0 до 1?

Я мог бы использовать историю этой переменной, чтобы обеспечить пределы. Это будет означать, что мне придется пересчитать старую статистику, если максимум увеличится. Должен ли я сделать это или есть другие хитрости, о которых я должен знать?


6
Поскольку любая неубывающая функция из сделает свое дело, вы обладаете большой гибкостью. Но некоторые методы будут лучше, чем другие, в зависимости от приложения. Какова ваша цель в поиске такого повторного выражения? [0,)[0,1]
whuber

1
Я измеряю контент по многим различным параметрам и хочу сравнивать, насколько релевантен данный фрагмент контента. Кроме того, я хочу отображать значения в этих измерениях, которые можно объяснить и легко понять.
Спенсер

1
@Spencer Точно, как вы оцениваете содержание и «релевантность»? Например, в произвольных масштабах, таких как подсчет, пропорции, частоты просмотров, корреляции с другим контентом и т. Д. И т. Д. Различные типы измерений выигрывают от различных видов повторных выражений.
whuber

1
Я измеряю их в произвольных масштабах. Сколько лет содержанию. Сколько «очков» за кусок контента получено. Самооценка «интереса» к предметной области контента.
Спенсер

2
Одно из самых простых преобразований, которое вы можете использовать, - преобразовать ваши данные в квантильные оценки.
charles.y.zheng

Ответы:


34

Очень распространенная уловка для этого (например, в моделировании коннекциониста) - это использовать гиперболический тангенс танх в качестве «функции сжатия». Она автоматически вписывает все числа в интервал от -1 до 1. Что в вашем случае ограничивает диапазон от От 0 до 1. В rи matlabвы получите это через tanh().

Другая функция сжатия - логистическая функция (спасибо Саймону за имя), предоставляемая , которая ограничивает диапазон от 0 до 1 (с 0, сопоставленным с .5). Таким образом, вам придется умножить результат на 2 и вычесть 1, чтобы подогнать ваши данные к интервалу от 0 до 1.f(x)=1/(1+ex)

Вот некоторый простой R-код, который отображает обе функции (tanh красным, логистическая синим цветом), так что вы можете увидеть, как обе сквош:

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

Спасибо за Ваш ответ. Это решает проблему ограничения. Что касается моих данных, то для моих данных они очень быстро переходят в 1, поэтому я думаю, что следующее, что мне нужно сделать, - это масштабировать эту информацию, чтобы сконцентрироваться на интересном диапазоне, который я мог бы сделать на основе ее истории, не боясь выйти за границы, просто достигнув предела.
Рассел Галоп

25

Как и часто, моим первым вопросом было « почему вы хотите это сделать», а потом я увидел, что вы уже ответили на это в комментариях к вопросу: « Я измеряю содержание во многих различных измерениях и хочу быть возможность сравнивать с точки зрения того, насколько релевантен данный фрагмент контента. Кроме того, я хочу отображать значения в этих измерениях, которые можно объяснить и легко понять »

Нет причин для нормализации данных, чтобы максимальное значение было равно 1, а минимальное значение равно нулю, чтобы достичь этого, и я считаю, что в целом это было бы плохой идеей . Максимальные или минимальные значения могут очень легко быть выбросами , которые не представляют распределение населения. Прощальное замечание @osknows об использовании -scoresZ - гораздо лучшая идея . баллы (или стандартные баллы) нормализуют каждую переменную, используя ее стандартное отклонение, а не диапазон. На стандартное отклонение меньше влияют выбросы. Для того, чтобы использовать ZZz- желательно, чтобы каждая переменная имела примерно нормальное распределение или, по крайней мере, имела примерно симметричное распределение (т.е. не сильно искажено), но при необходимости вы можете сначала применить соответствующее преобразование данных для достижения этого; какое преобразование использовать можно определить, найдя наиболее подходящее преобразование Бокса-Кокса .


[0,1]

1
Если кто-то беспокоится о выбросах, он может рассмотреть возможность использования медианного абсолютного отклонения (от медианы) вместо стандартного отклонения. В R используйте mad()функцию. И если кого-то беспокоит асимметрия, можно использовать ранги данных вместо исходных наблюдений. В R это было бы так rank(), но если кто-то собирается использовать это для новых данных, ecdf()будет лучшей альтернативой ( ecdf(x)возвращает новую функцию, которая в основном дает значениеп к пквантиль Икснапример, 0 (действительно 1/N) наименьшее значение Икс, 1на наибольшее значение, 0,5 на медиану и т. д.)
Карл Ове Хуфтхаммер

10

Любая сигмовидная функция будет работать:


erf не очень удобная функция, если вы не хотите использовать ее в качестве производной.

В итоге я использовал простую логистическую функцию с некоторыми небольшими изменениями: (1 / (1 + java.lang.Math.exp (-1 * (factor * i))) - 0.5) * 2. Я выбрал коэффициент 0,05, который кажется, хорошо работает для меня от 0 до нескольких сотен.
Жиль ван Гурп

1.0 / (1.0 + exp (-1.69897 * (x-mean (x)) / sd (x))) - близкое приближение к pnorm
Крис

3

В дополнение к хорошим предложениям Хенрика и Саймона Бирна, вы можете использовать f (x) = x / (x + 1). Для сравнения, логистическая функция будет преувеличивать различия по мере увеличения x. То есть разница между f (x) и f (x + 1) будет больше с логистической функцией, чем с f (x) = x / (x + 1). Вы можете или не можете хотеть этого эффекта.


1

В моем предыдущем посте есть метод ранжирования от 0 до 1. Рекомендации по корреляции входных данных классификатора

Тем не менее, в ранжировании, которое я использовал, Tmin / Tmax использует выборку мин / макс, но вы можете найти популяцию мин / макс более подходящей. Также посмотрите Z баллов


1

Чтобы добавить к другим ответам, предлагающим pnorm ...

Для потенциально оптимального метода выбора параметров я предлагаю это приближение для pnorm.

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

pnormish

По сути это нормализация Softmax.

Ссылка Пнорм в крайнем случае


1

Есть два способа реализовать это, которые я обычно использую. Я всегда работаю с данными в реальном времени, поэтому это предполагает непрерывный ввод. Вот некоторый псевдокод:

Используя обучаемый 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]

Эта функция требует, чтобы вы либо выполнили начальную фазу обучения (используя calibrate()), либо переподготовили либо через определенные промежутки времени, либо в соответствии с определенными условиями. Например, представьте себе такую ​​функцию:

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

Пик и впадина, как правило, не принимают значения, но если они outBounds()получают значение, которое более чем в 1,5 раза превышает текущий пик или меньше, чем текущее значение впадины, деленное на 1,5, то calibrate()вызывается, что позволяет функции автоматически выполнять калибровку.

Используя исторический минимакс:

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

Все это может быть реализовано в Max / MSP / Jitter с объектами [peak] и [trough] для первого примера и с [jit.3m] для второго примера.
терраса

0

Очень простой вариант - делить каждое число в ваших данных на наибольшее число в ваших данных. Если у вас много маленьких чисел и несколько очень больших, это может плохо передать информацию. Но это относительно легко; если вы думаете, что значимая информация теряется при отображении таких данных, вы можете попробовать один из более сложных методов, предложенных другими.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.