Zmiana skali zmiennej na 0-100

20

Zbudowałem indeks kapitału społecznego za pomocą techniki PCA. Indeks ten zawiera wartości zarówno dodatnie, jak i ujemne. Chcę przekształcić / przekonwertować ten indeks na skalę 0-100, aby ułatwić interpretację. Proszę zasugerować mi najłatwiejszy sposób.

Sohail Akram
źródło
Funkcja logistyczna stosowany w modelach logitowych może się przydać również. Zależy od konkretnego celu.
Ondrej,
2
Skalowanie istniejących danych do 0-100 ma ukryte ryzyko, kiedy zostanie zastosowane do przyszłych (lub dodatkowych) danych. Zobacz consumerreports.org/cro/cars/... , na przykład, gdzie napisał Consumer Reports”... mamy do czynienia rozterce: Tesla początkowo zdobył 103 w Consumer Reports' Oceny systemu, który z definicji nie przejść obok 100. Samochód ustanowił nowy punkt odniesienia, więc musieliśmy wprowadzić zmiany w naszej punktacji, aby to uwzględnić ”.
whuber

Odpowiedzi:

33

Dowolna zmienna (rozkład jednoczynnikowa) z zaobserwowanym m i n o l d i m x O L d wartości (lub te mogą być ustawione potencjalnych granic dla wartości) mogą być przeskalowane w stosunku do zakresu m i n n e W celu m x n e w następującym wzorze:vmjanolremzaxolremjannmiwmzaxnmiw

mzaxnmiw-mjannmiwmzaxolre-mjanolre(v-mzaxolre)+mzaxnmiw

lub

.mzaxnmiw-mjannmiwmzaxolre-mjanolre(v-mjanolre)+mjannmiw

ttnphns
źródło
18

Dla R dostępna jest również rescalefunkcja z pakietu skal , która robi dokładnie to, co chcesz i co opisali @AndrewTulloch i @ttnphns:

library(scales)
rescale(c(-10, -9, -5, 2, 6), to = c(0, 100)) ## Use scales:::rescale() if you have several packages loaded using the same function name
[1]   0.00   6.25  31.25  75.00 100.00
Mikko
źródło
7

po pierwsze, uzyskajmy przykładowe dane:

x <- runif(20, -10, 10)

Oto dwie funkcje, które będą działać w języku R.

rescale <- function(x) (x-min(x))/(max(x) - min(x)) * 100
rescale(x)

Lub możesz użyć innych transformacji. Na przykład transformacja logit została wspomniana przez @ondrej

plogis(x)*100

lub inne przekształcenia:

pnorm(x)*100
pnorm(x, 0, 100) * 100
punif(x, min(x), max(x))*100
David LeBauer
źródło
4

Wystarczy dodać do odpowiedzi ttnphnss, aby zaimplementować ten proces w Pythonie (na przykład), ta funkcja załatwi sprawę:

from __future__ import division

def rescale(values, new_min = 0, new_max = 100):
    output = []
    old_min, old_max = min(values), max(values)

    for v in values:
        new_v = (new_max - new_min) / (old_max - old_min) * (v - old_min) + new_min
        output.append(new_v)

    return output

print rescale([1, 2, 3, 4, 5])
# [0.0, 25.0, 50.0, 75.0, 100.0]
Andrew Tulloch
źródło
Dzięki, czy ta formuła dotyczy również wartości ujemnych? na przykład, jeśli moja oryginalna zmienna wynosi od -10 do 10.
Sohail Akram
Tak - działa dla wszystkich wartości - na przykład print rescale([-10, -9, -5, 2, 6]) # [0.0, 6.25, 31.25, 75.0, 100.0]
Andrew Tulloch,
3

Sugeruję, aby nie wiązać indeksu z przedziałem 0-100, ponieważ nie poprawia to interpretacji, ale raczej utrudnia. Jeśli składniki indeksu mogą być ujemne, to możliwe, że indeks staje się ujemny i, moim zdaniem, lepiej odzwierciedla to, co dzieje się ze składnikami niż jakaś niska wartość w zakresie 0-100.

Aksakal
źródło
0

W przypadku R z załadowanymi pakietami standardowymi możesz po prostu użyć funkcji scale () z pakietu „podstawowego”:

x=c(2,4,8,16)
x.scaled = scale(x,FALSE,max(x))  # divide each value in x by max(x)
x.scaled = as.vector(x.scaled) 

użyj „as.vector ()”, aby pobrać skalowane x jako wektor.

użytkownik161922
źródło
3
Ponieważ oryginalne wartości mogą być ujemne, dzielenie przez największą wartość nie będzie wystarczające. Zastanów się dobrze nad pytaniem, a --- biorąc pod uwagę, że David i Mikko opublikowali już odpowiedzi, które uwzględniają ten aspekt - aby uzyskać kciuki do góry, zazwyczaj musisz wnieść coś, czego nie udzieliły odpowiedzi.
Glen_b
Masz absolutną rację, przepraszam za to.
user161922,