Julia tips #5: MCMC法(Metropolis-Haisting法)を実装してみた
JuliaにてMCMC法(Metropolis-Haistings法)を実装してみました。
- コードの利用・改変・再配布は自由にして構いませんが、何か起きても責任は取りません。
- 一部いらない変数や無駄実装が混じってます。動作に問題はありません。バイオ実験系なので許して...。
- 一番下にコードを全部まとめたものを書いておきました。 パパっと試してみたい方はコピペしてどうぞ。
環境
- Windows 10 HOME
- Julia 0.6.2
実装
使うパッケージのインポート
using Distributions using Gadfly using StatsBase
目標分布を定義する
MCMCでよく出てくる有名なあれです。
μ = [-5.0, -5, 5.0] σ = [1.0, 0.1, 1.0] function target(x::Array{Float64, 1}) arr = zeros(length(x)) Normal_val_1(x) = 0.45 * 1/sqrt(2π*σ[1]^2)*exp(-(x-μ[1])^2/(2σ[1]^2)) Normal_val_2(x) = 0.45 * 1/sqrt(2π*σ[2]^2)*exp(-(x-μ[2])^2/(2σ[2]^2)) Normal_val_3(x) = 0.1 * 1/sqrt(2π*σ[3]^2)*exp(-(x-μ[3])^2/(2σ[3]^2)) for i in 1:length(x) arr[i] = Normal_val_1(x[i]) + Normal_val_2(x[i]) + Normal_val_3(x[i]) end return arr end function target(x::Float64) arr = zeros(length(x)) Normal_val_1(x) = 0.45 * 1/sqrt(2π*σ[1]^2)*exp(-(x-μ[1])^2/(2σ[1]^2)) Normal_val_2(x) = 0.45 * 1/sqrt(2π*σ[2]^2)*exp(-(x-μ[2])^2/(2σ[2]^2)) Normal_val_3(x) = 0.1 * 1/sqrt(2π*σ[3]^2)*exp(-(x-μ[3])^2/(2σ[3]^2)) val = Normal_val_1(x) + Normal_val_2(x) + Normal_val_3(x) return val end
多重ディスパッチを利用して、スカラーが来たら値を一つだけ返し、ベクトルが来たらベクトルを返すようになっています。
変な分岐処理を書かなくていいので楽ですね。
上記の関数を定義後に、このコードで分布を見ることができます。
x = Array{Float64}(linspace(-10, 10, 1000)) y = target(x) p=plot(x=x, y=y, Geom.line)
こんな感じ。
Sampler型を定義
Pythonのようにクラスを作って、メンバ変数としてMCMC法の状態を保持したいなーと思ったのですが、JuliaにはPythonのようなクラスがありません。*
無いならそれっぽい使い方ができればいいじゃん!
という発想です。
ここで定義した型をMCMCモジュールへ投げて、変数の保持に使います。
mutable struct Sampler x0::Float64 x_present::Float64 target::Any propose_next::Any burn_in::Int count::Int acceptance::Float64 seed::Int random_state::MersenneTwister end
各変数の説明
x0: 初期値
x_present: 現在の値を保持
target: 目標分布の密度関数
propose: 次点を生成する関数
burn_in: 焼きなまし期間
count: 現在のステップ数
acceptance: 採択回数(本当は採択率を入れたいが考え中。今回は不要。)
seed: 乱数の初期パラメータ
random_state: 乱数ジェネレータ(これを保持することで、途中からサンプリングを再開できる)
回してみる
seed = 0 rng = srand(seed) gaussian = Normal(0,2) uniform = Uniform(-10, 10) inits = rand(uniform) target = target generator(x) = x + 0.5*rand(gaussian) burn_in = 10000 num_sample = 1000000 cnt = 0 acceptance = 0 sampler = Sampler(inits, inits, target, generator, burn_in, cnt, acceptance, seed, rng) burn_in = MCMC.burn_in(sampler) samples = MCMC.run(sampler, num_sample)
結果のプロット
set_default_plot_size(9inch, 12inch/golden) # プロット範囲 _start = 990000 _last = 1000000 p1 = plot(y=autocor(samples), Geom.line, Guide.ylabel("Autocorrelation\ncoefficient"), Guide.xlabel("Lag"), Guide.title("Autocorrelation")) p2 = plot(x=_start:_last, y=samples[_start:_last], Geom.line, Guide.xlabel("Steps"), Guide.ylabel("Value"), Guide.title("Trajectory")) p3 = plot(layer(x=x, y=y, Geom.line, Theme(default_color="magenta")), layer(x=samples, Geom.histogram(density=true)), Guide.ylabel("Frequency"), Guide.xlabel("Samples"), Guide.title("Posterior distribution"), Guide.manual_color_key("Color", ["Target", "Posterir"], ["magenta", "cyan"])) p = title(vstack(hstack(p1, p2), p3), "Metropolis-Hastings (σ=2)", Compose.fontsize(14pt))
できました。
全コードまとめ
using Distributions using Gadfly using StatsBase using Cairo # 目標分布の定義-------------------------- μ = [-5.0, -5, 5.0] σ = [1.0, 0.1, 1.0] function target(x::Array{Float64, 1}) arr = zeros(length(x)) Normal_val_1(x) = 0.45 * 1/sqrt(2π*σ[1]^2)*exp(-(x-μ[1])^2/(2σ[1]^2)) Normal_val_2(x) = 0.45 * 1/sqrt(2π*σ[2]^2)*exp(-(x-μ[2])^2/(2σ[2]^2)) Normal_val_3(x) = 0.1 * 1/sqrt(2π*σ[3]^2)*exp(-(x-μ[3])^2/(2σ[3]^2)) for i in 1:length(x) arr[i] = Normal_val_1(x[i]) + Normal_val_2(x[i]) + Normal_val_3(x[i]) end return arr end function target(x::Float64) arr = zeros(length(x)) Normal_val_1(x) = 0.45 * 1/sqrt(2π*σ[1]^2)*exp(-(x-μ[1])^2/(2σ[1]^2)) Normal_val_2(x) = 0.45 * 1/sqrt(2π*σ[2]^2)*exp(-(x-μ[2])^2/(2σ[2]^2)) Normal_val_3(x) = 0.1 * 1/sqrt(2π*σ[3]^2)*exp(-(x-μ[3])^2/(2σ[3]^2)) val = Normal_val_1(x) + Normal_val_2(x) + Normal_val_3(x) return val end # Sampler型を定義(MCMCモジュール内で状態を保持する) mutable struct Sampler x0::Float64 x_present::Float64 target::Any propose_next::Any burn_in::Int count::Int acceptance::Float64 seed::Int random_state::MersenneTwister end # MCMC法の本体 module MCMC function present(sampler) return sampler.x_present end function next(sampler) proposed = sampler.propose_next(sampler.x_present) odds = sampler.target(proposed)/sampler.target(sampler.x_present) if rand(sampler.random_state) < odds sampler.x_present = proposed sampler.acceptance += 1 return proposed else return sampler.x_present end end function burn_in(sampler) arr = zeros(sampler.burn_in) for i in 1:sampler.burn_in arr[i] = next(sampler) sampler.count += 1 end sampler.acceptance = 0 return arr end function run(sampler, n_steps) arr = zeros(n_steps) for i in 1:n_steps arr[i] = next(sampler) sampler.count += 1 end return arr end end # 実行コード seed = 0 rng = srand(seed) gaussian = Normal(0,2) uniform = Uniform(-10, 10) inits = rand(uniform) target = target generator(x) = x + 0.5*rand(gaussian) burn_in = 10000 num_sample = 1000000 cnt = 0 acceptance = 0 sampler = Sampler(inits, inits, target, generator, burn_in, cnt, acceptance, seed, rng) burn_in = MCMC.burn_in(sampler) samples = MCMC.run(sampler, num_sample) # 結果のプロット set_default_plot_size(9inch, 12inch/golden) _start = 990000 _last = 1000000 p1 = plot(y=autocor(samples), Geom.line, Guide.ylabel("Autocorrelation\ncoefficient"), Guide.xlabel("Lag"), Guide.title("Autocorrelation")) p2 = plot(x=_start:_last, y=samples[_start:_last], Geom.line, Guide.xlabel("Steps"), Guide.ylabel("Value"), Guide.title("Trajectory")) p3 = plot(layer(x=x, y=y, Geom.line, Theme(default_color="magenta")), layer(x=samples, Geom.histogram(density=true)), Guide.ylabel("Frequency"), Guide.xlabel("Samples"), Guide.title("Posterior distribution"), Guide.manual_color_key("Color", ["Target", "Posterir"], ["magenta", "cyan"])) p = title(vstack(hstack(p1, p2), p3), "Metropolis-Hastings (σ=2)", Compose.fontsize(14pt))
*burn in 期間が短いときに途中から再計算させたいので。
Julia tips #4: Cairoのインストールに失敗する
環境
- Windows 10 HOME
- Julia 0.6.2
JuliaでグラフをプロットするライブラリとしてはGadlyが有名?ですが、プロットをpng形式で保存するためにはCairoというパッケージが必要です。
そこでPkg.add("Cairo")したらインストールに失敗したというお話。
解決法も書いておきます。
エラーメッセージ
Pkg.add("Cairo")したら何やらダウンロードエラーが...
WARNING: Unknown download failure, error code: 2148270086 WARNING: Retry 1/5 downloading: https://cache.julialang.org/http://download.opensuse.org/repositories/windows:/mingw:/win64/openSUSE_Leap_42.2/noarch/mingw64-zlib1-1.2.8-8.15.noarch.rpm WARNING: Unknown download failure, error code: 2148270086 WARNING: Retry 2/5 downloading: https://cache.julialang.org/http://download.opensuse.org/repositories/windows:/mingw:/win64/openSUSE_Leap_42.2/noarch/mingw64-zlib1-1.2.8-8.15.noarch.rpm WARNING: Unknown download failure, error code: 2148270086 WARNING: Retry 3/5 downloading: https://cache.julialang.org/http://download.opensuse.org/repositories/windows:/mingw:/win64/openSUSE_Leap_42.2/noarch/mingw64-zlib1-1.2.8-8.15.noarch.rpm WARNING: Unknown download failure, error code: 2148270086 WARNING: Retry 4/5 downloading: https://cache.julialang.org/http://download.opensuse.org/repositories/windows:/mingw:/win64/openSUSE_Leap_42.2/noarch/mingw64-zlib1-1.2.8-8.15.noarch.rpm WARNING: Unknown download failure, error code: 2148270086 WARNING: Retry 5/5 downloading: https://cache.julialang.org/http://download.opensuse.org/repositories/windows:/mingw:/win64/openSUSE_Leap_42.2/noarch/mingw64-zlib1-1.2.8-8.15.noarch.rpm INFO: try running WinRPM.update() and retrying the install
大事なのは最後の1行のメッセージでした。
この通りにやってみるとインストールできました。
julia> using WinRPM
julia> WinRPM.update()
最後にさっきインストールに失敗したCairoをビルドし直します。
Pkg.build(Cairo)
これでうまくインストールできました。
Julia tips #3: ODE solverの速度比較 with Python
JuliaではSundials.jlをインストールするだけで、SundialsのODEソルバ、CVODEが使えます!!(マニアックすぎ?)
未知システムのパラメータ推定をする際、数値積分の区間をうまいこと刻まないと値が飛びすぎて計算できなかったり、刻む必要のないところで刻んでしまって計算不能に陥ることがあります。
そこでCVODEなどのAdaptive stepなODEソルバが必要なわけです。
何個か種類がありますが、有名どころでは
- LSODA
- CVODE
が2強といったところで、Pythonでよく使われるodeintもadaptive stepです(内部的にはLSODEとかいうやつらしいけど...良く知りません)。
じゃあ、JuliaでCVODEを呼び出して使うのと、Pythonでodeint使うのはどっちがどんくらい速いのよ?と思ったので比べてみました。
なお、Juliaのソルバについては比較してくれている方がいました。
CVODEの圧勝です。
Juliaのコードもこちらから借りてきて、Pythonと比較したいと思います。
実装
Julia(上記リンク先から部分的に拝借)
using Sundials # 非線形パラメータ mu = 0.2 # 関数定義 function vdp_sun(t, u, du) # dx/dt du[1] = u[2] # dy/dt du[2] = mu * (1.0 - u[1]^2.0) * u[2] - u[1] du end # パラメータ設定 u0 = [0.2; 0.2] t = [0.0:0.1:10.0;]
Python (3.6)
import numpy as np from scipy.integrate import odeint # 非線形パラメータ mu = 0.2 # 関数定義 def vdp_sun(u, t): # dx/dt dxdt = u[1] # dy/dt dydt = mu * (1.0 - u[0]**2.0) * u[1] - u[0] return [dxdt, dydt] # パラメータ設定 u0 = [0.2, 0.2] t = np.arange(0,10.1,0.1) # メインの計算 res = odeint(vdp_sun, u0, t)
速度比較
Juliaは1ループごとに出力、Pythonのtimeitではループにかかった平均時間を出力していますが、大雑把な比較はこれで良いでしょう。
見やすさのため10回だけ回しています。
Julia
res = Sundials.cvode(vdp_sun, u0, t); for i in 1:10 @time res = Sundials.cvode(vdp_sun, u0, t); end
Python (3.6)
%timeit -n 10 odeint(vdp_sun, u0, t)
結果
Julia
0.000206 seconds (1.81 k allocations: 43.734 KiB) 0.000132 seconds (1.81 k allocations: 43.734 KiB) 0.000130 seconds (1.81 k allocations: 43.734 KiB) 0.000117 seconds (1.81 k allocations: 43.734 KiB) 0.000118 seconds (1.81 k allocations: 43.734 KiB) 0.000115 seconds (1.81 k allocations: 43.734 KiB) 0.000115 seconds (1.81 k allocations: 43.734 KiB) 0.000115 seconds (1.81 k allocations: 43.734 KiB) 0.000116 seconds (1.81 k allocations: 43.734 KiB) 0.000124 seconds (1.81 k allocations: 43.734 KiB)
Python (3.6)
716 µs ± 5.63 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
まとめると以下のようになります。
- Julia: 128.8 µs ± 26.43 µs
- Python: 716 µs ± 5.63 µs
Juliaの方が5倍ほど速い!
シミュレーションを何千回、何万回と繰り返すものにとっては5倍の高速化は結構大きいと思います。
予想ではもっと変わるかなと思っていたのですがこんなものでした。
Pythonを高速化
Pythonを高速化したら、Sundialsに迫るのでは??
と考えたので、numbaで高速化したPythonで戦ってみた。
odeintに渡す微分方程式をjit+型指定すると速くなる。
from scipy.integrate import odeint import numpy as np from numba import jit # 型指定jit, tが逐次的に渡されることに注意 @jit("float64[:](float64[:], float64)", nopython=True) def vdp_sun_jit(u, t): # dx/dt dxdt = u[1] # dy/dt dydt = mu * (1.0 - u[0]**2.0) * u[1] - u[0] return np.array([dxdt, dydt]).astype(np.float64) # パラメータ設定 u0 = np.array([0.2, 0.2]).astype(np.float64) # 渡す型に合わせる t = np.arange(0,10.1,0.1).astype(np.float64) # 渡す型に合わせる # メインの計算 res = odeint(vdp_sun, u0, t) %timeit -n 10 odeint(vdp_sun_jit, u0, t)
結果
387 µs ± 11.6 µs
うーん、速くはなりましたが2倍行かないくらいでしたね。
まとめ
やっぱSundials凄い。
数値計算ではJuliaを使おう!
Julia tips #2: ファイル検索
スタックオーバフローより。
「組み込み関数はないけどワンライナーで書けるよ」
とのこと。
関数化したほうが便利ですね。以下コードです。
searchdir(path,key) = filter(x->contains(x,key), readdir(path))
readdir (path)
渡したpathの中にあるディレクトリ、ファイルを文字列として出力してくれる
contains (x, key)
文字列 x に 文字列 key が含まれているかtrue or falseで返してくれる
filter (function, collection)
collectionを受け取る関数functionがtrueを返したら、そのcollectionのコピーを返す
例)
a = 1:10 julia> filter(isodd, a) 1 3 5 7 9
Julia tips #1:【超簡単】コードのテスト
テストマクロについてのメモ(2017/12/03時点)
環境
windows 10 Pro (Fall Creators Update)
WSL有効化済み
WSLのbashにて実行
環境構築の仕方はこちらをどうぞ
テストマクロの使い方
まずはJuliaのバージョン確認から
$ julia --version julia version 0.5.2
foo(x)という関数があったとして、その挙動を引数ごとにまとめて行う方法
julia> @testset "Foo Tests" begin @test foo("a") == 1 @test foo("ab") == 4 @test foo("abc") == 9 end Test Summary: | Pass Total Foo Tests | 3 3
全部で3回テスト(Total)して、3回ともクリアしたぞ(Pass)って意味。
ネストしていても大丈夫
julia> @testset "Foo Tests" begin @testset "Animals" begin @test foo("cat") == 9 @test foo("dog") == foo("cat") end @testset "Arrays $i" for i in 1:3 @test foo(zeros(i)) == i^2 @test foo(ones(i)) == i^2 end end Test Summary: | Pass Total Foo Tests | 8 8
結果が全部まとめられているが、エラーを吐いている場合は展開して表示してくれる。
Arrays: Test Failed Expression: foo(ones(4)) == 15 Evaluated: 16 == 15 in record at test.jl:297 in do_test at test.jl:191 Test Summary: | Pass Fail Total Foo Tests | 3 1 4 Animals | 2 2 Arrays | 1 1 2 ERROR: Some tests did not pass: 3 passed, 1 failed, 0 errored, 0 broken. in finish at test.jl:362
他にも色んなマクロがある
大体一緒か判定する
@test a≈b
≈は\approxと打った後にtabで表示される。
以下、エラーコードつき。
めっちゃ小さい数値誤差を許容して等しいかどうか判定
julia> @test_approx_eq 1. 0.999999999 ERROR: assertion failed: |1.0 - 0.999999999| < 2.220446049250313e-12 1.0 = 1.0 0.999999999 = 0.999999999 in test_approx_eq at test.jl:75 in test_approx_eq at test.jl:80
e-12なら通常使用なら問題なさそうかな?
許容誤差を設定して判定
@test_approx_eq_eps 1. 0.999 1e-3 ERROR: assertion failed: |1.0 - 0.999| <= 0.001 1.0 = 1.0 0.999 = 0.999 difference = 0.0010000000000000009 > 0.001 in error at error.jl:22 in test_approx_eq at test.jl:68
こんな書き方もあったりする。
julia> ≈(1, 0.999, atol=0.001) true julia> ≈(1, 0.999, atol=0.0001) false
感想
Pythonでデコレータ書いたりするより遥かに簡単で良い。
Windows Subsystem for Linux + Python + Jupyter + Julia
Windows Subsystem for Linux (WSL)で開発環境を構築する
Windows10 Fall Creators Updateにて、WSLが正式版となりました。
以下ではWSLの有効化は事前に行っているものとします。
WSLでは、Linuxが仮想環境ではなくサブシステムとしてWindows上で動く。
細かいことはわからないが、提供されていないカーネルを必要とするソフトウェアはWSL上では動かないらしい。
Linux互換環境といったところか。
Bashシェルやapt、gccコンパイラ、gitといったものは普通に動くので個人的には十分だ。
コンパイルして生成された実行ファイルはOSを跨ぐと当然動かないので、linux環境に統一したいというのが、今回WSL上に環境を構築する理由である。
大抵のスパコンや小規模計算機サーバなどはOSにlinuxを採用しているのでメリットは多い。
WSL上にPython仮想環境を構築する
WSL上にデフォルトのPythonが入っているので、WSL自体を壊してしまわないように仮想環境にAnacondaを使ってPythonを導入する。
pyenvのインストール
直接Anacondaを入れても良いが要らないパッケージを入れたくないので、pyenv経由で入れると良い。
$ sudo aptitude install git $ git clone https://github.com/yyuu/pyenv ~/.pyenv $ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc $ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc $ echo 'eval "$(pyenv init -)"' >> ~/.bashrc $ source ~/.bashrc
*gitが入っている人は1行目はいらない。
Anacondaのインストール
pyenvから入れる。
$ pyenv install --list
いろいろ表示されるが、anaconda~~~ってやつの最新版を探す。
自分の場合はanaconda3-5.0.1が最新だった。
$ pyenv install anaconda3-5.0.1 $ pyenv global anaconda3-5.0.1 $ pyenv rehash
これでAnacondaのインストールは完了。
GUIのインストール
WSLにはGUIがないので、ipythonは動いてもmatplotlibが動かない。
ココから以下の二つをダウンロード&インストールする。
インストール後、Xmingを起動すると、windowsのタスクバーにXmingが現れるのでカーソルを合わせると
Xming server:0.0
と出ることを確認。こいつをdisplayの出力先に指定してやる。
$ echo 'export DISPLAY=localhost:0.0' >> ~/.bashrc $ source ~/.bashrc
これでGUIの設定ができた。
matplotlibの導入
以上で大方準備は完了しているが、このままだとmatplotlibのインストールがうまくいかない。 また、jupyterのインストールにも失敗した(確か)。
これらの問題を避けるためにWSLで必要なパッケージをインストールしておく必要がある。
$ sudo aptitude install libqtgui4 $ sudo add-apt-repository ppa:aseering/wsl $ sudo aptitude update $ sudo aptitude install libzmq3 $ conda install -c jzuhone zeromq=4.1.dev0
これで動くようになったはず。
あとはconda installするだけ。
$ conda install matplotlib jupyter
numpyはmkl対応のものがデフォルトになっている。
エラーを吐く場合はmklを使わないOpenBLASのものを使うようにする。
$ conda install nomkl $ conda update --all
Juliaのインストール
WSLでは、Juliaのインストール自体はUbuntuと同じで簡単にできる。
$ sudo add-apt-repository ppa:staticfloat/juliareleases $ sudo add-apt-repository ppa:staticfloat/julia-deps $ sudo apt-get update $ sudo apt-get install julia
JupyterがインストールされていればIJuliaも簡単に導入可能
$ julia > Pkg.add("IJulia")
まとめ
WSLにPythonの開発環境をpyenvを経由してAnacondaで構築した。
Jupyterの導入に便乗する形でJuliaもインストールした
Google Driveで文献管理 Paperpileが凄い
研究者を悩ませる文献管理
研究者にとって、増え続ける論文は仕事の効率を悪くする。
- ほしい文献がどこに行ったか覚えていない
- supporting informationどこよ
- ファイルがダブっている
- てか読んだっけ?
なんてことは日常茶飯事で困っていた(情報整理とか豆なことは苦手)。
そこで文献管理ソフトを使うわけだが、日本では以下が有名どころのようだ。
文献管理ソフトの例
ただ、どれも容量に制限があったり、結構高いお金がかかったりとパッとしない。
求めることは
- オンラインストレージに文献保存
- クラウドでの文献管理環境
- メモ的なものが書けて、かつ簡単に確認できる
こんなのないかなーとずっと思っていたら、あった。
Paperpile
Paperpileの特徴
- 文献はGoogle Driveに保存
- ブラウザからワンクリックでインポート&pdfダウンロード
- メモが簡単&閲覧も簡単
- Google Docsにcitationができる。
- academic use(要学校のアドレス)なら家でも文献ダウンロードできる??(気がするだけ?)
- ブラウザベースなので引用元を簡単に表示できる。
まぁとにかく凄い。
管理させるだけなら最強では?
残念な点
- wordプラグインは開発中らしい(フォーラムによると優先度低め)
- PCからでないと使えない。
タブレット版はベータテスト中らしいが、いつ正式版がでるのか不明。
ただ、Google DriveにあるpdfはGoogle Driveに追加できるMetaPDFでコメントをペタペタしながら読めたりするので別にいいかも。
日本語で紹介・解説している人を見たことがないので参考になれば。
os.walkでエラーが出た
pythonの話題。
なお環境はAnacondaで構築して、python3.5となっている。
普段使っていたスクリプトがファイル読み込みでエラーをはいたのでその原因を調べた。
pandasとかいう便利なやつ
データ分析する人なら御用達のpandas。
エクセルファイルを簡単に読み込める凄いやつ。
こいつで複数ファイルをループして読み込みまくろうとしたらことが起きた。
こいつのバージョンが問題なのではと色々調べたが、結局問題はもっと根本的なところにあった。
なんだかglobとかos.walkが怪しい…
細かい説明はすっ飛ばして結論を言うと、excelとかのofficeソフトって._XXXXXXって感じの隠しファイルを生成していて、Ubuntuはもれなく条件にヒットしたファイル名を拾ってしまう。
windowsではこれを自動で無視するらしくglobだろうがos.walkだろうが問題にならない。
この._XXXファイルが読めないよ!!ってエラーをはいていたのだった。
ありがた迷惑である。
.(ドット)で始まるファイルを除けばいい
ということで隠しファイルを除くサンプルスクリプトを書いた。
import os parentPath = 探したいディレクトリのパス for root, dirs, fnames in os.walk(parentPath): for fname in fnames: if not fname.startswith("."): print(fname)
わかってしまえば簡単だった。
Ubuntuをアップデートしたらネットに繋がらなくなった
いつもの調子でsudo update!!PC
すると突然、DNSエラーが出てネットに繋がらなくなった。
同じ症状で困っている人もいると思うので記録しておく(調べれば一瞬で解決だけど)。
DNSサーバーって?
雑な言い方をすると、google、yahooなどの名前からIPアドレスを教えてくれるサーバー。
PCはIPアドレスがわからないと、googleやyahooやその他のPCなどに接続できない。
でもIPアドレスを毎回打ち込むのも、覚えるのも大変。
ニックネームだけ覚えて、ユーザーとしては実際のIPアドレスは隠蔽したい。
そんな面倒くさい部分を管理してくれているのがDNSサーバー。
なんで突然繋がらなくなった?
細かいところはわからないが、DNSサーバーの指定だか何かが勝手に書き換わってしまうらしい。
なんだそれ。
書き換えられないようにハードコードして解決
/etc/resolvconf/resolv.conf.d/head
最終行に
nameserver 8.8.8.8
と追記。
再起動すればネット復活。
まとめ
勉強になりました。
UbuntuでOneDriveを使いたい
Ubuntuで直感的にOneDriveを使いたい。
rcloneとかいう便利なソフトがあるらしい。
GUIもあるから設定してみた。
そんなお話。
rcloneってなに
Linux使いならよーくご存じだと思われるrsyncのクラウドバージョン。
それがrclone。
色々なクラウドストレージに対応しているようだ。
- Google Drive
- Amazon S3
- Openstack Swift / Rackspace cloud files / Memset Memstore
- Dropbox
- Google Cloud Storage
- Amazon Drive
- Microsoft OneDrive
- Hubic
- Backblaze B2
- Yandex Disk
- SFTP
- FTP
- HTTP
- The local filesystem
インストール
まずはインストールする
snapとかいうパッケージ管理マネージャ的な何かをaptでインストールしておく
sudo apt install snapd
snapでインストール
sudo snap install rclone --classic
アップデートしたい時
sudo snap refresh rclone --classic
rcloneを設定する
rclone config
interactiveに設定できる。
一問一答形式なので困ることもない。
No remotes found - make a new one n) New remote s) Set configuration password n/s> n name> remote Type of storage to configure. Choose a number from below, or type in your own value 1 / Amazon Drive \ "amazon cloud drive" 2 / Amazon S3 (also Dreamhost, Ceph) \ "s3" 3 / Backblaze B2 \ "b2" 4 / Dropbox \ "dropbox" 5 / Google Cloud Storage (this is not Google Drive) \ "google cloud storage" 6 / Google Drive \ "drive" 7 / Hubic \ "hubic" 8 / Local Disk \ "local" 9 / Microsoft OneDrive \ "onedrive" 10 / Openstack Swift (Rackspace Cloud Files, Memset Memstore, OVH) \ "swift" 11 / Yandex Disk \ "yandex" Storage> 9 Microsoft App Client Id - leave blank normally. client_id> Microsoft App Client Secret - leave blank normally. client_secret> Remote config Use auto config? * Say Y if not sure * Say N if you are working on a remote or headless machine y) Yes n) No y/n> y If your browser doesn't open automatically go to the following link: http://XXXXXXXXXXX/auth Log in and authorize rclone for access Waiting for code... Got code -------------------- [remote] client_id = client_secret = token = {"access_token":"XXXXXX"} -------------------- y) Yes this is OK e) Edit this remote d) Delete this remote y/e/d> y
上記のコマンドたちについて少し説明。
ここは空欄で良いです(この後自動設定で、OneDriveのページヘ行き認証を行うため)
Microsoft App Client Id - leave blank normally. client_id> Microsoft App Client Secret - leave blank normally. client_secret>
もし、自動でブラウザが立ち上がらない場合、以下の部分に書かれているurlヘ飛ぶ。
If your browser doesn't open automatically go to the following link: http://XXXXXXXXXXX/auth
OneDriveの認証画面が現れるので、承認する。
最後に
e) Edit existing remote n) New remote d) Delete remote r) Rename remote c) Copy remote s) Set configuration password q) Quit config e/n/d/r/c/s/q>
と聞かれるので、qを入力して終了。
このままでもCUIでコマンドを叩けば使えるが、rsyncのdeleteオプションが付いている状態でファイルのやり取りがされるらしく…
クラウド上のファイル全削除なんて事故が頻繁に起こるらしい。
ましてやコマンドなんてしばらく使わなければ忘れるもの。
そこで、ファイル全削除なうえ復元不可…なんて惨劇を回避するためにGUIを導入します。
RcloneBrowserの導入
rcloneがインストールされて、設定が終わっていることが前提です。
インストールする
sudo add-apt-repository ppa:mmozeiko/rclone-browser sudo apt-get update sudo apt install rclone-browser
これだけでインストールができるらしい…が、私の環境ではなぜかパッケージのダウンロードの段階で404 not found。
メンテナンス中とかだったのだろうか…。
仕方ないのでRcloneBrowaer公式からdebをダウンロードして直接入れた。
ダウンロードしてきたフォルダに移動して以下のようにコマンドを入力。
sudo dpkg -i rclone-browser_1.2_amd64.deb
準備は整った。
実行する。
rclone-browser
こんなwindowが立ち上がったら成功。
rcloneの設定が終わっていないとポップアップがでてきて、rcloneの設定をさせられる。
出てきたウィンドウに、rclone locationと.rclone.confのpathを入力すれば導入完了。
rcloneの場所がわからなければ
which rclone
で調べられる。
.rclone.confの場所は人によって違うかもしれないが、
/home/yourname/.rclone.conf
あるいは、Ubuntuなら
/home/yourname/.config/rclone/rclone.conf
となっている…と思う。
まとめ
Ubuntuからwebブラウザを経由せずにOneDriveにアクセスできるようになった!
マウント機能もあるらしいがexperimentalなので触らないでおく。