T检验靠谱吗?

对于实验生物学研究者来说,经常遇到的一个场景是,对照组测量3个值,实验组测量3个值,然后用T检验得出均值是否有显著性差异,然后做出结论。如下图所示:
bio_t

 

 

 

 

 

 

 

 

 

 

 

 

那么T检验靠谱吗?
本文采用模拟抽样的方法来探讨这件事情,由于本人统计学知识有限,还请各位读者批评指正。

我们通过构建两个随机总体,总体1的均值固定为1(模拟control),总体2的均值我们从依次取0.5到2.0(模拟treatment相对与control的变化),标准差我们取0.01、0.05、0.10(模拟测量误差1%,5%,10%)。总体数量为1000,每次随机抽取3个样本,抽样1000次,考察通过T检验得出正确结论的频率。代码如下:

import numpy as np
import pandas as pd
import seaborn as sns
from scipy import stats
import matplotlib.pyplot as plt
 
plt.xkcd()
sns.set(style="white", context="talk")
 
def norm_t(loc1, loc2, scale1, scale2, n):
    normSpace1 = stats.norm.rvs(loc = loc1, scale = scale1, size = 1000)
    normSpace2 = stats.norm.rvs(loc = loc2, scale = scale2, size = 1000)
    count = 0
    for i in range(1000):
        sample1 = np.random.choice(normSpace1, n)
        sample2 = np.random.choice(normSpace2, n)
        t, p = stats.ttest_ind(sample1, sample2)
        if (p < 0.05 and (sample1.mean() > sample2.mean()) == (loc1 > loc2)):
            count = count + 1
    return count / 1000
 
def plot(stds):
    df = pd.DataFrame()
    for std in stds:
        x = np.arange(0.5, 2.1, 0.1)
        y = [norm_t(loc1 = 1, loc2 = i, scale1 = std, scale2 = std, n = 3) for i in x]
        z = [std for i in x]
        df_std = pd.DataFrame([x, y, z]).T
        df_std.columns = ["difference", "sensitivity", "std"]
        if df.shape == (0, 0):
            df = df_std
        else:
            df = df.append(df_std)
    sns.pointplot(x = "difference", y = "sensitivity", hue = "std", data = df)
 
plot([0.01, 0.05, 0.10])

std_sensitivity
通过上图,我们发现,当标准差我们取0.01(模拟测量误差1%)时,增大到1.1倍或者减小到0.9倍,正确率可以达到100%。而当标准差取0.05和0.10(模拟测量误差5%和10%),效果就不理想了,本来是有差异的,还是有很大几率通过T检验得出错误的结论。显而易见的是,随着标准差的增加,T检验的效果变差了。

那么当标准差取0.10时,随着抽样样本数的增加,T检验判断正确的频率会是怎么样的呢?请看如下代码:

def plot2(diffs):
    df = pd.DataFrame()
    for diff in diffs:
        x = list(range(3, 60, 3))
        y = [norm_t(loc1 = 1, loc2 =1.1, scale1 = 0.10, scale2 = 0.10, n = i) for i in x]
        z = [diff for i in x]
        df_diff = pd.DataFrame([x, y, z]).T
        df_diff.columns = ["samle number", "sensitivity", "difference"]
        if df.shape == (0, 0):
            df = df_diff
        else:
            df = df.append(df_diff)
    sns.pointplot(x = "samle number", y = "sensitivity", hue = "difference", data = df)
 
plot2([0.5, 0.8, 1.2, 2.0])

n_sensitivity
通过上图,我们发现,即使标准差达到0.10,当样本数量达到30以上时,T检验的效果就非常好了。

那么如果两个总体没有差异,T检验得出有差异的错误结论的情况是什么样子的呢?我们构建两个均值为1容量为1000的总体,每次随机抽取3个样本,在不同标准差及样本数目的情况下,考察T检验得出正确结论的频率。请看代码:

def norm_t2(loc, scale1, scale2, n):
    normSpace1 = stats.norm.rvs(loc = loc, scale = scale1, size = 1000)
    normSpace2 = stats.norm.rvs(loc = loc, scale = scale2, size = 1000)
    count = 0
    for i in range(1000):
        sample1 = np.random.choice(normSpace1, n)
        sample2 = np.random.choice(normSpace2, n)
        t, p = stats.ttest_ind(sample1, sample2)
        if p > 0.05:
            count = count + 1
    return count / 1000
 
def plot3(stds):
    stds = [0.1, 0.5, 1]
    df = pd.DataFrame()
    for std in stds:
        x = list(range(3, 60, 3))
        y = [norm_t2(loc = 1, scale1 = std , scale2 = std, n = i) for i in x]
        z = [std for i in x]
        df_std = pd.DataFrame([x, y, z]).T
        df_std.columns = ["samle number", "specificity", "std"]
        if df.shape == (0, 0):
            df = df_std
        else:
            df = df.append(df_std)
    sns.pointplot(x = "samle number", y = "specificity", hue = "std", data = df)
    plt.ylim(0, 1.2)
 
plot3([0.1, 0.5, 1])

specificity
通过上图,我们惊讶地发现,当两个总体没有差异时,不管标准差是多少和取样数目是多少,T检验都有非常好的表现,即得到差异不显著的的结论。

这里构建的总体都是正太总体,其实对于其他分布的总体,结论是一样的,这里就不展示了。

通过上面的探索,我们可以得到如下结论:
1. 对于两个未知总体,通过T检验考察均值是否有显著差异,如果得出结论是差异不显著,那么进一步分析这些数据的标准差是否太大了,考虑是否增加抽样样本数做进一步分析。
2. 对于两个未知总体,通过T检验考察均值是否有显著差异,如果得出结论是差异显著,那么请相信它吧!

如果差异不显著,我们通过增大样本数量,使得差异显著;如果差异显著,那就是一个好结果嘛!
哈哈,T检验是实验生物学家的利器啊!

生物实验中的对照(control)

生物实验中,对照(control)是必不可少的。怎么做对照是一个学问,当年上“生命科学研究方法”课程时,老师讲整整3个小时还意犹未尽。这里谈谈我的看法。

在我看来,对照可以分为阳性对照(positive control)和阴性对照(negative control)。

阳性对照,是一定能做出来的,如果做不出来,那说明你的实验体系有问题。在小木虫上,经常有人构建质粒做了很久一直做不出来,发帖求助。构建质粒涉及到PCR、酶切、连接、转化等多个步骤,可能出问题的点很多。你可以随便扩增一段片段,连接到T载体上面,如果能顺利构建出来,PCR、连接、转化等基本上是没有问题的。从多克隆位点处对载体进行线性化,很难判断载体是否完全切开。用试剂盒提取出来的质粒,一般不会出现超螺旋、开环、线性三种构象,而且大载体的这三种构象也不好区分。如果想验证限制性内切酶是否好用,应该从你的质粒库选一个酶切后片段很分明的质粒去做酶切。当做完足够多的阳性对照后,基本上可以排除实验体系的问题了。这时,你的实验还做不出来,可以考虑优化条件了。不建议盲目地重复或者优化失败的实验。一个优秀实验员(应该写得出一手号代码,开个玩笑),不仅拥有丰富的知识、充足的经验、娴熟的技巧,更重要的是必胜的信念。做阳性对照,能大大提升你对实验成功的信心,因为它是很容易也一定能做出来的。

阴性对照,是一定做不出来的,如果做出来了,那说明你的实验结果不可信。当你想通过实验说明某个因果关系时,有人会反驳你这个果未必是这个因引起的,可能还存在“小三”。那你这个时候,做个阴性对照,来control掉这个“小三”。

总结一下,实验结果阴性(就是没做出想要的结果啦),看阳性对照,如果阳性对照阴性,实验体系有问题;实验结果阳性(就是结果很好),看阴性对照,如果阴性对照阳性,实验结果不可信。