pandasでgroupbyを使う
pythonのpandasで表の集計をしている
groupbyが便利だったのでメモ
groupbyについて参考にした
Pandasのgroupbyを使った要素をグループ化して処理をする方法 - DeepAge
例えばirisのデータで種毎に平均値を計算してみる
pythonでもirisのデータが使えた
【python】iris(アヤメ)のデータセットをpandasとseabornを使って可視化する
ライブラリscikit-learnに含まれている
irisのカラムは5つ
[5 rows x 5 columns] Index(['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)', 'target'], dtype='object')
targetが種の名前
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \ 0 5.1 3.5 1.4 0.2 1 4.9 3.0 1.4 0.2 2 4.7 3.2 1.3 0.2 3 4.6 3.1 1.5 0.2 4 5.0 3.6 1.4 0.2 target 0 setosa 1 setosa 2 setosa 3 setosa 4 setosa
groupbyでtargetを指定するとtargetで各行がまとめられて
mean()で平均値を計算してくれる
df.groupby(['target']).mean()
df.groupby(['target'])の出力は以下の通りで数値を確認できない
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x07FE0310>
dict(list(df.groupby(['target'])))とすると表示できる
実際に使用したコードはこれ
import pandas as pd from sklearn import datasets pd.set_option('display.max_columns', 5) iris = datasets.load_iris() df = pd.DataFrame(iris.data, columns=iris.feature_names) df['target'] = iris.target_names[iris.target] print(df.head()) print(df.columns) print(df.groupby(['target']).mean())
計算結果
sepal length (cm) sepal width (cm) petal length (cm) \ target setosa 5.006 3.428 1.462 versicolor 5.936 2.770 4.260 virginica 6.588 2.974 5.552 petal width (cm) target setosa 0.246 versicolor 1.326 virginica 2.026 [Finished in 1.624s]
列が省略されないようにするにはset_optionで指定する
Pandas DataFrameの表示を省略したくない時. Jupyter… | by takkii | Music and Technology | Medium
Atomで出力している
結果が折り返されるのが修正できない。。。
Pythonista3でTableviewを使う
Pythonisata3でui.tableviewを使うときにハマったのでメモ
.pyuiファイルにTextFieldを配置したとき
TextFieldの中身はsuperviewで読み出せる
例えばTextFieldの名前をtextfield1とするとき
以下のように書く
def on_textfield(sender): a = sender.superview['textfield1']
これがTableViewの場合だとsuperviewの前にtableviewを挟まないといけない
例えばTableViewの名前がtableview1とするとき
このように書く
def on_tableview(sender): b = sender.tableview.superview['tableview'1]
これでTableViewの読み書きできる
こんな感じで任意のリストを
TableViewに加えることができる
list = ui.ListDataSource([{'title':'dog'}, {'title':'cat'}, {'title':'bird'}]) tableview.data_source.items = [] for i in list.items: tableview.data_source.items.append(i) tableview.reload_data()
関数の引数であるsenderは
.pyui上のどのパーツをタップしたかで
内容が異なっている
for key in sender.__dict__.keys(): print(key)
で内容を確認できて
_pyuiが含まれていると
superviewを使えるっぽい
以下が確認した内容で
TableViewではsender.tablevewに_pyuiが含まれる
---sender@TextField--- <class '_ui.TextField'> _pyui None ---sender@TableView--- <class 'ui.ListDataSource'> tableview reload_disabled delete_enabled move_enabled action edit_action accessory_action tapped_accessory_row selected_row _items text_color highlight_color font number_of_lines None ---sender.tableview@TableView--- <class '_ui.TableView'> _pyui None
WSLとJupyter-notebookでCNN、その2、CNNを試す
前回の続き
mecobalamin.hatenablog.com
環境ができたので手持ちのデータセットを試してみる
こちらのサイトを参考にコードを作成した
kerasでCNN 自分で拾った画像でやってみる - Qiita
主な変更点は以下の3点
- 画像の読み込み
- mnist_cnn.pyのモデルを使用
- label、predict、画像ファイル名を保存する
こちらの環境ではlist_picturesが動かなかったので
ファイルを読み込む関数Image_Listを定義した
globは引数で指定したパスのファイル名を再帰的に取得する
ファイル名だけ取得したいのでrelpathで処理している
モデルはmnist_cnn.pyのと同じモデルを使ってみた
画像の分類は手動で行って
negativeとpositiveのディレクトリに保存してある
それぞれの画像がどのように分類されているかを知りたかったので
画像のファイル名とそれぞれがどのようにpredictされているかを
csvファイルに保存した
fit()で出力されるlistのindexも
バージョン違いのせいか"accu"ではエラーが出るので
"accuracy"に修正してある
実際のコードは以下の通り
# ライブラリのインポート import keras from keras.utils import np_utils from keras.layers.convolutional import Conv2D, MaxPooling2D from keras.models import Sequential from keras.layers.core import Dense, Dropout, Activation, Flatten from keras.preprocessing.image import array_to_img, img_to_array, load_img from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt import pandas as pd import numpy as np from glob import glob from os.path import relpath # ファイル名の取得 def Image_List(Path_Images, Ext): List_Images = glob(Path_Images + "/*." + Ext) List_Names = [] for i in List_Images: List_Names.append(relpath(i, Path_Images)) return List_Names # 画像の拡張子 Ext_Type = "png" # 画像のパス Path_Negative = '/path/to/negative/' Path_Positive = '/path/to/positive/' X = [] Y = [] # ネガティブ画像の読み込み Image_Negative = Image_List(Path_Negative, Ext_Type) for picture in Image_Negative: img = img_to_array(load_img(Path_Negative + picture, color_mode = "grayscale", target_size=(256, 256))) X.append(img) Y.append(0) # ポジティブ画像の読み込み Image_Positive = Image_List(Path_Positive, Ext_Type) for picture in Image_Positive: img = img_to_array(load_img(Path_Positive + picture, color_mode = "grayscale", target_size=(256, 256))) X.append(img) Y.append(1) # arrayに変換 # Zはファイル名のリスト X = np.asarray(X) Y = np.asarray(Y) Z = pd.DataFrame(Image_Negative + Image_Positive) # 画素値を規格化 X = X.astype('float32') X = X / 255.0 # one-hot表現に変換 Y = np_utils.to_categorical(Y, 2) # 学習用データとテストデータに分割 # ファイル名のリストも分割 X_train, X_test, y_train, y_test, indices_train, indices_test = train_test_split(X, Y, Z, test_size=0.33, random_state=111) # モデルの構築 model = Sequential() model.add(Conv2D(20, kernel_size=(3, 3), activation='relu', input_shape=X_train.shape[1:])) model.add(Conv2D(40, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(512)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(2)) # クラスは2個 model.add(Activation('softmax')) # コンパイル model.compile(loss='categorical_crossentropy', optimizer='SGD', metrics=['accuracy']) # 実行 # 出力有り(verbose=1)。 history = model.fit(X_train, y_train, batch_size=300, epochs=4[f:id:mecobalamin:20200608101008p:plain]0, validation_data = (X_test, y_test), verbose = 1) plt.plot(history.history['accuracy']) plt.plot(history.history['val_accuracy']) plt.title('model accuracy') plt.xlabel('epoch') plt.ylabel('accuracy') plt.legend(['acc', 'val_acc'], loc='lower right') plt.show() # テストデータに適用 predict_classes = model.predict_classes(X_test) # マージ。yのデータは元に戻す mg_df = pd.DataFrame({'predict': predict_classes, 'class': np.argmax(y_test, axis=1)}) # confusion matrix pd.crosstab(mg_df['class'], mg_df['predict']) # 結果の保存 # テストに使った画像ファイルのリストも保存 df_h = pd.concat([pd.DataFrame(y_test), indices_test], axis = 1) pd.DataFrame(y_test).to_csv("/path/to/y_test.csv") indices_test.to_csv("/path/to/indices_test.csv") pd.DataFrame(predict_classes).to_csv("/path/to/predict_test.csv")
jupyter-notebookの複数のcellをまとめたが
gistを使うとそのまま貼り付けられるらしい
計算結果は以下の通り
Core i5-7200UのノートPCで
大体6時間ぐらいかかった
Train on 3287 samples, validate on 1619 samples Epoch 1/40 3287/3287 [==============================] - 522s 159ms/step - loss: 0.6425 - accuracy: 0.5117 - val_loss: 0.5973 - val_accuracy: 0.5374 Epoch 2/40 3287/3287 [==============================] - 494s 150ms/step - loss: 0.5793 - accuracy: 0.6693 - val_loss: 0.5340 - val_accuracy: 0.7739 Epoch 3/40 3287/3287 [==============================] - 493s 150ms/step - loss: 0.5429 - accuracy: 0.7478 - val_loss: 0.5146 - val_accuracy: 0.7573 ~~~ 省略 ~~~ Epoch 38/40 3287/3287 [==============================] - 501s 152ms/step - loss: 0.4346 - accuracy: 0.8059 - val_loss: 0.4734 - val_accuracy: 0.7900 Epoch 39/40 3287/3287 [==============================] - 493s 150ms/step - loss: 0.4001 - accuracy: 0.8190 - val_loss: 0.5238 - val_accuracy: 0.7622 Epoch 40/40 3287/3287 [==============================] - 497s 151ms/step - loss: 0.4388 - accuracy: 0.8026 - val_loss: 0.4895 - val_accuracy: 0.7857
Epochが増えると学習データに対するAccuracyは増えているが
テストデータに対するAccuracyはあまり増えていない
Jupyter Notebookをはてなブログに貼り付ける方法 - akatak’s blog
画像の分類は以下の通り
classは学習時に使った画像のラベルで
0はnegative、1はpositiveを表す
predictはcnnで分類された画像で
0/1はやはりnegative/positiveを表す
predict | |||
---|---|---|---|
0 | 1 | ||
class | 0 | 652 | 104 |
1 | 243 | 620 |
10%-30%程度間違っている
グラフにしてないけれど損失関数も
mnistのデータを使ったときほど減っていない
使ったモデルが合っていないのか
教師データの分類が不十分なのか
そもそもデータの数が足りないのか
分類できた画像を確認したら
見た目にも分類が不十分に感じる
この画像がネガティブに分類?みたいな
計算はできたけど
ここからの修正はどうしたらいいだろうか
WSLとJupyter-notebookでCNN、その1、環境構築
画像の分類をしたくてDeep Learningについて勉強している
ネットで調べながらこの本を何度も読み直している
ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
(Amazonのサイトに飛びます)
CourseraのMachine Learningの講義もおすすめ
mecobalamin.hatenablog.com
試してみたいデータもあるのでどこか
似たようなことをやっている人がないか探してみたら
Kerasの開発者がCNNを使ってMNISTの画像認識を行っていた
https://github.com/keras-team/keras/tree/master/examples
いくつもファイルがあるがこの中からmnist_cnn.pyを利用した
mnist_cnn.pyについてはググるといくつも情報が出てくる
https://pondad.net/deep-learning/2016/12/25/keras-mnist.html
【AI初心者向け】mnist_cnn.pyを1行ずつ解説していく(KerasでMNISTを学習させる) - Qiita
手持ちの画像データを使いたいので
画像を読み込ませるために以下のサイトを参考にした
kerasでCNN 自分で拾った画像でやってみる - Qiita
Google Colaboratory で Keras 自作データセットを読み込み - Qiita
sklearn の train_test_split でデータの順番の情報を保持しておく - Qiita
実際に行ったのは
- mnist_cnn.pyを動かす環境の構築と実行
- 手持ち画像を読み込ませるコードの実行
今回はmnist_cnn.pyを動かす環境の構築
実行環境はWSLに作った
WSLを利用したのはPower Shellには
tensorflowをインストールできなかったためだ
まずはkeras/tensorflowをインストールする仮想環境を用意する
以下の過去記事を参考にした
mecobalamin.hatenablog.com
condaのコマンドを使ってtfという仮想環境を作る
conda create -n tf python=3.7 anaconda
環境の切り替えは
conda activate tf
と
conda deactivate
で行う
この環境にkerasとtensorflowをWSLにインストールした
keras/tensorflowの関係がいまいちよくわかっていないけど
tensorflowはバックエンドで実際の作業をするライブラリで
kerasはtensorflowを効率よく使うためのライブラリという認識
インストールは以下の通り
pip install --upgrade tensorflow
conda install keras
しようがないとはいえpipとcondaを混ぜて使ってしまったのが若干気になる
condaとpip:混ぜるな危険 - onoz000’s blog
仮想環境下にインストールしているので
やり直しをしやすいと思う
pythonコードの実行環境としてJupyterもインストール
pip install Jupyter
jupyter-notebookを使えるようになる
jupyter-notebookはデータサイエンス・機械学習の分野で
よく使われているらしい
セル毎にコードを実行できるので
修正箇所だけ実行とかできて便利
インストール後にjupyter-notebookを起動すると
jupyter-notebook
以下の表示が出るのでURLを
windowsのbrowserにコピペすると
jupyter-notebookを利用できる
To access the notebook, open this file in a browser: file:///home/hogehoge/.local/share/jupyter/runtime/nbserver-hogehoge-fugafuga.html Or copy and paste one of these URLs: http://localhost:8888/?token=hogehogefugafuga or http://127.0.0.1:8888/?token=hogehogefugafuga
実際にはtokenにアルファベットと数字の文字列が入っている
jupyter-notebookで新規にnotebookを作って
mnist_cnn.pyの中身をコピペするとこんな感じ
実行結果は以下の通り
Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz 11493376/11490434 [==============================] - 5s 0us/step x_train shape: (60000, 28, 28, 1) 60000 train samples 10000 test samples Train on 60000 samples, validate on 10000 samples Epoch 1/12 60000/60000 [==============================] - 138s 2ms/step - loss: 0.2544 - accuracy: 0.9218 - val_loss: 0.0638 - val_accuracy: 0.9800 Epoch 2/12 60000/60000 [==============================] - 133s 2ms/step - loss: 0.0873 - accuracy: 0.9743 - val_loss: 0.0448 - val_accuracy: 0.9861 Epoch 3/12 60000/60000 [==============================] - 134s 2ms/step - loss: 0.0651 - accuracy: 0.9802 - val_loss: 0.0327 - val_accuracy: 0.9894 Epoch 4/12 60000/60000 [==============================] - 139s 2ms/step - loss: 0.0539 - accuracy: 0.9836 - val_loss: 0.0291 - val_accuracy: 0.9901 Epoch 5/12 60000/60000 [==============================] - 130s 2ms/step - loss: 0.0445 - accuracy: 0.9866 - val_loss: 0.0301 - val_accuracy: 0.9900 Epoch 6/12 60000/60000 [==============================] - 131s 2ms/step - loss: 0.0407 - accuracy: 0.9874 - val_loss: 0.0292 - val_accuracy: 0.9900 Epoch 7/12 60000/60000 [==============================] - 123s 2ms/step - loss: 0.0368 - accuracy: 0.9891 - val_loss: 0.0254 - val_accuracy: 0.9907 Epoch 8/12 60000/60000 [==============================] - 74s 1ms/step - loss: 0.0326 - accuracy: 0.9899 - val_loss: 0.0300 - val_accuracy: 0.9908 Epoch 9/12 60000/60000 [==============================] - 77s 1ms/step - loss: 0.0310 - accuracy: 0.9905 - val_loss: 0.0243 - val_accuracy: 0.9921 Epoch 10/12 60000/60000 [==============================] - 76s 1ms/step - loss: 0.0272 - accuracy: 0.9919 - val_loss: 0.0268 - val_accuracy: 0.9921 Epoch 11/12 60000/60000 [==============================] - 76s 1ms/step - loss: 0.0264 - accuracy: 0.9916 - val_loss: 0.0268 - val_accuracy: 0.9917 Epoch 12/12 60000/60000 [==============================] - 77s 1ms/step - loss: 0.0261 - accuracy: 0.9920 - val_loss: 0.0247 - val_accuracy: 0.9922 Test loss: 0.024740188298751492 Test accuracy: 0.9922000169754028
mnist_cnn.pyには
Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
とある
test accuracyは0.9920で大体あっているようだ
また今回使用した
Intel Core i5 7200U、GPUなしのnotebook PCでは
74-139s/Epochなので1/5 - 1/9 程度の計算速度か
値段の差を考えるとまあ順当
NVIDIA GRID k520 8 GB gddr5 PCIe gen3 x16クラウドゲームケプラーGPUグラフィックス900 – 12055 – 0020 – 000
とりあえず環境ができたので
次は手持ちのデータで試してみる
Pythonで数値のみの入力
以前、選択肢を数字で選ばせる
pythonのスクリプトの記事を書いた
mecobalamin.hatenablog.com
該当する部分は以下のコード
print('計算の種類を選んで数字を入力してね') print('1: 少数のたし算・ひき算') print('2: 大きな数のかけ算') print('3: あまりのあるわり算') print('4: 分数のたし算・ひき算') while True: eq_type = input('数値を入力 (1 - 4): ') if eq_type > '0' and eq_type < '5': break
動いていたから気にしていなかったが
入力は文字なのに大小の比較ができている
なぜだ?
文字列にも等号記号が使えることは知っていたが
調べてみると比較演算子も使えた
Pythonで文字列を比較(完全一致、部分一致、大小関係など) | note.nkmk.me
比較演算子の使い方 | Python入門
unicodeのコードポイントを比較しているそうだ
pythonではord()でコードポイントを取得できる
>>> ord('0') 48 >>> ord('1') 49 >>> ord('2') 50 >>> ord('9') 57
数字の0から9には
48から57が割り当てられている
なので過去記事で使ったコードでも
問題なく動いたようだ
本来ならint()で数値にして
大小比較するのが筋かも
ただし数値以外の文字・記号を
int()の引数にした場合はエラーになるので
try/except文を使って
エラーを弾きつつ
数値の入力を受け付けるように書き直した
try/excptの使い方は以下のサイトを参考にさせてもらった
Pythonの例外処理(try, except, else, finally) | note.nkmk.me
書き直したコードはこんな感じ
確認のためprint()を追加している
while True: eq_type = input('数値を入力 (1 - 4): ') try: int(eq_type) except ValueError as e: print('1から4までの数字を入力してね') else: if int(eq_type) >= 1 and int(eq_type) <= 4: break else: print('1から4までの数字を入力してね') print(eq_type)
もっと簡潔にかけそうな気がする
あと全角・半角の区別はしていない
出力は半角になる
そのうち区別できるようにしたい
Pythonista3でpythonプログラミング
pythonプログラミングに利用している
iOSアプリのPythonista3
mecobalamin.hatenablog.com
mecobalamin.hatenablog.com
割と色々できて便利
まずはpythonistaについて
iOS上で動作する革命的ものづくり環境「Pythonista 3」の魅力をとくと語る
iOS上で動作する革命的ものづくり環境「Pythonista 3」の魅力をとくと語る
iPad ProでPythonプログラム
iPad ProでPythonプログラム - Qiita
Deep Learningの勉強にも使っていたり
「ゼロから作るDeep Learning」をiPhoneのPythonistaだけで学ぶ(2)
「ゼロから作るDeep Learning」をiPhoneのPythonistaだけで学ぶ(2) - blog.tmp.tokyo
iPadで「ゼロから作るDeep Learning」を勉強するために必要なこと
poipoides.hatenablog.com
自分でも試してみたけどコードに変更が必要で
上記のリンク先の方が変更したコードを載せてくれている
3章か4章ぐらいまではpythonistaで動くことを確認した
その先は結局PCのpythonで。
今までやったのは
コンソールに結果を表示する
プログラミング
希望する機能を実装できていたけど
せっかくiPadを使っているのだから
タッチ操作できるプログラミングをしてみたい
pythonistaにはいくつもサンプルコードが入っていて
そのいくつかはタッチ操作のゲームだったりする
実際ゲームを作っている人達もいる
Pythonistaで作るポーカー作成講座(全5回)
Pythonistaで作るポーカー作成講座(全5回) | みやびのどっとぴーわい
Pythonista+sceneでトランプをランダムに表示する
Pythonista+sceneでトランプをランダムに表示する - Qiita
公式でXcodeに変換するコードを公開しているので
その気になればiOSアプリも作れそう
python2に対応
github.com
で、試しに作ってみた
作ったのは例えば何かカードゲームをして
得点を記録するプログラム
一度コンソールに表示するバージョンは書いていて
こんな感じ
それをこのように表示したい
プレイヤーは3人で
ポイントを入力してsubmitを押すと
totalに加算される
そしてroundが一つ進む
コードはpythonプログラムのui.pyと
ボタン等を配置したui.pyuiの2つで一セット
実際のコードはこの記事の最後に載せるとして
ui.pyの説明を書く
import ui import console
pythonistaにはsceneというライブラリもあるが
今回使用したのはui
consoleもpythonistaのライブラリで
コンソールを操作するのに使う
v = ui.load_view() v['num1'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v['num2'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v['num3'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v.present('fullscreen')
ui.load_view()でui.pyuiをロードしている
v['num1'].keyboard_typeは
num1に入力するときのキーボードの種類を設定する
num1は得点の入力なので数値のみ
なので最初から数字入力になっている
キーボードが表示されるようにしている
present('fullsucreen')で
フルスクリーン表示でコードを実行する
よくわかっていないんだけど
このときプログラムは×印をタップして停止させるまで
入力待ちになっているっぽい
関数を実行するにはui.pyに書かれた関数を
ui.pyuiのボタンに紐付けしておく
ボタンをタップすると
紐付けされた関数on_buttonが実行される
def on_button(sender):
引数のsenderには画面上の情報が入っているようで
superview[]とボタンやtextfieldの名前を使って値を取り出す
text_label1 = sender.superview['label1'] Num_1 = sender.superview['num1']
label1やnum1はtextfieldの名前であり
ui.pyuiで編集できる
print文はconsol画面に表示されるため
プログラムを停止するまで表示を見られない
書いただけなので読みやすく修正したいけど
とりあえずここまででやりたいことは実装できた
ui.pyuiも見やすいデザインにしたい
まだ読んでいないけどpytonista3を使った
プログラミング教本らしいのでメモ
PythonではじめるiOSプログラミング 〜iOS+Pythonで数値処理からGUI、ゲーム、iOS機能拡張まで〜
実際のコードは以下の通り
ui.py
import ui import console def on_button(sender): text_label1 = sender.superview['label1'] Num_1 = sender.superview['num1'] Re_1 = sum_score(text_label1.text, Num_1.text) text_label1.text = str(Re_1) Num_1.text = '' text_label2 = sender.superview['label2'] Num_2 = sender.superview['num2'] Re_2 = sum_score(text_label2.text, Num_2.text) text_label2.text = str(Re_2) Num_2.text = '' text_label3 = sender.superview['label3'] Num_3 = sender.superview['num3'] Re_3 = sum_score(text_label3.text, Num_3.text) text_label3.text = str(Re_3) Num_3.text = '' num_round = sender.superview['num_round'] num_round.text = str(int(num_round.text) + 1) #print(Num_3.text_color) print('round' + str(int(num_round.text) - 1), Re_1, Re_2, Re_3) def sum_score(m, n): r = 0 if m == '': r = int(n) elif n == '': r = int(m) else: r = int(m) + int(n) return r if __name__ == '__main__': console.clear() console.set_font('Menlo',20) v = ui.load_view() v['num1'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v['num2'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v['num3'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v.present('fullscreen')
ボタンや数字の入力場所の配置はこんな感じ
赤でマークしたactionにon_button関数を登録した
submitのボタンを押すと
on_button関数が実行される
ui.pyuiはテキストファイルなのでエディタで中身が読める
よくわからないけどファイルの形式はJSON?っぽく見える
ui.pyui
[ { "nodes" : [ { "nodes" : [ ], "frame" : "{{119, 54}, {77, 43}}", "class" : "TextField", "attributes" : { "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "font_size" : 17, "frame" : "{{60, 224}, {200, 32}}", "custom_attributes" : "", "action" : "", "alignment" : "right", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "num1", "flex" : "WHLRTB" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 54}, {95, 43}}", "class" : "TextField", "attributes" : { "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "font_size" : 17, "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "left", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "usr1", "flex" : "WHLRTB" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 105}, {95, 43}}", "class" : "TextField", "attributes" : { "flex" : "WHLRTB", "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "left", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "usr2", "font_size" : 17 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 156}, {95, 43}}", "class" : "TextField", "attributes" : { "flex" : "WHLRTB", "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "left", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "usr3", "font_size" : 17 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{119, 105}, {77, 43}}", "class" : "TextField", "attributes" : { "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "font_size" : 17, "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "right", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "num2", "flex" : "WHLRTB" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{119, 156}, {77, 43}}", "class" : "TextField", "attributes" : { "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "font_size" : 17, "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "right", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "num3", "flex" : "WHLRTB" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{204, 54}, {97, 43}}", "class" : "Label", "attributes" : { "uuid" : "F3870D2E-9FCF-4C83-B5AF-C393166D3D4E", "flex" : "WHLRTB", "corner_radius" : 0, "frame" : "{{85, 224}, {150, 32}}", "number_of_lines" : 0, "border_width" : 1, "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "alignment" : "center", "text" : "0", "font_name" : "<System>", "class" : "Label", "name" : "label1", "font_size" : 18 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{204, 105}, {97, 43}}", "class" : "Label", "attributes" : { "uuid" : "F3870D2E-9FCF-4C83-B5AF-C393166D3D4E", "flex" : "WHLRTB", "corner_radius" : 0, "frame" : "{{85, 224}, {150, 32}}", "number_of_lines" : 0, "border_width" : 1, "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "alignment" : "center", "text" : "0", "font_name" : "<System>", "class" : "Label", "name" : "label2", "font_size" : 18 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{204, 156}, {97, 43}}", "class" : "Label", "attributes" : { "flex" : "WHLRTB", "uuid" : "F3870D2E-9FCF-4C83-B5AF-C393166D3D4E", "corner_radius" : 0, "frame" : "{{85, 224}, {150, 32}}", "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "border_width" : 1, "alignment" : "center", "text" : "0", "font_name" : "<System>", "class" : "Label", "name" : "label3", "font_size" : 18 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{95, 207}, {142, 41}}", "class" : "Button", "attributes" : { "action" : "on_button", "flex" : "WHLRTB", "border_width" : 1, "frame" : "{{120, 224}, {80, 32}}", "title" : "submit", "uuid" : "BD6B3517-3570-46B3-B6E4-E967C932197B", "class" : "Button", "corner_radius" : 0, "name" : "button1", "font_size" : 15 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{174, 6}, {73, 19}}", "class" : "Label", "attributes" : { "font_size" : 18, "flex" : "WHLRTB", "frame" : "{{85, 224}, {150, 32}}", "uuid" : "AC87D8D9-39BC-4DA0-90E3-861257E72023", "class" : "Label", "alignment" : "left", "text" : "1", "custom_attributes" : "", "name" : "num_round", "font_name" : "<System>" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 6}, {150, 19}}", "class" : "Label", "attributes" : { "name" : "Round_title", "flex" : "WHLRTB", "frame" : "{{85, 224}, {150, 32}}", "uuid" : "7CBBD8E2-1DAE-471D-B7D6-2EAA890A3C7F", "class" : "Label", "alignment" : "right", "text" : "Round", "font_size" : 18, "font_name" : "<System>" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 33}, {95, 20}}", "class" : "Label", "attributes" : { "flex" : "WHLRTB", "font_name" : "<System>", "frame" : "{{85, 224}, {150, 32}}", "uuid" : "7CBBD8E2-1DAE-471D-B7D6-2EAA890A3C7F", "class" : "Label", "alignment" : "center", "text" : "User name", "name" : "", "font_size" : 18 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{119, 33}, {77, 20}}", "class" : "Label", "attributes" : { "flex" : "WHLRTB", "font_size" : 18, "frame" : "{{85, 224}, {150, 32}}", "uuid" : "7CBBD8E2-1DAE-471D-B7D6-2EAA890A3C7F", "class" : "Label", "alignment" : "center", "text" : "point", "name" : "", "font_name" : "<System>" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{204, 33}, {97, 20}}", "class" : "Label", "attributes" : { "flex" : "WHLRTB", "font_name" : "<System>", "frame" : "{{85, 224}, {150, 32}}", "uuid" : "7CBBD8E2-1DAE-471D-B7D6-2EAA890A3C7F", "class" : "Label", "alignment" : "center", "text" : "total", "font_size" : 18, "name" : "" }, "selected" : false } ], "frame" : "{{0, 0}, {320, 480}}", "class" : "View", "attributes" : { "tint_color" : "RGBA(0.000000,0.478000,1.000000,1.000000)", "enabled" : true, "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)", "name" : "", "flex" : "" }, "selected" : false } ]
RNA-seqその10、Dockerで環境構築
RNA-Seqのパイプラインに限らず
他人のスクリプトが自分の環境では
うまく動かないことはよくある話
かと言ってクリーンな環境を
毎回用意もできない
そこでDockerをつかって
クリーンなubuntuに
RNA-Seqのパイプラインを実行できる
環境を作ってみた
作ったのはTrinityを動かす環境
以下の過去記事を参考に構築した
mecobalamin.hatenablog.com
mecobalamin.hatenablog.com
mecobalamin.hatenablog.com
1番目の記事を参考にDockerを動かすことができたら
今回は2番目の記事を参考に120GBのストレージをもつ
Virtual Machineを作成する
3番目の記事を参考にしてWindows-Docker間で
ファイルのやり取りができるようにする
Trinityは出力ディレクトリに
ファイルのシンボリックリンクを作成するが
現状Windows10 homeでは仮想マシンから
ホストにシンボリックリンクを貼れない
そのため出力先はDocker内にし
生成されたファイルは終了後に
Widows側に移動して次の作業に使用する
ホストからゲストにはシンボリックリンクを貼れるので
入力するbamファイルはホストにある
環境構築にDockerfileを利用した
Dockerfileとは以下のようなもの
Docker は Dockerfile の命令を読み込み、自動的にイメージを構築できます。
平たく言えばダウンロードしたubuntuのイメージファイルに
必要なコマンドをインストールする操作を
記述したファイル
このファイルをdockerを使ってビルドすると
必要なコマンドの入ったubuntu imageを作成できる
実際に作ったDockerfileは以下の通り
# install ubuntu FROM ubuntu # set shell type SHELL ["/bin/bash", "-c"] # update apt-get and install commands RUN apt-get update && \ apt-get install -y openjdk-8-jre && \ apt-get install -y less && \ apt-get install -y wget && \ apt-get install -y unzip && \ apt-get install -y vim ENV RNASEQ_PATH=/RNA-Seq ENV TMP_PATH=${RNASEQ_PATH}/tmp ENV CONDA_PATH=${RNASEQ_PATH}/miniconda3 WORKDIR ${TMP_PATH} # install miniconda3 RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh RUN chmod 755 ${TMP_PATH}/Miniconda3-latest-Linux-x86_64.sh && \ ${TMP_PATH}/Miniconda3-latest-Linux-x86_64.sh -b -p ${CONDA_PATH} ENV PATH=${CONDA_PATH}/bin:${PATH} RUN conda update conda && \ conda install -c bioconda trimmomatic=0.39 && \ conda install -c bioconda trinity=2.6.6 && \ conda install -c bioconda ea-utils=1.1.2.779 && \ conda install -c bioconda numpy=1.15.0 && \ conda install -c bioconda hisat2=2.1.0 && \ conda install -c bioconda stringtie=2.1.1 # make directory for shared directory and scripts RUN mkdir -p ${RNASEQ_PATH}/data && \ mkdir -p ${RNASEQ_PATH}/scripts # Perl setting RUN ln -sf ${CONDA_PATH}/lib/libcrypto.so.1.1 ${CONDA_PATH}/lib/libcrypto.so.1.0.0 RUN mv -f /usr/bin/perl /usr/bin/perl.5.30.0 && \ ln -sf ${CONDA_PATH}/bin/perl /usr/bin/ ENV PERL5LIB=${PERL5LIB}:${CONDA_PATH}/lib/5.26.2 # change working directory WORKDIR ${RNASEQ_PATH}
この内容をDockerfileという名前のファイルに保存する
DockerfileのあるディレクトリにはDockerfileのみを保存する
Dockerfileのあるディレクトリで以下のコマンドでビルドする
$ docker build -t hogehoge:hugahuga .
Dockerfileにエラーがなければ
Repositoryがhogehoge
tagがhugahugaの
imageが作成される
作成したimageは以下のコマンドで実行する
docker run --rm -v /e/hoge:/tmp/fuga -it hogehoge:hugahuga /bin/bash
ディレクトリのhogeとfugaは
windowsのディレクトリhogeに
dockerのディレクトリfugaをマウントしつつ
imageのhogehoge:hugahugaを起動している
例えばwindowsのeドライブにあるtmpディレクトリを
今回作ったイメージ内の/RNA-Seq/dataにマウントするなら
この様になる
docker run --rm -v /e/tmp:/RNA-Seq/data -it hogehoge:hugahuga /bin/bash
imageの作り方などは以下の本を参考にした
(Amazonのページに飛びます)
自宅ではじめるDocker入門―人気のコンテナ型「仮想化ソフト」を使ってみる! (I・O BOOKS)
これよりDockerfileの説明
ベースになるのはubuntuのイメージ
Dockerのデフォルトではshを使うのでbashに変更している
/RNA-Seq
というディレクトリを作成し、
それ以下にdata、tmp、scriptsというディレクトリを作成する
dataはwindowsとファイルのやり取りをするディレクトリ
scriptsはTrinityのスクリプトファイルを保存するディレクトリ
tmpはTrinityの一時ファイルを保存する作業ディレクトリ
過去記事をもとにTrinityで使うコマンドを追加する
mecobalamin.hatenablog.com
Javaのバージョンが古いのでアップデートする
lessやwgetも含まれていないことに驚いた
ほんと最小限
もっとサイズの小さなディストリビューションだとどうなるんだろう
pythonも使うのでminicondaをインストール
condaでいくつかパッケージをインストールするが
バージョン指定でインストールしている
Trinityは使えるオプションの関係で2.6.6をインストールしている
指定しないともっと古いバージョンがインストールされる
2.6.6よりも新しいバージョンも存在するが使ったことがない
コンテナ内で使うファイルパスはENVで指定する
${HOME}/.bashrcに記入するのと同じなのかもしれないが
Dockerfileから.bashrcに記入して
sourceコマンドで.bashrcの再読み込みでは
上手くパスを設定できなかった
perlもコマンドとライブラリのシンボリックリンクを貼り直している
最後にWORKDIRを変更している
これでWORKDIRが${HOME}になる
ここまでがDockerfileに記述した処理
以前Trinityの処理に使用したシェルスクリプトにも変更を加えて
/RNA-Seq/scritps/
に保存した
シェルスクリプトは以下の通り
#!/bin/bash echo "Trinity has began" date_begin=`date` dir_scripts="/RNA-Seq/scripts" dir_working="/RNA-Seq/data" dir_tmp="/RNA-Seq/tmp" echo "open sra list" dir_list_sra=${dir_scripts} name_sra="list_sra.txt" list_filename=$(cat ${dir_list_sra}/${name_sra} | sed 's/\.sra//') for i in ${list_filename} do echo "analyze ${i}" file_in="sort_${i}.bam" dir_in="hisat_${i}" dir_out="trinity_${i}" echo "makind directories" mkdir -p ${dir_tmp}/${dir_out} mkdir -p ${dir_tmp}/${dir_out} Trinity \ --genome_guided_bam ${dir_working}/${dir_in}/${file_in} \ --genome_guided_max_intron 10000 \ --verbose \ --output ${dir_tmp}/${dir_out} \ --workdir ${dir_tmp}/${dir_out} \ --CPU 1 \ --max_memory 10G mv ${dir_tmp}/${dir_out}/Trinity-GG.fasta ${dir_tmp}/${dir_out}/Trinity-GG_${i}.fasta TrinityStats.pl ${dir_tmp}/${dir_out}/Trinity-GG_${i}.fasta > \ ${dir_tmp}/${dir_out}/Trinity-GG_${i}.stats done echo ${date_begin} echo `date`
bamファイルはwindows側に保存されていて
結果はDocker側に出力される
スクリプトファイルを加えたimageを保存するなら
docker commitコマンドを使う
$ docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
今回作成したimageのIDはdf2113fdef5eなので
$ docker commit df2113fdef5e hogehoge:hugahuga
とすると
Repositoryがhogehoge
Tagがhugahuga
のimageを作成できる
また
$ docker save hogehoge:hugahuga > hogehoge_hugahuga.tar
を実行するとtar形式で保存されて持ち出せるようになる
つまり他のPCやvirtual machineで使用できるようになる
image idでも保存はできるがそれだと
tarファイルを読み込んだときに
repositoryとtagの情報を失っているので
repository:tagを使ってtarファイルを作るのがよさげ
ここまででDockerにRNA-Seqのパイプラインを実行できる環境を構築できた
Dockerfileを使えば異なるVirtual Machine上にも
Trinityを実行する全く同じ環境が作成できる
あとはDockerの環境構築と
直接WSL上に環境を構築するのとで
どっちが手間がかかるか
ってことかもしれない
Dockerだと他のパイプラインに影響を与えずに
コマンドのアップデートができたり
うまくいかないときに
作り直しするのも楽なのは助かる
それと作成したimageのサイズは2.56GBになった
ベースのubuntuが80MB以下だったので
シークエンスのデータを含まずにこのサイズは
かなり大きい気がする
dfとdocker statsは使用頻度が高かった
【 df 】コマンド――ディスクの空き領域を表示する:Linux基本コマンドTips(58) - @IT
docker stats — Docker-docs-ja 20.10 ドキュメント
Dockerの使い方で調べると
ウェブサーバーとして使っていたりするらしい
もしかしたらJBrowseを実行するのに良かったりして
そのうち時間があれば作ってみたい
8 May 2020 追記
計算に使っていたPCが落ちてた
つい3時間前までは動いていたのに・・・
再起動後にログイン画面ならわかるが
BIOS画面になっていたのが気になる
20時間ぐらいやっていたことが全部消えてしまった
virtual machineも当然落ちたので記録なし
出力先をホスト側にしないとこんなとき何も残らないな
追記ここまで