scikit-learnをインストールした
MacOSX(10.7.5)でInstalling scikit-learnを見ながらpip installしたらあっさり成功したので喜んでいたのだが、いざ使ってみるとsoを読もうとしてATLで始まるシンボルを見つけられずにエラーになる。
import sklearnが成功しただけで満足して、ちゃんと「nosetests sklearn --exe」しなかったのがいけない。動的に読み込まれるものがちゃんと動くかどうかテストすることが必要だった。
今回の問題は、振る舞いとしてはこれと同じ:python - scikit-learn fails to load - Stack Overflow
from .cd_fast import sparse_std ImportError: sklearn/linear_model/cd_fast.so: undefined symbol: ATL_dcopy
で、こちらではワークアラウンドのスクリプトが紹介されている。Linking problem with atlas on OS X · Issue #1247 · scikit-learn/scikit-learn
このスクリプトは「-L/opt/local/libが付いているコマンドを、全部-L/opt/local/libを削って再実行」というもの。しかし、あれはportでいれて、これはpipで入れて、それはソースからワークアラウンドスクリプト噛ませて入れて、というのはなるべくしたくないなぁ。
MacPortで入っているATLASが悪さをしている風だったので、まずMacPortをバッサリ削除して、そこからport install py27-scikit-learnで入れたらどうなるかを確認してみた。テストでATLAS系の問題が引っかからなくなった。めでたしめでたし。
でもテストは1個エラーになる。
====================================================================== ERROR: sklearn.cluster.bicluster.tests.test_utils.test_get_submatrix ---------------------------------------------------------------------- Traceback (most recent call last): File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nose/case.py", line 197, in runTest self.test(*self.arg) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/sklearn/cluster/bicluster/tests/test_utils.py", line 43, in test_get_submatrix assert_true(np.all(X != -1)) File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 422, in assertTrue if not expr: File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/sparse/base.py", line 183, in __bool__ raise ValueError("The truth value of an array with more than one " ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(). ----------------------------------------------------------------------
def test_get_submatrix(): data = np.arange(20).reshape(5, 4) rows = [True, True, False, False, True] cols = [False, False, True, True] for X in (data, csr_matrix(data)): submatrix = get_submatrix(rows, cols, X) if issparse(submatrix): submatrix = submatrix.todense() assert_array_equal(submatrix, [[2, 3], [6, 7], [18, 19]]) submatrix[:] = -1 assert_true(np.all(X != -1))
これcsr_matrix(data)がsparse matrixを返して、X != -1でブロードキャストされてboolのsparse matrixになって、 *それがnp.allに渡されてもなぜかboolではなくsparse matrixが返る* という現象なのでsparse matrixのバグかnp.allの設計がイケてないのかじゃないかと疑っているが、まあ続きは今度気が向いたら追いかける。