統計的に有意になるようにデータをシミュレートする方法は?


18

私は10年生で、機械学習サイエンスフェアプロジェクトのデータをシミュレートしたいと考えています。最終モデルは患者データで使用され、特定の時間帯と、これが単一患者のデータ内の服薬遵守に与える影響との相関関係を予測します。順守値はバイナリになります(0は薬を服用しなかったことを意味し、1は服用したことを意味します)。私は、週の時間の関係から学習できる機械学習モデルを作成し、週を21の時間帯に分けています。1時間ごとに3つ(1は月曜日の朝、2は月曜日の午後、等。)。1,000人の患者に相当するデータをシミュレートしたいと考えています。各患者には30週間分のデータがあります。週の時間とアドヒアランスに関連する特定のトレンドを挿入したいと思います。例えば、あるデータセットでは、週の時間帯7は順守と統計的に有意な関係があると言えます。関係が統計的に有意であるかどうかを判断するには、1つのタイムスロットを他のタイムスロットと比較する2サンプルt検定を実行し、有意値が0.05未満であることを確認する必要があります。

ただし、自分のデータをシミュレートして挿入した傾向が重要かどうかを確認するのではなく、逆方向に作業して、特定のタイムスロットに重要な傾向を順守して割り当てることができるプログラムを使用すると、戻りますその中に私が求めたトレンドを含むバイナリデータ、およびノイズを含むが統計的に有意なトレンドを生成しない他のタイムスロットのバイナリデータ。

このようなことを達成するのに役立つプログラムはありますか?それとも、Pythonモジュールですか?

どんな助けでも(私のプロジェクトに関する一般的なコメントでさえ)非常に感謝されます!


4
これは素晴らしい質問です。そして、このようなことは、研究デザイン段階において、ほとんどの科学者が助成金を申請する前にすべきことです。私はあまりにも多くの場合、人々が最初に自分のデータを収集し、統計学者だけの言葉では、実験はで死亡したものを伝えることができるかもしれその結果、後でそれを分析する方法を見つけ出すことを試みることがわかりロナルド・フィッシャー
S. Kolassa -復活モニカ

@StephanKolassaはしかし、データがヒトのデータといくつかの実験で利用できるようになりますどのようなロバに非常に困難であり、他の設定1の用途データに利用可能であるとコレクトもっと...することはできません
LLRの

2
@llrs:それは完全に正しいです。そして、それはもちろん、シミュレーション演習に通知する必要があります。事前に考える方が良い実験に重要なデータを取得できないことを知るよりも、利用可能なデータについてとよいでしょう。
S. Kolassa -復活モニカ

(+1)この質問を終了する投票はいくぶん好ましくないと思います
ロバートロング

@RobertLong、なぜあなたはそれを言うのですか?単純に尋ねるのは、信頼性を低下させるような応答で何かを見逃していないことを確認したいからです。
ニーラシャバタチャルジー

回答:


14

一般的なコメント

  • 「私は10年生で、機械学習サイエンスフェアプロジェクトのデータをシミュレートしたいと考えています。」驚くばかり。私は10年生の数学を全く気にしませんでした。私はその年に代数2のようなものを取ったと思う...?数年後にあなたが私を失業させるまで待ちきれません!以下にいくつかアドバイスをしますが、このシミュレーションから何を学ぼうとしていますか?統計や機械学習ですでに知っていることは何ですか?これを知ることは、私(および他の人)がより具体的なヘルプをまとめるのに役立ちます。

  • Pythonは非常に便利な言語ですが、データのシミュレーションにはRの方が優れていると思います。データのシミュレーションで出会ったほとんどの本/ブログ/研究/クラス(また、人々が「モンテカルロ法」と呼ぶもの)はRにあります。R言語は、「統計学者、統計学者、シミュレーション研究に基づいてメソッドの動作を確認するほとんどのアカデミックは、Rを使用します。rnorm正規分布、runifユニフォームなど、多くのクールな関数はベースR言語にあります(つまり、追加のパッケージは不要です)配布、rbetaベータ配布など。Rでは、入力する?Distributionsとヘルプページが表示されます。しかし、mvtnormまたはのような他の多くのクールなパッケージがありますsimstudyそれは便利です。Pythonしか知らない場合は、Rの学習にDataCamp.comをお勧めします。物事を優しく紹介するのに良いと思う

  • ここでは多くのことが行われているようです:経時的(縦方向)、被験者内(多レベルモデルを使用)、季節的コンポーネント(おそらく時系列モデル)を持ち、すべて予測するデータが必要です二分した結果(ロジスティック回帰のようなもの)。シミュレーションの研究を始めた多くの人(私を含む)は一度にたくさんのものを投げ入れたいと思っていますが、これは非常に困難で複雑な場合があります。ですから、私がやることは、データを生成するための関数を1つまたは2つ作成するなど、単純なものから始めて、そこから構築することです。

特定のコメント

あなたの基本的な仮説は次のように見えます:「一日の時間は、誰かが薬を服用することに固執するかどうかを予測します。」そして、2つのシミュレーションデータセットを作成します。1つ関係があり、もう1つは関係がありません

また、同じ人物からの複数の観測値を表すデータのシミュレーションについても言及します。これは、各人が自分の順守の可能性だけでなく、おそらく、時刻と順守の可能性の間の関係についての自分の傾きを持つことを意味します。このタイプの関係の「マルチレベル」または「階層」回帰モデルを検討することをお勧めしますが、これよりも簡単に始めることができると思います。

また、時間と投薬レジメンを順守する確率との間の継続的な関係に言及しているため、時系列モデリング(特に季節的な傾向を見る)が役立つと思います。これもシミュレーション可能ですが、繰り返しますが、もっと簡単に始められると思います。

私たちには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対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-テック

本当にありがとうございました!私はプロジェクトの機械学習の側面にロジスティック回帰モデルが必要であることを知っていましたが、データのシミュレーションにもアプリケーションがあるようです。しかし、ロジスティック回帰は時間の順序が重要であると考える印象を受けましたが、この場合、各時間は互いに関係のない異なるカテゴリであるため、そうではありません。私は数学の先生と話し合った後、この結論に至りましたが、私たち二人とも間違っている可能性があります。ここでロジスティック回帰を正確に使用できる理由を明確にしてください。
ニーラシャバチャータジー

@NeelashaBhattacharjeeデータのシミュレーションとロジスティック回帰モデルのフィッティングは2つの別個のステップです。同じデータをシミュレートし、必要に応じて分割表とカイ2乗統計を使用して分析することもできます。あなたが正しいのは、私が適合しているモデルは、時間内に順序をエンコードしないことです。ただし、回帰モデルでは、独立変数ではなく、従属変数の分布方法を想定しています。順序付けられた予測子、連続予測子、カウント予測子などを使用できますが、それらはすべてロジスティック回帰に適しています。
マークホワイト

@NeelashaBhattacharjeeここではロジスティック回帰を使用できます。これは、2つの従属変数(つまり、2つだけの可能な結果を​​持つモデル)をモデリングしているためです。ロジスティック回帰では、「ロジスティックリンク関数」を使用して、回帰方程式(b0 + b1 * xなど)のすべての予測値を0〜1の範囲に収めます。そして、これらの数値を、 1の従属変数値
マーク・ホワイト

どうもありがとうございます!ただし、2つのシミュレートされたデータセット間のp値を調べて、一方が有意な傾向を示したのか、他方が傾向を示したのかを判断する方法を知りたいと思いました。私にとって、両方のセットには、有意になるほど十分に異なるp値があります。
ニーラシャバタチャルジー

4

すでにPythonを知っている場合は、numpyおよび/またはとともにベースPythonを使用して、必要なものを確実に実現できます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

これは素晴らしいプロジェクトです。このようなプロジェクトには課題があり、シミュレートされたデータを使用する方法は、それを評価する優れた方法です。

「夕方の方が物忘れが多い」といった先験的な仮説はありますか?その場合、夕方の忘却の頻度を朝と比較する統計的テストでテストされます。以前のレスポンダーが言ったように、これはベルヌーイ分布です。

もう1つの方法は、データをトロールして、どのタイムスロットの障害率が最も高いかを調べることです。あるはずなので、質問は「これは単なる偶然の結果ですか?」です。この場合、有意性のしきい値は高くなります。これについて詳しく知りたい場合は、「false discovery rate」を検索してください。

あなたの場合、システムは十分に単純なので、少し考えてしきい値を計算できます。しかし、一般的な方法を使用することもできます。1000個のデータセットをレート変動なしで同化してから、偶然の低い数の頻度分布を見つけます。実際のデータセットを比較してください。1pmが実際のデータのスパーススロットであるが、50/1000のシミュレートされたデータセットに同等のスパーススロットがある場合、結果はロバストではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.