Jak symulować dane, aby były istotne statystycznie?

18

Mam 10 klasę i zamierzam symulować dane dla projektu targów nauki maszynowego. Ostateczny model zostanie zastosowany do danych pacjenta i będzie przewidywał korelację między niektórymi porami tygodnia i wpływ, jaki ma to na przyleganie leku w danych jednego pacjenta. Wartości przylegania będą binarne (0 oznacza, że ​​nie zażyli leku, 1 oznacza, że ​​przyjęli). Chcę stworzyć model uczenia maszynowego, który będzie mógł uczyć się na podstawie relacji między porami tygodnia i podzielił tydzień na 21 przedziałów czasowych, po trzy dla każdej pory dnia (1 to poniedziałek rano, 2 to poniedziałek po południu, itp.). Chcę symulować dane o wartości 1000 pacjentów. Każdy pacjent będzie miał dane z 30 tygodni. Chcę wstawić pewne trendy związane z porą tygodnia i przestrzeganiem zasad. Na przykład, w jednym zbiorze danych mogę powiedzieć, że przedział czasowy 7 tygodnia ma statystycznie istotny związek z przestrzeganiem. Aby ustalić, czy związek jest statystycznie istotny, czy nie, wymagałbym wykonania testu t dla dwóch próbek, porównując jedną szczelinę czasową z każdym z pozostałych, i upewnienia się, że wartość istotności jest mniejsza niż 0,05.

Jednak zamiast symulować własne dane i sprawdzać, czy trendy, które wstawiłem, są znaczące, czy nie, wolę pracować wstecz i być może skorzystam z programu, o który mógłbym poprosić, aby przypisać pewnemu przedziałowi czasu znaczący trend z zachowaniem zgodności, i powróci dane binarne, które zawierają w sobie trend, o który prosiłem, a także dane binarne dla innych przedziałów czasowych, które zawierają szum, ale nie generują statystycznie istotnego trendu.

Czy jest jakiś program, który może mi pomóc osiągnąć coś takiego? A może moduł python?

Jakakolwiek pomoc (nawet ogólne komentarze na temat mojego projektu) będzie bardzo mile widziana !!

Neelasha Bhattacharjee
źródło
4
To świetne pytanie. I coś takiego powinno zrobić większość naukowców przed złożeniem wniosku o grant w fazie projektowania badań. Zdecydowanie zbyt często widzę, że ludzie najpierw zbierają swoje dane i próbują wymyślić, jak je później przeanalizować, w wyniku czego statystycy mogą być w stanie stwierdzić, co zmarł eksperyment, słowami Ronalda Fishera .
S. Kolassa - Przywróć Monikę
@StephanKolassa Jednak bardzo trudno jest ocenić, jakie dane będą dostępne w niektórych eksperymentach z danymi ludzkimi, aw innych ustawieniach wykorzystuje się dane, które są dostępne i nie można zebrać więcej ...
llrs
2
@llrs: To jest całkowicie poprawne. I powinno oczywiście informować o ćwiczeniu symulacyjnym. Lepiej wcześniej pomyśleć o dostępnych danych, niż dowiedzieć się po eksperymencie, że nie można uzyskać kluczowych danych.
S. Kolassa - Przywróć Monikę
(+1) Uważam, że głosowanie nad zamknięciem tego pytania jest nieco niewłaściwe
Robert Long,
@RobertLong, dlaczego tak mówisz? Pytam po prostu dlatego, że chcę się upewnić, że niczego nie brakuje w odpowiedzi, co czyni to mniej wiarygodnym.
Neelasha Bhattacharjee,

Odpowiedzi:

14

Uwagi ogólne

  • „Mam 10 klasę i staram się symulować dane dla projektu targów nauki maszynowego”. Niesamowite. W ogóle nie dbałem o matematykę w 10. klasie; Myślę, że wziąłem coś takiego jak Algebra 2 tego roku ...? Nie mogę się doczekać, aż zwolnisz mnie z pracy za kilka lat! Poniżej podaję kilka rad, ale: Czego próbujesz się nauczyć z tej symulacji? Co znasz już w statystyce i uczeniu maszynowym? Wiedza o tym pomogłaby mi (i innym) zebrać bardziej szczegółową pomoc.

  • Python jest bardzo przydatnym językiem, ale uważam, że R jest lepszy do symulacji danych. Większość książek / blogów / badań / zajęć, na które natknąłem się na symulowanie danych (również to, co ludzie nazywają „metodami Monte Carlo” jako wymyślnymi), jest w języku R. Język statystyczny jest znany przez statystyków, dla statystyk, „i większość naukowców - którzy opierają się na badaniach symulacyjnych w celu wykazania, że ​​ich metody działają - używa R. Wiele fajnych funkcji znajduje się w podstawowym języku R (to znaczy, nie są wymagane żadne dodatkowe pakiety), na przykład rnormdla normalnej dystrybucji, runifdla munduru dystrybucja, dystrybucja rbetabeta i tak dalej. W R wpisanie ?Distributionsspowoduje wyświetlenie na nich strony pomocy. Istnieje jednak wiele innych fajnych pakietów, takich jak mvtnormlubsimstudyktóre są przydatne. Poleciłbym DataCamp.com do nauki języka R, jeśli znasz tylko Python; Myślę, że są dobre do łagodnego wprowadzenia do rzeczy

  • Wygląda na to, że dużo się tu dzieje: chcesz danych, które są z czasem (podłużne), wewnątrz podmiotu (być może przy użyciu modelu wielopoziomowego) i mają do nich komponent sezonowy (być może model szeregów czasowych), wszystkie przewidujące dychotomiczny wynik (coś w rodzaju regresji logistycznej). Myślę, że wiele osób rozpoczynających studia symulacyjne (w tym ja) chce wrzucić wiele rzeczy na raz, ale może to być naprawdę zniechęcające i skomplikowane. Dlatego zalecałbym zacząć od czegoś prostego - na przykład zrobienia jednej lub dwóch funkcji do generowania danych - a następnie zbudować stamtąd.

Szczegółowe uwagi

Wygląda na to, że twoja podstawowa hipoteza brzmi: „Pora dnia pozwala przewidzieć, czy ktoś przyjmie leki”. I chcesz utworzyć dwa symulowane dwa zestawy danych: jeden, gdzie nie ma związku i jeden tam gdzie nie .

Wspominasz także o symulowaniu danych w celu reprezentowania wielu obserwacji tej samej osoby. Oznacza to, że każda osoba ma swoje własne prawdopodobieństwo przestrzegania, a także, być może, własne nachylenie zależności między porą dnia a prawdopodobieństwem przestrzegania. Sugerowałbym przyjrzenie się modelom regresji „wielopoziomowej” lub „hierarchicznej” dla tego rodzaju relacji, ale myślę, że można zacząć od czegoś prostszego.

Wspominasz także o ciągłym związku między czasem a prawdopodobieństwem zastosowania się do schematu leczenia, co sprawia, że ​​myślę, że modelowanie szeregów czasowych - szczególnie patrząc na trendy sezonowe - byłoby dla ciebie pomocne. Można to również symulować, ale myślę, że możemy zacząć od prostszego.

Załóżmy, że mamy 1000 osób i mierzymy, czy przyjmowali lek tylko raz. Wiemy również, czy przydzielono je do przyjmowania rano, po południu czy wieczorem. Powiedzmy, że przyjmowanie leku wynosi 1, a nie przyjmowanie 0. Możemy symulować dane dychotomiczne, używając rbinomdo rysowania z rozkładu dwumianowego. Każdą osobę możemy ustawić na 1 obserwację z danym prawdopodobieństwem. Powiedzmy, że ludzie mają 80% szans na przyjęcie rano, 50% po południu i 65% w nocy. Wklejam poniższy kod z kilkoma komentarzami po #:

set.seed(1839) # this makes sure the results are replicable when you do it
n <- 1000 # sample size is 1000
times <- c("morning", "afternoon", "evening") # create a vector of times
time <- sample(times, n, TRUE) # create our time variable

# make adherence probabilities based on time
adhere_prob <- ifelse(
  time == "morning", .80, 
  ifelse(
    time == "afternoon", .50, .65
  )
)

# simulate observations from binomial distribution with those probabilities
adhere <- rbinom(n, 1, adhere_prob)

# run a logistic regression, predicting adherence from time
model <- glm(adhere ~ time, family = binomial)
summary(model)

To podsumowanie pokazuje częściowo:

Coefficients:
            Estimate Std. Error z value Pr(>|z|)    
(Intercept)  0.02882    0.10738   0.268  0.78839    
timeevening  0.45350    0.15779   2.874  0.00405 ** 
timemorning  1.39891    0.17494   7.996 1.28e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1

InterceptReprezentuje popołudnie, i widzimy, że zarówno wieczorem i rano są znacznie wyższe prawdopodobieństwo przywierania. Istnieje wiele szczegółów na temat regresji logistycznej, których nie mogę wyjaśnić w tym poście, ale testy t zakładają, że masz zmienną zależną warunkowo normalnie dystrybuowaną. Modele regresji logistycznej są bardziej odpowiednie, gdy masz dychotomiczne wyniki (0 vs. 1) takie jak te. Większość książek o statystykach wprowadzających będzie mówić o t- teście, a wiele książek o wprowadzaniu do maszyn będzie mówić o regresji logistycznej. Myślę, że wprowadzenie do uczenia statystycznego: z aplikacjami w języku R jest świetne, a autorzy opublikowali wszystko online:https://www-bcf.usc.edu/~gareth/ISL/ISLR%20First%20Printing.pdf

Nie jestem pewien co do dobrych książek do badań symulacyjnych; Nauczyłem się po prostu grzebiąc, czytając to, co zrobili inni, i na studiach podyplomowych zacząłem obliczenia statystyczne (materiały profesora znajdują się tutaj: http://pj.freefaculty.org/guides/ ).

Na koniec możesz także przeprowadzić symulację bez efektu, ustawiając wszystkie czasy na takie samo prawdopodobieństwo:

set.seed(1839)
n <- 1000
times <- c("morning", "afternoon", "evening")
time <- sample(times, n, TRUE)
adhere <- rbinom(n, 1, .6) # same for all times
summary(glm(adhere ~ time, binomial))

Które zwraca:

Coefficients:
            Estimate Std. Error z value Pr(>|z|)    
(Intercept)  0.40306    0.10955   3.679 0.000234 ***
timeevening -0.06551    0.15806  -0.414 0.678535    
timemorning  0.18472    0.15800   1.169 0.242360    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1

Nie pokazuje to znaczących różnic między czasami, ponieważ można by oczekiwać, że prawdopodobieństwo będzie takie samo w czasie.

Mark White
źródło
Dziękuję bardzo za rekomendację książki! Właśnie tego potrzebowałem do czytania na wakacje!
MD-Tech,
Dziękuję bardzo za to! Wiedziałem, że potrzebuję modelu regresji logistycznej dla aspektu uczenia maszynowego w moim projekcie, ale wydaje się, że ma on również zastosowanie w symulacji danych. Miałem jednak wrażenie, że regresja logistyczna wymaga, aby kolejność czasów miała znaczenie, ale w tym przypadku tak nie jest, ponieważ za każdym razem jest inna kategoria bez związku z drugą. Doszedłem do tego wniosku po rozmowie z moim nauczycielem matematyki, ale obaj moglibyśmy bardzo się mylić. Czy możesz wyjaśnić, dlaczego dokładnie tutaj można zastosować regresję logistyczną?
Neelasha Bhattacharjee,
@NeelashaBhattacharjee Symulacja danych i dopasowanie modelu regresji logistycznej to dwa osobne kroki - moglibyśmy zasymulować te same dane i przeanalizować je przy użyciu tabeli awaryjnej i statystyki chi-kwadrat, gdybyśmy chcieli. Masz rację, że model, który pasuję, nie koduje żadnej kolejności w czasie. Modele regresji przyjmują jednak założenia dotyczące rozkładu zmiennej zależnej , a nie zmiennych niezależnych. Moglibyśmy zamówić predyktory, predyktory ciągłe, predyktory zliczające itp., A wszystkie z nich byłyby odpowiednie do regresji logistycznej.
Mark White,
@NeelashaBhattacharjee Można tu zastosować regresję logistyczną, ponieważ modelujemy dychotomiczną zmienną zależną - to znaczy jedną z dwoma i tylko dwoma możliwymi wynikami. To, co robi regresja logistyczna, polega na użyciu „funkcji łącza logistycznego”, aby dopasować wszystkie przewidywane wartości równania regresji (np. B0 + b1 * x) do przedziału od 0 do 1. I nazywamy te liczby prawdopodobieństwem, że ktoś ma zależna wartość zmiennej 1.
Mark White
Dziękuję bardzo! Zastanawiałem się jednak, w jaki sposób byłeś w stanie spojrzeć na wartości p między dwoma symulowanymi zestawami danych i ustalić, czy jeden miał znaczący trend, a drugi. Dla mnie oba zestawy mają wartości p, które różnią się na tyle, aby były znaczące.
Neelasha Bhattacharjee
4

Jeśli znasz już jakiś Python, na pewno będziesz w stanie osiągnąć to, czego potrzebujesz, używając podstawowego Pythona wraz z numpyi / lub pandas. Jak sugeruje Mark White, wiele rzeczy związanych z symulacjami i statystykami zapisano w R, więc na pewno warto je zobaczyć.

Poniżej znajduje się podstawowa struktura, w jaki sposób możesz podejść do tego przy użyciu klasy Python. Możesz użyćnp.random.normal do regulacji baseline_adherencekażdego obiektu i wstawić trochę szumu. Zapewnia to pseudolosowe przywiązanie, do którego można dodać ukierunkowane zmniejszone przywiązanie w określone dni.

import pandas as pd
import numpy as np

from itertools import product

class Patient:

    def __init__(self, number, baseline_adherence=0.95):
        self.number = number
        self.baseline_adherence = baseline_adherence
        self.schedule = self.create_schedule()

    def __repr__(self):
        return "I am patient number {}".format(self.number)

    def create_schedule(self):

        time_slots = []
        for (day, time) in product(range(1, 8), range(1, 4)):
            time_slots.append("Day {}; Slot {}".format(day, time))
        week_labels = ["Week {}".format(x) for x in range(1, 31)]
        df = pd.DataFrame(np.random.choice([0, 1],
                                           size=(30, 21),#1 row per week, 1 column per time slot
                                           p=(1-self.baseline_adherence, self.baseline_adherence)),
                          index=week_labels,
                          columns=time_slots
                         )
        return df

    def targeted_adherence(self, timeslot, adherence=0.8):

        if timeslot in self.schedule.columns:
            ad = np.random.choice([0, 1],
                                  size=self.schedule[timeslot].shape,
                                  p=(1-adherence, adherence)
                                 )
            self.schedule[timeslot] = ad


sim_patients = [Patient(x) for x in range(10)]
p = sim_patients[0]
p.targeted_adherence("Day 1; Slot 3")
Andrzej
źródło
1

To świetny projekt. Dla takich projektów jest wyzwanie, a twoja metoda wykorzystania danych symulowanych jest świetnym sposobem na ich ocenę.

Czy masz hipotezę a priori, np. „Ludzie bardziej zapominają wieczorem”? W takim przypadku przetestuje go test statystyczny porównujący częstotliwość zapominania wieczorem w porównaniu z porankiem. Jest to dystrybucja Bernoulliego, jak powiedzieli poprzedni respondenci.

Drugim podejściem jest przeszukiwanie danych w celu ustalenia, który przedział czasowy ma najwyższy wskaźnik awaryjności. Musi być jeden, więc pytanie brzmi: „czy to tylko przypadkowy wynik?”. W tym przypadku próg istotności jest wyższy. Jeśli chcesz o tym poczytać, wyszukaj „współczynnik fałszywych odkryć”.

W twoim przypadku system jest na tyle prosty, że można obliczyć próg przy odrobinie namysłu. Ale można również zastosować metodę ogólną: symuluj 1000 zestawów danych bez zmian prędkości, a następnie znajdź rozkład częstotliwości przypadkowych niskich liczb. Porównaj z nim swój prawdziwy zestaw danych. Jeśli 13.00 jest rzadkim przedziałem danych rzeczywistych, ale symulowane zestawy danych 50/1000 mają równie rzadkie przedziały, wynik nie jest solidny.

chrishmorris
źródło