kuroの覚え書き

96の個人的覚え書き

nがばらばらのときのTukey

多重比較検定としてTukeyをよく使う。
一応Tukey-HSDとしてpythonのwebアプリを作って使っているのだが、どうも比較する各項目のnが同じでないとちゃんと検定が働かないようだった。もともとのTukeyの検定ではnが揃っていないとだめなんだが、statmodelsモジュールで提供されるライブラリではTukey-Kramer HSDを採用しているので、本来的にはnがばらばらでも働くはず。ソースを探ってみたところ、原因はcsvまたはtsvから値を読み取ってnumpyで配列化してからstatmodelsのpairwise_tukeyhsdにデータを渡しているところにありそうだ。

@app.route('/tukey2', methods=['GET', 'POST'])
def tukey2_index():
    user = g.user.name
    form=StatForm()
    dir = "./user/" + user + "/stat"
    input = dir + "/input.txt"
    output = dir + "/results.txt"


    if request.method == 'POST':
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            if form.samp_tk.data:
                samp = form.samp_tk.data.strip()
                f = open(input, 'w')
                f.write(samp)
                f.close()
            else:
                flash('No data input')
                return redirect(request.url)
        if file and allowed_file(file.filename):
            file.save(input)
    if os.path.exists(input):
        if form.data_f.data=='csv':
            df = pd.read_csv(input)
        if form.data_f.data=='tsv':
            df = pd.read_table(input)

        df = df.melt(var_name='groups', value_name='values')
        keys = df.groupby('groups').groups.keys()
        val_data =[]
        group_data =[]
        for key in keys:
            d = df.loc[df.groupby('groups').groups[key],'values']
            val_data.append(d)
            group_data.append([key]*len(d))

        val_data1 = np.concatenate(val_data)
        group_data1 = np.concatenate(group_data)

        from statsmodels.stats.multicomp import pairwise_tukeyhsd
        pc1 = pairwise_tukeyhsd(val_data1, group_data1)
        results = str(pc1)
        with open(output, mode='w') as f:
            f.write(results)

こんな感じで処理をしていたところ
val_dataを取得したところでnが揃ってないと足りないデータの部分にnanが入ってしまっていた。
なので

        val_data1 = np.concatenate(val_data).tolist()
        group_data1 = np.concatenate(group_data).tolist()
        in_data = pd.Series(val_data1, index=group_data1).dropna(how='any')
        val_data2 = in_data.values
        group_data2 = in_data.index

        from statsmodels.stats.multicomp import pairwise_tukeyhsd
        pc1 = pairwise_tukeyhsd(val_data2, group_data2)

というふうに一旦numpy配列からただのリストに戻し、さらにpandasでgroup_dataをラベルとして取り込んでシリーズにし、nanを含む行を取り除き、そこからもう一度numpy配列に戻してやってpairwise_tukeyhsdに食わしてやったところ、nにばらつきがあってもちゃんと解析が走るようになった。

一つデータ解析したいだけなのにアプリを作り直すのに結構時間を使った。まあ、そのおかげで、今後はいつでもnにばらつきのあるTukey-HSDが簡単に使えるわけだ。

今回の参考ページはこちら
リスト ↔︎ Numpy配列 ↔︎ Series ↔︎ DataFrameの変換方法|ぷんたむの悟りの書