如何模拟具有统计意义的数据?


18

我正在读10年级,正在寻找模拟机器学习科学博览会项目的数据的方法。最终模型将用于患者数据,并将预测一周中某些时间与其在单个患者数据内对药物依从性的影响之间的相关性。坚持值将是二进制的(0表示未服用药物,1表示已服用药物)。我正在寻找一种机器学习模型,该模型能够从一周中的时间之间的关系中学习,并将一周分为21个时间段,一天中的每个时间段分为三个时间段(1是星期一上午,2是星期一下午,等等。)。我正在寻找模拟1,000名患者的数据。每位患者将获得30周的数据。我想插入与一周的时间和遵守相关的某些趋势。例如,在一个数据集中,我可以说一周中的第7个时隙与依从性在统计上有显着关系。为了确定该关系是否具有统计显着性,要求我执行两个样本t检验,将一个时隙与其他每个时隙进行比较,并确保显着性值小于0.05。

但是,与其模拟自己的数据并检查我插入的趋势是否显着,不如倒退工作,也许我使用一个程序,要求我在一定的时隙内分配一个重要的趋势,并坚持执行。二进制数据中包含我所要求的趋势,以及其他时隙中的二进制数据,其中包含一些噪声但没有产生统计上显着的趋势。

是否有任何程序可以帮助我实现这样的目标?或者也许是python模块?

任何帮助(甚至对我的项目的一般性评论)将不胜感激!!


4
这是一个很好的问题。在研究设计阶段,大多数科学家申请资助之前应该做的是这样的事情。我经常看到人们首先收集他们的数据,然后试图弄清楚如何对其进行分析,以致用罗纳德·费舍尔Ronald Fisher)的话说,统计学家可能只能说出实验的死因。
S. Kolassa-恢复莫妮卡

@StephanKolassa但是,很难在某些实验中用人类数据来评估哪些数据将可用,而在其他情况下,则使用可用的并且无法收集更多的数据...
llrs

2
@llrs:完全正确。它当然应该为模拟练习提供信息。最好事先考虑可用的数据,而不是在实验发现无法获取关键数据。
S. Kolassa-恢复莫妮卡

(+1)我发现结束这个问题的投票有些令人反感
罗伯特·隆

@RobertLong,你为什么这么说?我之所以问是因为我想确保我不会在响应中遗漏任何使其不那么可信的内容。
Neelasha Bhattacharjee

Answers:


14

普通的留言

  • “我正在读10年级,我正在为机器学习科学博览会项目模拟数据。” 太棒了 我根本不关心十年级的数学;我想那年我选了像代数2这样的东西...?我等不及要等你几年后辞职!我在下面提供一些建议,但是:您想从该模拟中学到什么?您已经在统计和机器学习领域熟悉什么?知道这一点将对我(和其他人)提供一些更具体的帮助。

  • Python是一种非常有用的语言,但我认为R更适合模拟数据。我在模拟数据时遇到的大多数书籍/博客/研究/课程(也有人称其为“蒙特卡洛方法”)是R。R语言被“统计学家”称为“统计学家,对于统计学家来说, ”,并且大多数依靠模拟研究来证明其方法有效的学者都使用R。许多很酷的功能都使用R语言(即不需要额外的软件包),例如rnorm正态分布,runif统一分布,rbeta用于beta分布等等。在R中,键入?Distributions将显示有关它们的帮助页面。但是,还有许多其他很酷的软件包,例如mvtnormsimstudy这很有用。如果您只了解Python,我建议您使用DataCamp.com来学习R。我认为它们对于轻轻地介绍事物很有好处

  • 看来您正在做很多事情:您想要的是随时间推移(纵向),主题内(也许使用多级模型)的数据,并具有季节性成分(也许是时间序列模型),所有这些数据都可以预测二分法的结果(类似于逻辑回归)。我认为很多开始进行模拟研究的人(包括我自己)都想一次投入很多东西,但这确实很艰巨和复杂。因此,我建议做的事情从简单的事情开始(也许要创建一两个函数来生成数据),然后从那里开始构建。

具体评论

看起来您的基本假设是:“一天中的时间可以预测某人是否坚持服药。” 你想要两张创建两个模拟数据集:一是那里一个关系,一个地方有没有

您还提到了模拟数据以代表同一个人的多个观察结果。这意味着每个人都有自己的依从概率以及一天中的时间与依附概率之间的关系的斜率。我建议针对这种类型的关系研究“多级”或“分层”回归模型,但我认为您可以比这更简单。

另外,您提到时间和遵守药物治疗方案的可能性之间的连续关系,这也使我认为时间序列建模(特别是关注季节性趋势)将对您有所帮助。这也是可以模拟的,但是我想我们可以更简单地开始。

假设我们有1000人,我们衡量他们是否只吃过一次药。我们还知道他们是否被分配在早上,下午或晚上参加。假设吃药为1,而不是为0。我们可以使用rbinom二项式分布的平局来模拟二分数据。我们可以将每个人设置为具有给定概率的1个观察值。假设人们早上有80%的可能性,下午有50%的可能性,晚上有65%的可能性。我将以下代码粘贴到以下代码中#

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)

此摘要部分显示:

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

Intercept代表下午,我们可以看到,晚上和早晨都是秉承的概率显著较高。关于逻辑回归的很多细节我在这篇文章中无法解释,但是t检验假定您有一个条件正态分布的因变量。当您有这样的二分(0 vs. 1)结果时,逻辑回归模型更合适。大多数入门级统计书籍都将讨论t检验,并且很多入门级机器学习书籍都将讨论逻辑回归。我认为《统计学习入门:R中的应用程序》很棒,作者将全部内容在线发布:https://www-bcf.usc.edu/~gareth/ISL/ISLR%20First%20Printing.pdf

我不确定模拟研究的好书;我只是从四处闲逛,阅读别人所做的事情以及从统计学课程的研究生课程中学到了东西(教授的资料在这里:http : //pj.freefaculty.org/guides/)。

最后,您还可以通过将所有时间都设置为具有相同的概率来模拟无效:

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

哪个返回:

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

这表明时间之间没有显着差异,正如我们从时间跨度相同的可能性中所期望的那样。


非常感谢您的推荐书!正是我度假读书所需要的!
MD-Tech

非常感谢你做的这些!我知道我需要一个逻辑回归模型来进行项目的机器学习,但是它似乎在模拟数据方面也有应用。但是,我的印象是逻辑回归需要时间顺序重要,但是在这种情况下,情况并非如此,因为每次都是不同的类别,彼此之间没有关系。在与我的数学老师讨论后,我得出了这个结论,但是我们两个人很可能是错的。您能否阐明为什么可以在此处使用精确的逻辑回归?
Neelasha Bhattacharjee

@NeelashaBhattacharjee模拟数据和拟合logistic回归模型是两个单独的步骤-如果需要,我们可以模拟相同的数据,并使用列联表和卡方统计量对其进行分析。您是正确的,我适合的模型没有按时间编码任何顺序。但是,回归模型假设变量而不是自变量的分布方式。我们可以订购预测变量,连续预测变量,计数预测变量等,并且所有这些变量都适合进行逻辑回归。
马克·怀特

@NeelashaBhattacharjee在这里可以使用逻辑回归,因为我们正在建模一个二分法因变量,即一个具有两个且只有两个可能结果的因变量。逻辑回归的作用是使用“逻辑链接函数”使回归方程的所有预测值(例如,b0 + b1 * x)都介于0和1之间。我们称这些数字为某人具有1.因变量值
马克白

非常感谢!但是,我想知道您如何查看两个模拟数据集之间的p值,并确定一个是否具有显着趋势,另一个是否具有显着趋势。对我来说,这两个集合的p值相差很大,都非常重要。
Neelasha Bhattacharjee

4

如果您已经知道一些Python,那么使用基本Python和numpy和/或一定可以实现所需的功能pandas。正如Mark White所建议的那样,R中包含了大量与模拟和统计相关的内容,因此绝对值得一看。

以下是一个基本框架,用于说明如何使用Python类进行处理。您可以使用np.random.normal调整baseline_adherence每个主题的,以插入一些噪音。这为您提供了伪随机遵守,您可以在特定日期向其添加目标减少的遵守。

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

1

这是一个伟大的项目。这样的项目面临挑战,您使用模拟数据的方法是评估它的好方法。

您是否有先验假设,例如“人们在晚上更健忘”?在这种情况下,比较晚上和早上忘记频率的统计测试将对其进行测试。如先前的响应者所说,这是伯努利分布。

另一种方法是拖曳数据以找出哪个时隙的故障率最高。必然会有一个,所以问题是“这仅仅是偶然的结果吗?”。在这种情况下,重要性阈值较高。如果您想阅读有关此内容,请搜索“错误发现率”。

在您的情况下,该系统非常简单,您可以稍加思考就可以计算阈值。但是,也可以使用一般方法:将没有速率变化的1000个数据集同化,然后找出同时发生的低数的频率分布。比较您的真实数据集。如果1pm是实际数据中的稀疏时隙,但是50/1000个模拟数据集具有同样稀疏的时隙,则结果并不可靠。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.