強弱と高低

Python3をメインに

sklearn.manifold.tsneのメモリリークを回避するために(Anacondaのみ)

現象

大規模データでscikit-learnのmanifold.tsneを使うとメモリエラーを起こします。Pythonでメモリエラーか。

原因

mklのバグ、、、らしい。以前にscikit-learnにイシューが立っていたようだ。バージョンが上がった現在でも改善はされていない。このイシューはPython2系時点だった。今回はPython3系なのでやはりバージョンも関係ない。

Python crashes when calculating large t-SNE · Issue #4619 · scikit-learn/scikit-learn · GitHub

対策(翻訳)

Anacondaのみだが conda install nomkl これで解決できる。これでintel-mkl ライブラリを使わないためメモリリークを起こさないようだ。

非Anacondaの場合はラッパーを利用することになる。

GitHub - danielfrg/tsne: A python wrapper for Barnes-Hut tsne

自分はAnacondaだったのでこっちは試していない。念の為。

pandasで要素内に特定の文字列が含まれる行を抜き出したい

列Aに"美"が含まれる行を抜き出す

index A ...
0 太郎 ...
1 真由美 ...
2 和則 ...
3 和美 ...
4 哲也 ...
5 ...

というDataFrame(df)があったとする。 このとき、"美"という文字列を含む行だけ欲しいという場合にどうするか。

str.containsを使う

df[df["A"].str.contains("美")]

これで

index A ...
1 真由美 ...
3 和美 ...

が返ってくる。 詳細はドキュメントで確認して欲しい。

pandas.Series.str.contains — pandas 0.19.1 documentation

pandasで条件にあった値を持つ行を削除する場合

列Aにあるnという値を持つ行を削除したい

df A B C
0 k n n
1 n n n
2 n k k
... ... ... ...
1000 n m m
... ... ... ...

この1行目2行目に該当する行を削除したい時にどうするか。
もちろんこの簡単な例ではdf.drop([1,2,1000])でいける? まさかそんな話ではない。

方針

  1. Aにnという値を持つ行を削除する
  2. Aにn以外の値を持つ行を抽出する

方針1

正直わからんかった。df.drop()はindexの値をリストとして与えればうまく削除できる。
ただ, df[df.A == n]で得られたDataFrameからindexのリストを取得することはどこを見ても書いてなかったしそもそもできないのかもしれない。

過去にindexの値を取得するスクリプトを書いた気がするがそれはまた別の機会に。

方針2

df[df.A != n]

これでよい。削除する削除するという頭だとどうしてもdf[df.A == n]をdropすることばかりに頭がいくが, 逆に考えてn以外の値を持つ行を抽出する。そう考える。

.vimrcをGitで管理するのはいいけれども

.vimrcをGitで管理したいのだけれど

/home/xxx/以下にそのままGitを置くわけじゃあるまいし, どうやるんだろうと思っていたら見つけた.

シンボリックリンクを貼ればいけるわけね〜

mkdir ~/dotfiles
mv  ~/.vimrc ~/dotfiles/_vimrc
ln -s ~/dotfiles/_vimrc ~/.vimrc

holypp.hatenablog.com

matplotlib savefigをサーバーで行う場合

そのままサーバーでも画像出力させようとすると

Traceback 
... 
...
RuntimeError: Invalid DISPLAY variable

うまくいかない

解決策

import matplotlib as mpl
mpl.use('Agg')

これを追加する。見つかるドキュメントにはそれしか書いておらず「追加したのにうまくいかない」状況が起こりうる。

注意点

  • 追加するのは, import matplotlib.pyplot as pltの前でなければならない
  • 追記するファイルは, savefigがあるファイルという訳ではなく, 実行するファイルである

これに気をつければ問題なく画像出力ができるはずである. PNGの他の場合も知りたいなんてときは以下に詳しくまとまっている,

qiita.com

matplotlibでOverflowError: In draw_path: Exceeded cell block limitというエラーが出る

引っかかったところ

matploblibで比較的大きなデータをプロットしようとしたとき, plt.savefigをしようとして OverflowError: In draw_path: Exceeded cell block limit というエラーが出た.

解決策

結構簡単で,

import matplotlib as mpl
mpl.rcParams['agg.path.chunksize'] = 100000

この文を加えるだけ. 100000という数字は大きければとりあえずOKなようだ.

経験的モード分解(Empirical Mode Decomposition)とは

経験的モード分解とは

Huangらによって提案された時系列信号を非定常・非線形な時間-周波数な空間に変換する手法のことで, 大まかな理解として, もともとの信号 x(t) を固有モード関数IMF(Intrinsic Mode Function)と残滓に分解するということを頭に入れておけば良い.

分解するということ

信号を分解する手法は従来から存在しており, FFTやウェーブレット変換がある. これは大学の授業でも扱うくらい古典的で強い手法だ. では何がEMDと違うのか.

FFTやウェーブレット変換はsin関数等の基底を仮定して周波数領域へと変換する一方, EMDは所謂ヒューリスティックな変換を行う. 基底の仮定を置かずに信号を順々に分解していき閾値でもってループの終了とする.

アルゴリズム

これはすでに様々な論文が出回っており再掲するのも忍びない.が, 引用させてもらう.

1. 入力信号 x_0(t)の全ての極値を検出する
2. 極大点と極小点をそれぞれ補間し,上側包絡線 emax(t)と下側包絡線 emin(t)を得る
3. 上側包絡線と下側包絡線の局所平均m(t) = ( emin(t) + emax(t) ) / 2 を算出する
4. 入力と局所平均の差分 y(t) = x(t) - m(t)を入力とみなして 1~4 を繰り返す。
5. 局所平均の標準偏差が閾値以下になった時点で,y(t) を IMF とみなし,ループを終了する
6. 入力信号と IMF の残差 x1(t) = x0(t) - y(t)を新たな入力信号として 1~6 を繰り返す
7. 全ての IMF を抽出したら(x_n(t)の極値が1 つになったら)終了する

出典:http://old.acoust.ias.sci.waseda.ac.jp/publications/happyou/asj/asj-yatabe-2012sep.pdf

要するになにか

暴論ではあるが, EMDは入力信号を,時間軸を中心とした信号に分解することと言って良いかもしれない. 信号の平均が0になるような信号をIMFとしているため波形全体として上下のトレンドがあるような信号は存在しない.

例えば、下のようなトレンドのある信号は, sin波のような切片が存在しない平均面積0の波形に分解できるのだろう. http://touki-tousi.com/wp-content/uploads/2015/09/943578ab5a1148ce847c2eb36745c84d.jpg

何に使うのか

主成分が出てくることから, 支配的な振動を抽出できるという仮説が成り立ち,複雑にノイズが入り込んだ信号波形から,対象の長期信号を取得するような「変調」に使うことができる.そういった考え方の一つとしてノイズ除去がある.IMFの中にホワイトノイズのようなものがあったらそれを削除すれば元々の信号からノイズを削減できたことになる.

昨今の深層学習の成果では, EMDと同じように「信号の分解を何らかの仮定をおかずに行う」ことができてきている.例えば,時間方向での畳込みは,FFTのような操作と同等と解釈することができるということだ. こうした,データに語らせる方法が使えない場合において,EMDのようなヒューリスティックな手法は試してみる価値はあるのだろうと思う.

修正履歴

[2018-06-06] 深層学習への言及を追加した