2012-10-17 9 views
5

Sto cercando un geniale aiuto SQL con un problema statistico complesso che sto riscontrando.Campionamento statistico SQL

Quello che sto cercando di fare è estrarre un campione statisticamente bilanciato da un gruppo sbilanciato di profili utente. Fare questo per un attributo profilo singolo (ad esempio genere) alla volta sarebbe un po 'semplice. Ma farlo su più dimensioni contemporaneamente richiede una certa raffinatezza.

Per amor di discussione, diciamo che ho questo tavolo.

Profile.userID 
Profile.Gender 
Profile.Age 
Profile.Income 

Se voglio tirare un pool di profili fuori dal mix in modo che il nuovo campione di utenti corrisponde grosso modo tutte le seguenti caratteristiche:

50% male, 50% female 
30% young, 40% middle age, 40% old 
40% low income, 40% middle income, 20% high income 

Qualcuno ha qualche idea su come tirare fuori questo?

+1

Che cosa impedisce di estrarre casualmente i record uno alla volta fino a quando il campionamento soddisfa le specifiche? –

+0

Come faccio a evitare che si perda continuamente? Dico che ho bisogno solo di un altro record femminile, ma tirando quello poi inclino la mia età e le entrate fuori equilibrio ...? – tbacos

+2

30% giovani, 40% di mezza età, 40% vecchi! = 100% C'è una sovrapposizione tra giovani e di mezza età nel tuo raggio d'azione? –

risposta

3

Quello che hai è un problema di campionamento. La chiave per risolvere questo problema è quella di suddividere i dati in gruppi separati delle combinazioni delle tre variabili. Quindi, calcola il prodotto delle probabilità marginali di ciascun gruppo (i tuoi valori sono probabilità marginali). Quindi, normalizza questi oltre tutti i 18 gruppi.

Ad esempio, il gruppo Maschio-Giovane-Basso otterrebbe un valore di 0,5 * 0,3 * 0,4 = 0,06. Si ripete questo per tutti i 18 gruppi e quindi si normalizza in una percentuale (ovvero, divide ciascun valore per la somma di tutti i valori). Ecco il risultato:

Gender Age  Income Marg Normalized 
Male Young Low  0.06 5.5% 
Male Young Middle 0.06 5.5% 
Male Young High 0.03 2.7% 
Male Middle Low  0.08 7.3% 
Male Middle Middle 0.08 7.3% 
Male Middle High 0.04 3.6% 
Male Old  Low  0.08 7.3% 
Male Old  Middle 0.08 7.3% 
Male Old  High 0.04 3.6% 
Female Young Low  0.06 5.5% 
Female Young Middle 0.06 5.5% 
Female Young High 0.03 2.7% 
Female Middle Low  0.08 7.3% 
Female Middle Middle 0.08 7.3% 
Female Middle High 0.04 3.6% 
Female Old  Low  0.08 7.3% 
Female Old  Middle 0.08 7.3% 
Female Old  High 0.04 3.6% 

Questo diventa la frequenza di campionamento per ciascun gruppo. Qui è pseudo-codice SQL per effettivamente facendo il campionamento:

with SamplingRates (
    select 'Male' as gender, 'Young' as Age, 'Low' as income, 0.045 as SamplingRate, 
    union all . . 
) 
select t.* 
from (select t.*, 
      row_number() over (partition by gender, age, income order by <random>) as seqnum, 
      count(*) over (partition by gender, age, income) as NumRecs 
     from table t 
    ) t join 
    SampleRates sr 
    on t.gender = sr.gender and t.age = sr.age and t.income = sr.income and 
     seqnum <= sr.SamplingRate * NumRecs 
0

Ecco come vorrei andare a questo proposito, Assumendo: 30% giovani, il 40% la mezza età, il 30% vecchio

Prendendo denominatori almeno comuni, la dimensione della piscina = 5x5x3x4x2x4 = 2400

Hai 18 query per popolare la tua piscina in una TABELLA TEMP. Ripeti tutte le 18 domande per darti una piscina più grande. Di seguito è riportata l'idea di come sarebbe la distribuzione di un pool ideale e quale sarebbe l'aspetto di ogni query. Puoi anche introdurre un po 'di casualità in ogni query. C'era un post precedente su come farlo.

Questo è forse meno elegante ma dovrebbe comunque fornire una piscina bilanciata.

vostra prima query in pseudocodice sarà simile:

SELECT * INTO TEMP TABLE 
WHERE male, young, high income and ID NOT IN TEMP TABLE 
LIMIT RECORD SET 72 

E così via e così via. Spero che sia d'aiuto. Buona domanda però.

CREATE TEMP TABLE 
480 high income 
    144 young 
     72 males [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 72] 
     72 females [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 72] 
    192 middle age 
     96 males [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 96] 
     96 females [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 96] 
    144 old 
     72 males [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 72] 
     72 females [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 72] 

960 middle income 
    288 young 
     144 male [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 144] 
     144 female [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 144] 
    384 middle age 
     192 male [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 192] 
     192 female [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 192] 
    288 old 
     144 male [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 144] 
     144 female [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 144] 

960 low income 
    288 young 
     144 male [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 144] 
     144 female [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 144] 
    384 middle age 
     192 male [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 192] 
     192 female [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 192] 
    288 old 
     144 male [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 144] 
     144 female [SELECT THIS INTO TEMP TABLE WHERE ID NOT IN TEMP TABLE LIMIT 144] 
Problemi correlati