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检验是实验生物学家的利器啊!

使用JBrowse搭建基因组浏览器服务

JBrowse是一款快速的,可以嵌入的基因组浏览器,它采用JavaScript和HTML5开发,同时提供了perl脚本处理数据。JBrowse采用了Ajax技术,主要的计算在客户端上完成, 对服务器资源的占用非常低,速度非常快,可以轻松部署上G的数据。JBrowse支持GFF3, BED, FASTA, Wiggle, BigWig, BAM, VCF (with tabix), REST等众多数据格式,BAM, BigWig,VCF格式的数据可以不需要转换而直接使用。 JBrowse对系统依赖非常低,只需要一个web服务器,因此部署起来非常方便。
下载JBrowse最新版本,然后安装:

unzip JBrowse-1.12.1.zip
cd JBrowse-1.12.1
./setup.sh

./setup.sh这一步需要安装很多perl依赖库,需要的时间可能有点久。如果报错,请查看setup.log文件,一般是系统可能缺某个依赖库。
安装好之后,我们将JBrowse-1.12.1下所有文件拷贝到网站根目录,这里我们使用Nginx作为web服务器。有关Nginx的安装和配置,参加另一篇博客文章:http://blog.biochen.com/archives/797

sudo mv * /usr/local/nginx/html/

访问http://127.0.0.1可以看到欢迎页面:
JBrowse_0
访问http://127.0.0.1/index.html?data=sample_data/json/volvox可以看到示例页面:
JBrowse_1

Ubuntu14.04 安装、配置nginx

Nginx是一款轻量级、高性能web服务器,它占用内存少,并发能力强。越来越多的网站使用Nginx作为web服务器。
Nginx依赖以下模块:
1. gzip模块需要 zlib 库
2. rewrite模块需要 pcre 库
3. ssl 功能需要openssl库
Nginx可以使用系统中已经安装的库,也可以自行指定。
下载Nginx,pcre,openssl,zlib源文件,然后通过如下命令安装:

tar zxvf nginx-1.11.0.tar.gz
tar zxvf pcre-8.38.tar.gz
tar zxvf openssl-1.0.1j.tar.gz
tar zxvf zlib-1.2.8.tar.gz
cd nginx-1.11.0
./configure --with-pcre=../pcre-8.38 --with-openssl=../openssl-1.0.1j --with-zlib=../zlib-1.2.8
sudo make & make install

Nginx默认安装在/usr/local/下,也可以在configure时使用–prefix参数指定安装路径。
Nginx安装后,Nginx文件夹的目录结构如下:

.
|-- conf
|   |-- fastcgi.conf
|   |-- fastcgi.conf.default
|   |-- fastcgi_params
|   |-- fastcgi_params.default
|   |-- koi-utf
|   |-- koi-win
|   |-- mime.types
|   |-- mime.types.default
|   |-- nginx.conf
|   |-- nginx.conf.default
|   |-- scgi_params
|   |-- scgi_params.default
|   |-- uwsgi_params
|   |-- uwsgi_params.default
|   `-- win-utf
|-- html
|   |-- 50x.html
|   `-- index.html
|-- logs
|   |-- access.log
|   `-- error.log
`-- sbin
    `-- nginx

conf文件夹下是配置文件,html文件夹是网站默认根目录,logs文件夹下是日志文件,sbin文件夹下是Nginx可执行程序。
启动Nginx:

sudo /usr/local/nginx/sbin/nginx             #启动Nginx
sudo /usr/local/nginx/sbin/nginx -s stop     #停止Nginx
sudo /usr/local/nginx/sbin/nginx -s reload   #重启Nginx

启动Nginx后,访问127.0.0.1,可以看到欢迎页面。
nginx
nginx.conf是主配置文件
worker_process表示工作进程的数量,一般设置为cpu的核数
worker_connections表示每个工作进程的最大连接数
server{}块定义了虚拟主机
listen监听端口
server_name监听域名
location{}指定网站文件的位置
index指定首页index文件的名称,可以配置多个,以空格分开。如有多个,按配置顺序查找。