パーセンテージデータにはどのような曲線(またはモデル)を適合させる必要がありますか?


15

ウイルスコピーとゲノムカバレッジ(GCC)の関係を示す図を作成しようとしています。これは私のデータのようです:

ウイルス量とGCC

最初、私は線形回帰をプロットしましたが、スーパーバイザーはそれが間違っていると私に言って、シグモイド曲線を試してみました。そこで、geom_smoothを使用してこれを行いました。

library(scales)
ggplot(scatter_plot_new, aes(x = Copies_per_uL, y = Genome_cov, colour = Virus)) +
    geom_point() +
    scale_x_continuous(trans = log10_trans(), breaks = trans_breaks("log10", function(x) 10^x), labels = trans_format("log10", math_format(10^.x))) +
        geom_smooth(method = "gam", formula = y ~ s(x), se = FALSE, size = 1) +
    theme_bw() +
    theme(legend.position = 'top', legend.text = element_text(size = 10), legend.title = element_text(size = 12), axis.text = element_text(size = 10), axis.title = element_text(size=12), axis.title.y = element_text(margin = margin (r = 10)), axis.title.x = element_text(margin = margin(t = 10))) +
    labs(x = "Virus copies/µL", y = "GCC (%)") +
    scale_y_continuous(breaks=c(25,50,75,100))

ウイルス量とGCC-geom_smooth

しかし、私の監督者は、カーブがGCCが100%を超える可能性があるように見えるため、これも間違っていると言いますが、不可能です。

私の質問は、ウイルスコピーとGCCの関係を示す最良の方法は何ですか?A)ウイルスのコピー数が少ない= GCCが低く、B)一定量のウイルスがGCCのプラトーをコピーした後、それを明確にしたい。

GAM、LOESS、ロジスティック、ピースワイズなど、さまざまな方法を調査しましたが、データに最適な方法を判断する方法がわかりません。

編集:これはデータです:

>print(scatter_plot_new)  
Subsample   Virus   Genome_cov  Copies_per_uL
1   S1.1_RRAV   RRAV    100 92500
2   S1.2_RRAV   RRAV    100 95900
3   S1.3_RRAV   RRAV    100 92900
4   S2.1_RRAV   RRAV    100 4049.54
5   S2.2_RRAV   RRAV    96.9935 3809
6   S2.3_RRAV   RRAV    94.5054 3695.06
7   S3.1_RRAV   RRAV    3.7235  86.37
8   S3.2_RRAV   RRAV    11.8186 84.2
9   S3.3_RRAV   RRAV    11.0929 95.2
10  S4.1_RRAV   RRAV    0   2.12
11  S4.2_RRAV   RRAV    5.0799  2.71
12  S4.3_RRAV   RRAV    0   2.39
13  S5.1_RRAV   RRAV    4.9503  0.16
14  S5.2_RRAV   RRAV    0   0.08
15  S5.3_RRAV   RRAV    4.4147  0.08
16  S1.1_UMAV   UMAV    5.7666  1.38
17  S1.2_UMAV   UMAV    26.0379 1.72
18  S1.3_UMAV   UMAV    7.4128  2.52
19  S2.1_UMAV   UMAV    21.172  31.06
20  S2.2_UMAV   UMAV    16.1663 29.87
21  S2.3_UMAV   UMAV    9.121   32.82
22  S3.1_UMAV   UMAV    92.903  627.24
23  S3.2_UMAV   UMAV    83.0314 615.36
24  S3.3_UMAV   UMAV    90.3458 632.67
25  S4.1_UMAV   UMAV    98.6696 11180
26  S4.2_UMAV   UMAV    98.8405 12720
27  S4.3_UMAV   UMAV    98.7939 8680
28  S5.1_UMAV   UMAV    98.6489 318200
29  S5.2_UMAV   UMAV    99.1303 346100
30  S5.3_UMAV   UMAV    98.8767 345100

6
これは0〜100%の範囲にあるため、ロジスティック回帰が最適だと思われます。
mkt-モニカの復活

1
(2)区分的(線形)モデルを試してください。
user158565

3
元のggplotコードにmethod.args=list(family=quasibinomial))引数を追加してみてgeom_smooth()ください。
ベンボルカー

4
PSで標準エラーを抑制しないことをお勧めしますse=FALSE。不確実性が実際にどれほど大きいかを人々に示すのは常に素晴らしいことです...
ベンボルカー

2
移行領域に十分なデータポイントがないため、なめらかな曲線が存在するという権限を主張できません。あなたが示しているポイントにヘビサイド関数を簡単に適合させることができました。
カールヴィットフト

回答:


6

これを回避する別の方法は、ベイズの定式化を使用することです。最初は少し重いかもしれませんが、問題の詳細を表現するのがはるかに簡単になる傾向があります。は

スタンは比較的使いやすいプログラムインターフェイスを備えたモンテカルロサンプラーであり、ライブラリはRなどで使用できますが、ここではPythonを使用しています

私たちは他のすべての人と同様にシグモイドを使用します。これには生化学的な動機があり、数学的に非常に便利です。このタスクの素晴らしいパラメーター化は次のとおりです。

import numpy as np

def sigfn(x, alpha, beta):
    return 1 / (1 + np.exp(-(x - alpha) * beta))

ここalphaで、シグモイド曲線の中点(つまり、50%を交差する場所)をbeta定義し、勾配を定義します。ゼロに近い値は平坦です。

これがどのように見えるかを示すために、データを取得してプロットできます:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_table('raw_data.txt', delim_whitespace=True)
df.columns = ['subsample', 'virus', 'coverage', 'copies']
df.coverage /= 100

x = np.logspace(-1, 6, 201)
plt.semilogx(x, sigfn(np.log(x), 5.5, 3), label='sigfn', color='C2')

sns.scatterplot(df.copies, df.coverage, hue=df.virus, edgecolor='none')

ここraw_data.txtにはあなたが与えたデータが含まれており、カバレッジをより有用なものに変換しました。係数5.5と3は見栄えがよく、他の回答と非常によく似たプロットを示します。

プロットデータと手動フィット

Stanを使用してこの関数を「適合」させるには、RとC ++を組み合わせた独自の言語を使用してモデルを定義する必要があります。単純なモデルは次のようになります。

data {
    int<lower=1> N;  // number of rows
    vector[N] log_copies;
    vector<lower=0,upper=1>[N] coverage;
}
parameters {
    real alpha;
    real beta;
    real<lower=0> sigma;
}
model {
    vector[N] mu;
    mu = 1 ./ (1 + exp(-(log_copies - alpha) * beta));

    sigma ~ cauchy(0, 0.1);
    alpha ~ normal(0, 5);
    beta ~ normal(0, 5);

    coverage ~ normal(mu, sigma);
}

うまくいけばOKと表示されます。dataモデルparametersをサンプリングし、サンプリングするものをmodel定義し、尤度関数を定義するときに期待するデータを定義するブロックがあります。スタンにモデルを「コンパイル」するように指示します。これにはしばらく時間がかかります。その後、いくつかのデータを使用してモデルからサンプリングできます。例えば:

import pystan

model = pystan.StanModel(model_code=code)
model.sampling(data=dict(
    N=len(df),
    log_copies=np.log(df.copies),
    coverage=df.coverage,
), iter=10000, chains=4, thin=10)

import arviz
arviz.plot_trace(fit)

arviz 素敵な診断プロットを簡単にしますが、近似を印刷すると、Rスタイルのパラメーターの概要がわかります。

4 chains, each with iter=10000; warmup=5000; thin=10; 
post-warmup draws per chain=500, total post-warmup draws=2000.

        mean se_mean     sd   2.5%    25%    50%    75%  97.5%  n_eff   Rhat
alpha   5.51  6.0e-3   0.26   4.96   5.36   5.49   5.64   6.12   1849    1.0
beta    2.89    0.04   1.71   1.55   1.98   2.32   2.95   8.08   1698    1.0
sigma   0.08  2.7e-4   0.01   0.06   0.07   0.08   0.09    0.1   1790    1.0
lp__   57.12    0.04   1.76   52.9   56.1  57.58  58.51  59.19   1647    1.0

上の大きな標準偏差betaは、データが実際にこのパラメーターに関する多くの情報を提供しないことを示しています。また、モデルの適合で有効桁数が10桁​​以上の回答の一部は、やや誇張されています

いくつかの答えは、各ウイルスが独自のパラメータを必要とする可能性があると指摘したため、「ウイルス」ごとに許可alphaおよびbeta変更できるようにモデルを拡張しました。少しalpha手間がかかりますが、2つのウイルスの値はほぼ確実に異なります(つまり、同じカバレッジに対してRRAVのコピー/μLがさらに必要です)。これを示すプロットは次のとおりです。

データとMCサンプルのプロット

データは以前と同じですが、後部の40サンプルについて曲線を描いています。 同じ勾配に従ってより高いコピー数を必要とするか、より急な勾配と同様のコピー数を必要とする可能性がありますがUMAV、比較的よく決定されているようRRAVです。後部腫瘤のほとんどは、より高いコピー数を必要としていますが、この不確実性は、異なるものを見つける他の答えの違いの一部を説明するかもしれません

私は主にスタンに対する私の知識を向上させるための練習としてこれに答えることを使用し、誰もがこれを複製することに興味/望んでいる場合に備えて、このJupyterノートをここに入れました。


14

(以下のコメントを考慮して編集。@ BenBolkerと@WeiwenNgに有益な情報を提供してくれてありがとう。)

分数ロジスティック回帰をデータに適合させます。0から100%の範囲にあり、生物学の多くの分野で理論的に正当化されたパーセンテージデータに適しています。

プログラムはデータが0から1の範囲であると頻繁に予測するため、すべての値を100で除算する必要がある場合があることに注意してください。代わりに準二項分布。

コードに基づいて、興味のある2つのウイルスがあり、それらが異なるパターンを示す(ウイルスの種類とコピー数の間に相互作用がある可能性がある)などの仮定をしました。

まず、モデルの適合:

dat <- read.csv('Book1.csv')
dat$logcopies <- log10(dat$Copies_per_uL)
dat$Genome_cov_norm <- dat$Genome_cov/100

fit <- glm(Genome_cov_norm ~ logcopies * Virus, data = dat, family = quasibinomial())
summary(fit)


Call:
glm(formula = Genome_cov_norm ~ logcopies * Virus, family = quasibinomial(), 
    data = dat)

Deviance Residuals: 
     Min        1Q    Median        3Q       Max  
-0.55073  -0.13362   0.07825   0.20362   0.70086  

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)  
(Intercept)          -5.9702     2.8857  -2.069   0.0486 *
logcopies             2.3262     1.0961   2.122   0.0435 *
VirusUMAV             2.6147     3.3049   0.791   0.4360  
logcopies:VirusUMAV  -0.6028     1.3173  -0.458   0.6510  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for quasibinomial family taken to be 0.6934319)

    Null deviance: 30.4473  on 29  degrees of freedom
Residual deviance:  2.7033  on 26  degrees of freedom

p値を信頼する場合、出力は2つのウイルスが有意に異なることを示唆しません。これは以下の@NickCoxの結果と対照的ですが、異なる方法を使用しました。30のデータポイントについては、どちらの方法でもあまり自信がありません。

第二に、プロット:

出力を自分で視覚化する方法をコーディングするのは難しくありませんが、ほとんどの作業を行うggPredictパッケージがあるようです(それを保証することはできません。自分で試したことはありません)。コードは次のようになります。

library(ggiraphExtra)
ggPredict(fit) + theme_bw(base_size = 20) + geom_line(size = 2) 

更新:コードまたはggPredict関数をより一般的にお勧めしなくなりました。試してみたところ、プロットされたポイントは入力データを正確に反映していないが、代わりに何らかの奇妙な理由で変更されていることがわかりました(プロットされたポイントの一部は1を超え0未満でした)。したがって、自分でコーディングすることをお勧めしますが、それはより多くの作業です。


7
私はこの答えを支持しますが、明確化のポイントを作りたいと思います。この分数ロジスティック回帰と呼びます。この用語はもっと広く認識されると思います。ほとんどの人が「ロジスティック回帰」を聞いたとき、0/1の従属変数を考えているに違いありません。この命名法を扱う一つの良いStackexchangeの答えはここにある:stats.stackexchange.com/questions/216122/...
Weiwenン

2
@teaelleceecee明らかに、最初にカバレッジを100で割る必要があります。
ニックコックス

4
family=quasibinomial()警告(および厳密すぎる分散の仮定を伴う根本的な問題)を避けるために使用します。他の問題に関する@mktのアドバイスを受けてください。
ベンボルカー

2
これは機能するかもしれませんが、関数を適合させるに、実際にデータがその関数に従うべきであるという前提があるべきだと人々に警告したいと思います。そうしないと、フィット関数を選択するときにランダムに撮影していることになり、結果にだまされる可能性があります。
カールウィットフト

6
@CarlWitthoft私たちは説教を聞きますが、奉仕の外の罪人です。他のコメントでヘビサイド関数を提案するに至った前提は何ですか?ここでの生物学は、急激なしきい値での移行に似ていません。ここで私が理解している研究の事実は、形式理論はデータよりも弱いということです。私は同意します:人々がステップ関数が理にかなっていると思うなら、彼らはそれに合うべきです。
ニックコックス

11

これは@mktと異なる答えではありませんが、特にグラフはコメントに収まりません。まず、Stataのロジスティック曲線を(予測子をログに記録した後)すべてのデータに適合させ、このグラフを取得します

ここに画像の説明を入力してください

方程式は

100 invlogit(-4.192654 + 1.880951 log10Copies))

次に、インジケータ変数を定義するウイルスの最も単純なシナリオで、各ウイルスの曲線を個別に適合させます。記録用のStataスクリプトは次のとおりです。

clear 
input id str9 Subsample   str4 Virus   Genome_cov  Copies_per_uL
1   S1.1_RRAV   RRAV    100 92500
2   S1.2_RRAV   RRAV    100 95900
3   S1.3_RRAV   RRAV    100 92900
4   S2.1_RRAV   RRAV    100 4049.54
5   S2.2_RRAV   RRAV    96.9935 3809
6   S2.3_RRAV   RRAV    94.5054 3695.06
7   S3.1_RRAV   RRAV    3.7235  86.37
8   S3.2_RRAV   RRAV    11.8186 84.2
9   S3.3_RRAV   RRAV    11.0929 95.2
10  S4.1_RRAV   RRAV    0   2.12
11  S4.2_RRAV   RRAV    5.0799  2.71
12  S4.3_RRAV   RRAV    0   2.39
13  S5.1_RRAV   RRAV    4.9503  0.16
14  S5.2_RRAV   RRAV    0   0.08
15  S5.3_RRAV   RRAV    4.4147  0.08
16  S1.1_UMAV   UMAV    5.7666  1.38
17  S1.2_UMAV   UMAV    26.0379 1.72
18  S1.3_UMAV   UMAV    7.4128  2.52
19  S2.1_UMAV   UMAV    21.172  31.06
20  S2.2_UMAV   UMAV    16.1663 29.87
21  S2.3_UMAV   UMAV    9.121   32.82
22  S3.1_UMAV   UMAV    92.903  627.24
23  S3.2_UMAV   UMAV    83.0314 615.36
24  S3.3_UMAV   UMAV    90.3458 632.67
25  S4.1_UMAV   UMAV    98.6696 11180
26  S4.2_UMAV   UMAV    98.8405 12720
27  S4.3_UMAV   UMAV    98.7939 8680
28  S5.1_UMAV   UMAV    98.6489 318200
29  S5.2_UMAV   UMAV    99.1303 346100
30  S5.3_UMAV   UMAV    98.8767 345100
end 

gen log10Copies = log10(Copies)
gen Genome_cov_pr = Genome_cov / 100
encode Virus, gen(virus)
set seed 2803 
fracreg logit Genome_cov_pr log10Copies i.virus, vce(bootstrap, reps(10000)) 

twoway function invlogit(-5.055519 + 1.961538 * x), lc(orange) ra(log10Copies)      ///
|| function invlogit(-5.055519 + 1.233273 + 1.961538 * x), ra(log10Copies) lc(blue) ///
|| scatter Genome_cov_pr log10Copies if Virus == "RRAV", mc(orange) ms(Oh)          ///
|| scatter Genome_cov_pr log10Copies if Virus == "UMAV", mc(blue) ms(+)             ///
legend(order(4 "UMAV" 3 "RRAV") pos(11) col(1) ring(0))                             ///
xla(-1 "0.1" 0 "1" 1 "10" 2 "100" 3 "10{sup:3}" 4 "10{sup:4}" 5 "10{sup:5}")        ///
yla(0 .25 "25" .5 "50" .75 "75" 1 "100", ang(h))                                    ///
ytitle(Genome coverage (%)) xtitle(Genome copies / {&mu}L) scheme(s1color) 

これは小さなデータセットを強く推し進めていますが、ウイルスのP値は2つの曲線を一緒に適合させることを支持しているように見えます。

Fractional logistic regression                  Number of obs     =         30
                                                Replications      =     10,000
                                                Wald chi2(2)      =      48.14
                                                Prob > chi2       =     0.0000
Log pseudolikelihood = -6.9603063               Pseudo R2         =     0.6646

-------------------------------------------------------------------------------
              |   Observed   Bootstrap                         Normal-based
Genome_cov_pr |      Coef.   Std. Err.      z    P>|z|     [95% Conf. Interval]
--------------+----------------------------------------------------------------
  log10Copies |   1.961538   .2893965     6.78   0.000     1.394331    2.528745
              |
        virus |
        UMAV  |   1.233273   .5557609     2.22   0.026     .1440018    2.322544
        _cons |  -5.055519   .8971009    -5.64   0.000    -6.813805   -3.297234
-------------------------------------------------------------------------------

ここに画像の説明を入力してください


3

シグモイドを試す関数を。ロジスティック曲線を含むこの形状には多くの定式化があります。双曲線正接は別の一般的な選択肢です。

プロットを考えると、単純なステップ関数も除外できません。ステップ関数と任意の数のシグモイド仕様を区別することはできないと思います。パーセンテージが50%の範囲にある観測値がないため、単純なステップ定式化が最も複雑な選択であり、より複雑なモデルよりも性能が劣ることはありません。


σバツ=121+タンバツ2

2
@JGは、「シグモイドは、」私の知る限りは心配として、S字カーブの総称であるが、あなたシグモイドの2つの仕様の間のリンクをポイントにしている権利
Aksakal

2

ここで4PL「バイオアッセイの検出限界を決定し、比較するための統計的方法」CAホルスタイン、M.グリフィン、J.香港、PDサンプソン、当たりとして式(4パラメータロジスティック)嵌合し、双方が制約と制約のない、あるアナル。Chem。 87(2015)9795-9801。4PL方程式は両方の図に示されており、パラメーターの意味は次のとおりです。

図1は、aを0%に、dを100%に制限します。

図1 aおよびdの制約

図2には、4PL方程式の4つのパラメーターに制約がありません。

図2制約なし

これは楽しかったです。生物学的なことを知っているふりをすることはありません。それがどのように落ち着くかを見るのは面白いでしょう!


ありがとう、これは本当に助かります。疑問に思って、MATLABで関数fitを使用してこれを行いましたか?
teaelleceecee

1
図に示すユーザー定義のユーザー関数でIgor Proを使用しました。私は1988年以来Igor Proとその前身(Igor)を使用していますが、Origin Proや非常に安価なKaleidagraphなど、他の多くのプログラムで曲線近似を行うことができます。そして、あなたはRと(おそらく?)Matlabへのアクセス権を持っているように見えますが、どちらも非常に有能であること以外は何も知りません。これで最高の成功を収めました。次回スーパーバイザーと話し合うときに良いニュースが得られることを願っています。また、データを投稿してくれてありがとう!
エドV

2

散布図からデータを抽出し、方程式検索により、3パラメーターロジスティックタイプの方程式が適切な候補として判明しました: "y = a /(1.0 + b * exp(-1.0 * c * x))"、ここで、 x "は、プロットごとの10を底とする対数です。当てはめられたパラメーターは、抽出されたデータに対してa = 9.0005947126706630E + 01、b = 1.2831794858584102E + 07、およびc = 6.6483431489473155E + 00でした。私の値を初期パラメータ推定値として使用する元のデータ。私のパラメーター値は、抽出されたデータでR-2乗= 0.983およびRMSE = 5.625になります。

プロット

編集:実際のデータを含めるために質問が編集されたので、上記の3パラメーター方程式と初期パラメーター推定を使用したプロットを次に示します。

プロット2


データ抽出でエラーが発生したようです。多数の負のパーセンテージ値があります。また、最大値は元のプロットのように100%ではなく約90%です。何らかの理由ですべてが約10%相殺されている場合があります。
mkt-モニカの復活

Meh-これは半手動で抽出されたデータで、元のデータが必要です。これは通常、方程式の検索には十分であり、もちろん最終結果には十分ではありません。そのため、元のデータの初期パラメーター推定値として、extract-o-fitパラメーター値を使用すると言いました。
ジェームズフィリップス

実際のデータが投稿に追加されたので、更新されたデータを使用してこの回答を更新したことに注意してください。
ジェームズフィリップス

繰り返しになりますが、たとえばヘビサイド関数を適用すると、同様のエラー値が生じる場合があります。
カールウィットソフト

1
@JamesPhillips私はそうしようとします(Heaviside-> errorbarsまたは同等のもの)
カールウィットソフ

2

ヘビサイドについて大きな口を開かなければならなかったので、結果はここにあります。遷移ポイントをlog10(viruscopies)= 2.5に設定します。次に、データセットの2つの半分の標準偏差を計算しました。つまり、Heavisideは、両側のデータがすべて導関数= 0であると仮定しています。

RH側std dev = 4.76
LH側std dev = 7.72

各バッチには15個のサンプルがあるため、全体的なstd devは平均、つまり6.24です。

他の回答で引用されている「RMSE」が全体で「RMSエラー」であると仮定すると、ヘビサイド関数は、少なくとも「Z曲線」(写真の応答命名法から借用)フィットと同等以上の性能を発揮します。ここに。

編集する

役に立たないグラフですが、コメントで要求されました:

ヘビサイドカーブフィット


他の回答で行われたのと同じように、モデルと散布図を投稿してください。私はこれらの結果を見て比較したいのです。比較のためにRMSE値とR-2乗値も追加してください。私は個人的にヘビサイド機能を使用したことがなく、これが非常に興味深いと感じています。
ジェームズフィリップス

@JamesPhillips表示するものは本当にありません-明らかに散布図は同じです。私がしたことは、移行ポイントを手動で選択し、各ポイントセットの生の平均(左手と右手)を取ることだけでした。よく分かりませんR2ここには多くの意味があります。
カール・ウィットフト

私の意味は、それらの回答と直接比較する目的で、他の回答で作成されたものと同様のプロットを作成することでした。
ジェームズフィリップス

2
@JamesPhillipsあなたには2つの願いが残っています。賢明に選択してください:-)
カールウィトフト

プロットをありがとう。他の回答のすべてのプロットでは、プロットされた方程式は右上のデータの曲線形状に従いますが、ヘビサイド関数の性質はそうではありません。これは、ヘビサイド関数が他の回答に投稿された方程式と同様に行うというあなたの主張と視覚的に矛盾するように見えます-これが以前にRMSEとRの2乗値を要求した理由です。この領域のデータのデータであり、これらの適合統計の値がより悪い場合があります。
ジェームズフィリップス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.