Як зобразити необмежену змінну як число між 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().

f(x)=1/(1+ex)

Ось простий R-код, який побудує обидві функції (підфарбований червоним кольором, логістичний синій колір), щоб ви могли бачити, як обидва сквош:

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

Як часто, моє перше питання полягало в тому, що " чому ти хочеш це робити", тоді я побачила, що ти вже відповіла на це в коментарях на питання: " Я вимірюю вміст у багатьох різних вимірах, і я хочу бути вмію проводити порівняння з точки зору того, наскільки релевантним є певний вміст. Крім того, я хочу відображати значення в цих вимірах, які можна зрозуміти і легко зрозуміти ".

zzz-результати, бажано, щоб кожна змінна мала приблизно нормальний розподіл або, принаймні, мала приблизно симетричний розподіл (тобто не було сильно перекошеним), але, якщо потрібно, спочатку можна застосувати відповідне перетворення даних для досягнення цього; яке перетворення використовувати можна, визначивши найкращу трансформацію Box-Cox .


[0,1]

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

10

Будь-яка сигмоїдна функція буде працювати:


erf - це не дуже зручна функція, якщо ви не хочете скоріше використовувати її для її похідної.

Я в кінцевому підсумку використовував просту логістичну функцію з невеликими налаштуваннями: (1 / (1 + java.lang.Math.exp (-1 * (фактор * i)) - 0,5) * 2. Я вибрав коефіцієнт 0,05, який здається, працює добре для мене від 0 до декількох сотень.
Jilles van Gurp

1,0 / (1,0 + exp (-1,69897 * (середнє значення x (x)) / sd (x))) є близьким наближенням до pnorm
Кріс,

3

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


1

У моїй попередній публікації є метод оцінювання між 0 і 1. Порада щодо кореляції введення класифікатора

Однак у ранжируванні, який я використав, Tmin / Tmax використовує вибірку min / max, але ви можете вважати, що сукупність min / max є більш доцільною. Подивіться також оцінки балів


1

Щоб додати до інших відповідей, що пропонують pnorm ...

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

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

нудоту

Це по суті Softmax Normalization.

Довідкова Pnorm у крайньому випадку


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 з об'єктами [пік] та [корита] для першого прикладу та з [jit.3m] для другого прикладу.
тераса

0

Дуже простий варіант - розділити кожне число ваших даних на найбільшу кількість у ваших даних. Якщо у вас багато невеликих чисел і кілька дуже великих, це може не передати інформацію добре. Але це відносно просто; якщо ви думаєте, що змістовна інформація втрачається при графіку подібних даних, ви можете спробувати один із найскладніших методів, які запропонували інші.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.