pyenvでPython環境を利用する

環境によっては、Pythonが古かったり、しかもそれを更新できなかったりする場合があるかと思うけど、そんなときにpyenvでPython環境を作るとよい。
今回は、Ubuntuに入れる想定で進める。まず、pyenvをcloneする。

$ git clone git://github.com/yyuu/pyenv.git ~/.pyenv

そして、環境変数の設定。Ubuntuでなければ、.bash_profileとかに入れるのが良いでしょう。

$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc

ここで、一度ターミナルを開き直す。
pyenvで利用できるバージョンを確認する。

$ pyenv install -l
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4
  2.4.1
  2.4.2
  2.4.3
...

今回は2.7.9を入れる。

$ pyenv install 2.7.9
$ pyenv rehash

インストールしたPythonを利用するように設定する。

$ pyenv versions
* system (set by /home/taro/.pyenv/version)
  2.7.9
$ pyenv global 2.7.9
$ pyenv versions
  system
* 2.7.9 (set by /home/taro/.pyenv/version)

という感じで、環境の準備完了。
Python 2.7系であれば、~/.pyenv/versions/2.7.9/lib/python2.7/site-packages/sitecustomize.pyを作成して

import sys
sys.setdefaultencoding('utf-8')

を記述しておくとエンコーディング周りで悩まされないでよいかも。
あとは、使うモジュールをインストールしておく。(以下は個人的なメモに近いけど…)

pip install elasticsearch
pip install numpy
pip install scipy
pip install matplotlib
pip install pandas
pip install scikit-learn
pip install gensim

Wikipediaのデータをスクロールスキャンする

WikipediaをElasticsearchに取り込むの続き。
いろいろと試していくためには、Elasticsearchに取り込んだWikipediaのデータにアクセスできるようになる必要がある。Elasticsearchで全データにアクセスするためには、ScrollScanでアクセスする。
というわけで、今回はPythonで全データにアクセスしてみる。
事前にpip install ElasticsearchなどでPythonモジュールを利用可能な状況にしておく必要があるが、以下のような.pyを作成する。

# coding: utf-8
from optparse import OptionParser
import sys
from elasticsearch import Elasticsearch
import json
from elasticsearch.exceptions import NotFoundError
def main(argv=sys.argv):
    parser = OptionParser(prog="main.py")
    parser.add_option("--elasticsearch", dest="elasticsearch",
                  help="Elasticsearch", metavar="ES",
                  default="localhost:9200")
    parser.add_option("--index", dest="index",
                  help="Index", metavar="INDEX",
                  default="_all")
    parser.add_option("--source", dest="source",
                  help="Source", metavar="SOURCE",
                  default="{\"query\":{\"match_all\":{}}}")
    (options, args) = parser.parse_args()
    source = json.loads(options.source)
    es = Elasticsearch(hosts=options.elasticsearch)
    response = es.search(index=options.index,
                         scroll='1m',
                         search_type='scan',
                         size=100,
                         body=source)
    scroll_id = response['_scroll_id']
    counter = 0
    while (True):
        try:
            response = es.scroll(scroll_id=scroll_id, scroll='1m')
            if len(response['hits']['hits']) == 0:
                break
            for hit in response['hits']['hits']:
                counter = counter + 1
                if "_source" in hit:
                    if "title" in hit['_source']:
                        print hit['_source']['title']
        except NotFoundError:
            print u"Finished ({0}) documents.".format(counter)
            break
        except:
            print u"Unexpected error: {0}".format(sys.exc_info()[0])
            break
    return 0
if __name__ == "__main__":
    sys.exit(main())

上記の例ではスクロールで_sourceのtitleデータを出力している。
NotFoundErrorのエラーで止めるのも微妙だけど、何か良い方法があるのかしら…。
実行は

$ python title.py --index jawiki-pages-articles

という感じで実行すれば、タイトルが出力されていく。
というわけで、そのあたりのコードをいじればいろいろできる感じかな。

/sbin/mount.vboxsf: mounting failed with the error

Vagrantでvbguestを使って、VirtualBoxのアドオンを更新していて、VagrantとVirutalBoxを更新したら以下のように怒られるようになった…。

Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:
mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant
The error output from the last command was:
/sbin/mount.vboxsf: mounting failed with the error: No such device

こんなときは、~/.vagrant.d/Vagrantfileを以下のように更新して、auto_updateを無効にする必要があるらしい。

Vagrant.configure("2") do |config|
  config.vbguest.auto_update = false
end

として、vagrant upしたら解決した。