さて、さっきのアプリからPCAだけを抜き出してちょっと改変してみる。
主成分分析を Python で理解する - Qiita
こちらのページを参考にさせてもらう。
ポイントはnumpyで数値データを抜き出していた点をpandasに換えることでテキストも含んだcsvを入り口にできるようにした点とクラスわけを色で塗り分けるようにした点。
おまけでfigure sizeを設定できるようにもしてみた。
前に作ったstat.pyに以下の記述を追加した。
@app.route('/stat2', methods=['GET', 'POST']) def stat2_index(): user = g.user.name form=StatForm() dir = "./user/" + user + "/stat" if os.path.exists(dir): shutil.rmtree(dir) if not os.path.exists(dir): os.makedirs(dir) input = dir + "/input.txt" output = dir + "/output.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 == '': flash('No selected file') return redirect(request.url) if file and allowed_file(file.filename): file.save(input) stat_fig = dir + "/stat_" + str(time.time()) + ".png" if form.fig_x.data: fig_x=form.fig_x.data if form.fig_y.data: fig_y=form.fig_y.data df = pd.read_csv(input, sep=",", index_col=0) dfs = df.iloc[:, 1:].apply(lambda x: (x-x.mean())/x.std(), axis=0) pca = PCA() feature = pca.fit(dfs) feature = pca.transform(dfs) plt.figure(figsize=(fig_x,fig_y)) plt.scatter(feature[:, 0], feature[:, 1], alpha=0.8, c=list(df.iloc[:, 0])) plt.grid() plt.title('principal component') plt.xlabel("PC1") plt.ylabel("PC2") plt.savefig(stat_fig) img_url = "../../static/" + stat_fig return render_template('/tools/stat2.html', form=form, img_url=img_url) return render_template('/tools/stat2.html', form=form)
templateの方は殆ど変わらないが
stat2.html
{% extends "base.html" %} {% import "bootstrap/wtf.html" as wtf %} {% block title %}Statistics_tool{% endblock %} {% block head %} {{ super() }} {% endblock %} {% block scripts %} {{ super() }} {% endblock %} {% block page_top %} <h2>PCA tool</h2> <div class="row"> <form class="form form-group form-group-sm" method=post enctype=multipart/form-data> <div class="col-xs-2"> <h4>Figure setting</h4> <h5> figure_x size <br> {{ form.fig_x }}<br><br> figure_y size <br> {{ form.fig_y }}<br><br> </h5> </div> <div class="col-xs-10"> <br> <b>Upload csv file</b><br> <input type=file name=file> <br> <b>start statistics</b><br> <input class='btn btn-primary' type=submit value=Submit> {% if img_url %} <p><img src="{{ img_url }}"></p> {% endif %} <br><br> {% for message in get_flashed_messages() %} <div class="alert alert-success">{{ message }}</div> {% endfor %} <br><br> <div> <iframe name="info2" frameborder="0" width=1220px height=600px></iframe> </div> </div> </form> </div> {% endblock %} {% block left %} {% endblock %} {% block right %} {% endblock %} {% block page_bottom %} {% endblock %}
要素の側のプロットもつけられるようにした。これでほぼ完成。