Pythonのスクリプトを起動するときのオプションを指定する方法

2016-01-26
このエントリーをはてなブックマークに追加

以前は optparse 使ってましたけど、廃止予定だそうです。で、今は argparse 使います。2.7以降はargparseが標準で入ってるそうなので、今時はもうoptparseも使えはするけどargparse一択でしょう。

from argparse import ArgumentParser

if __name__ == "__main__":

    _parser = ArgumentParser()

    _parser.add_argument(
        '-s',
        '--string',
        type=str,
        dest='string',
        required=True,
        help='String Value'
    )

    _parser.add_argument(
        '-n',
        '--number',
        type=int,
        dest='number',
        required=True,
        help='Number Value'
    )

    _args = _parser.parse_args()

    print(_args.string, _args.number)

なんのオプションも指定しないで起動すると

$ python sample.py
usage: sample.py [-h] -s STRING -n NUMBER
sample.py: error: argument -s/–string is required

「-sで文字列、-nで値を指定してね。-sは必須オプションだからエラーだよ。」
ってメッセージがでます。親切です。

$ python sample.py -s S -n N
usage: sample.py [-h] -s STRING -n NUMBER
sample.py: error: argument -n/–number: invalid int value: ‘N’

-n に文字列を与えてもエラーが出ます。ちゃんと型チェックしてくれます。親切です。

$ python sample.py -s Hello -n 123
(‘Hello’, 123)

便利。

電気自動車に乗り換えて1年経った

2015-12-31
このエントリーをはてなブックマークに追加

日産のLEAFという電気自動車に乗り換えて1年経ったのでどんなもんかブログに書いておきましょう。電気自動車に興味のある方、購入を検討している方の参考になれば幸いです。

なお、このエントリは電気自動車を否定するものではありません。むしろ応援しています。電気自動車はいいぞ。

まず気になるのは走行距離でしょうか。たしかカタログ上の走行距離は100%充電で220kmくらいだったと思います。まあ当然そんなに走りません。

thumb_IMG_6992_1024

「今の充電量だったらxxkm走りますよ」、っていうのがコンソールに表示されるのです。写真の右側にある「159」という数字がこの時の走行可能距離です。100%充電で160kmいくかいかないかくらい。カタログ値の2/3くらいでしょうか。まあガソリンエンジンの燃費もそれくらいだから妥当でしょう。

thumb_IMG_6993_1024

ちなみに、エアコンをオンにすると10%ちょっと走行可能距離が減ります。エアコンがどれだけ電気を消費するのか実感します。

この走行可能距離は電費(燃費)の悪い乗り方をしていると下がります。ディーラーさん曰く、「最近の消費電力と走行距離から算出」しているそうなのですが、その「最近」がどれくらいの期間なのかは不明とのことでした。

なお、高速道路を走るとビビるくらい電気を消費します。1km走るごとに1%減ってるんじゃないかと思うくらい。ちょっとおおげさですけど、そう思っちゃうくらい減ります。

回生ブレーキシステムで充電しているらしいですけど、多少減りにくくなってる程度でしょう。正直充電量が増えたところは見たことありません。ソーラーパネルも搭載していますが、同様です。真夏に外に駐車してても1%も増えません。

購入時に無料で自宅に充電設備を設置してくれたのですが、自宅で充電することはほぼありません。1年間で2〜3回しか自宅で充電してません。近所のイオンモールに無料の充電器があるので概ねそこで充電しています。イオンモールで買い物してる間に充電が終わるので非常にお世話になっています。あとは日産のディーラーさんのところでも充電できます。ショールームの中で飲み物出してもらってのんびり待てます。

自宅で充電しても300円くらいで満タンになるそうです。

10009312_809120102457573_4328280958089988453_n

乗り心地はガソリンエンジン車とはまったく違います。圧倒的に静かです。振動も少なく、排気ガス臭くもありません。静かで振動が無いというのがこんなに快適だとは思いませんでした。

静かなのに、びっくりするくらいパワフルです。4,000ccエンジン相当のトルクだそうです。たしかにecoモードをオフにして静止状態からベタ踏みするとホイールスピンします。マーチサイズのボディで暴れるので面白いです。

静かでパワフルで無料で充電できていいコトづくめですが、まあ走行可能距離が短くて急速充電器でも充電に30分かかるのは正直きつい。

  • 近所に無料の充電設備がある
  • あんまり遠出しない
  • あんまり毎日距離走らない

っていう人だったらいいですけど、そうでもなければ現時点で電気自動車を選択するのは相当の覚悟がいると思います。

正直、細かいこと気にする人はやめておいた方がいいと思います。100キロちょっと走ったら充電で30分足止めになっても「まあそういうもんだよね」って休憩兼ねて停まれるくらいがいいでしょう。そんな感じでゆるく乗ってあげるといい車だと思います。

PythonでWord2Vecを使って類義語抽出

2015-11-12
このエントリーをはてなブックマークに追加

今更のWord2Vec。

分かち書きしたテキストファイルを読み込ませて学習データを作って保存。保存した学習データを読み込んで類義語を出力するところまで。毎回学習してから類義語抽出っていう訳にもいかないから学習データの保存は必要ですよね、っていうサンプル。

Word2Vecはおもしろいし、いろいろ触ってるので今後もブログに書いていこう。このエントリも下書きのまま1年くらい放置されててちゃんとブログ書かねばと反省中。。。

from gensim.models import word2vec

def main():

    data = word2vec.Text8Corpus("/path/to/file")
    model = word2vec.Word2Vec(data, size=250, window=5, min_count=2, workers=4)
    model.save("./teacher.bin")

    model = word2vec.Word2Vec.load("./teacher.bin")
    for _w in model.most_similar(positive=['ジャケット']):
        print(_w)

if __name__ == "__main__":
    main()

elasticsearchでcopy_toを使ってみる

2015-11-01
このエントリーをはてなブックマークに追加

SolrでいうところのCopyField。全文検索で複数フィールドを束ねて検索したい時には便利です。フィールドごとにスコアブーストしたいとなると別の方法を取るしかないかな。

{
    "title": {
        "type": "string",
        "copy_to": "text"
    },
    "description": {
        "type": "string",
        "copy_to": "text"
    },
    "text": {
        "type": "string",
        "index": "analyzed",
        "analyzer": "text_ja"
    }
}

これでtextフィールドにクエリ投げればtitleかdescriptionのどちらかに適合するドキュメントが返ってくる。データ元になるtitleとかdescriptionはindexをfalseにしておけばインデックスサイズも小さくなる。elasticsearch1.7.3で動きました。

Pythonでscikit-learnを使ってランダムフォレストの分類器を書いて、学習結果を保存してみた

2015-10-01
このエントリーをはてなブックマークに追加

分類するだけじゃなくて学習したデータを保存もしています。学習データがあったらデータを読み込んで利用します。

import os

from sklearn.ensemble import RandomForestClassifier
from sklearn.externals import joblib


class RandomForest(object):
    def __init__(self):
        if os.path.exists('./.supervised/data.bin'):
            self._m = joblib.load('./.supervised/data.bin')

        else:
            _training_data = [
                [2, 0, 0, 0],
                [0, 2, 0, 0],
                [0, 0, 2, 0],
                [0, 0, 0, 2],
            ]
            _training_label = [1, 2, 3, 4]

            self._m = RandomForestClassifier()
            self._m.fit(_training_data, _training_label)

            joblib.dump(self._m, './.supervised/data.bin')

    def start(self):
        _test_data = [
            [0, 4, 0, 0],
            [0, 0, 0, 2]
        ]
        _out = self._m.predict(_test_data)

        print(_out)

if __name__ == "__main__":
    _obj = RandomForest()
    _obj.start()

結果出力
[2 4]

Pythonでnumpyを使って値を正規化する

2015-09-24
このエントリーをはてなブックマークに追加
$ import numpy as np
$ _array = np.array([1, 2, 3])
$ _n_array = _array / np.amax(_array) * 1
$ print(_n_array)

[ 0.33333333  0.66666667  1.        ]

0から1の間に収めます。
こんなに簡単にできちゃうって素晴らしい。

Tags:

「人間のためのHTTP」Requestsでオレオレ証明書かつベーシック認証を突破する

2015-08-14
このエントリーをはてなブックマークに追加

Requests は「人間のためのHTTP」という謳い文句のhttpライブラリ。確かにとても便利。Python3であれば http.client 使えばいいんですけど、ついついRequestsを使ってしまう。

_response = requests.get(
     'https://TARGET_URL',
     auth=('user_name', 'passwd'),
     verify=False
)

auth=の部分がベーシック認証、verify=Falseがオレオレ証明書の許容。これだけです。簡単。

まあ、

InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised.

ってWarning吐きまくってるんですけどね。

Requestsが動くならPython2でも3でも動くはずです。

Pythonでジョブキューしてみる

2015-08-02
このエントリーをはてなブックマークに追加

PythonでジョブキューするといえばやっぱりCeleryがスタンダードなんだろうか。RQというシンプルなジョブキューライブラリもあるんですけど、今回はCeleryを動かしてみる。

インストールは簡単。

pip install Celery

バックエンドはRabbitMQかRedisで使うのが良さそうです。手元の環境にRedisが入っていたのでそのままRedisを使ってみます。

from celery import Celery

app = Celery('tasks', broker='redis://localhost:6379/0')

@app.task
def task(message):
    return "Hello {0}".format(message)

上記をjob.pyとして保存しておきます。で、このjob.pyをワーカーとして起動。このワーカーがデキューしてくれます。

$ celery -A job worker --loglevel=info

いろいろログを出力して起動してくれます。ワーカーの起動はいろいろオプションがあります。デーモンとして動かしたり並列で大量に立ち上げたり。非常に便利。

で、エンキューはもうインタラクティブシェルでもできます。

$ python
Python 3.4.2 (default, Oct 16 2014, 01:53:40)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from job import task
>>> task.delay("World.")

エンキューもこれだけ。
で、エンキューするとさっき立ち上げたワーカーの方でデキューしてジョブを捌いてくれます。

succeeded in 0.0014186919997882796s: 'Hello World.'

こんな簡単にジョブキューの仕組みが作れるなんて。

Pythonでscikit-learnを使ってNon-negative Matrix Factorization

2015-06-16
このエントリーをはてなブックマークに追加

Non-negative Matrix Factorization(NMFでググるといろいろ出てきます)、非負値行列因子分解です。

集合知プログラミング でも紹介されている特徴を抽出する方法です。推薦エンジンとかにも使われているそうです。

書籍では自前で実装されてますがscikit-learnに同じものがあるので便利に利用させていただきます。

import numpy as np
from sklearn.decomposition import ProjectedGradientNMF


def main():

    X = np.array([
        [1, 0, 0],
        [1, 1, 0],
        [0, 1, 0],
        [0, 1, 0],
        [0, 0, 1],
    ])

    model = ProjectedGradientNMF(init='nndsvdar')
    _res = model.fit_transform(X)
    print(_res)

if __name__ == "__main__":
    main()

実行するとこんな感じで出力されます。

$ python nfm.py
[[ -0.00000000e+00   9.15822497e-01  -0.00000000e+00]
 [  6.85467400e-01   9.15816894e-01  -0.00000000e+00]
 [  6.85636205e-01   2.24117374e-09  -0.00000000e+00]
 [  6.85636205e-01   2.24116561e-09  -0.00000000e+00]
 [ -0.00000000e+00  -0.00000000e+00   9.99944486e-01]]

素晴らしい。

サンプルデータをちゃんと投入すればもうちょっとまともな値がでてきます。パラメータの与え方はちゃんと検証して調整しないとです。

動かした環境はPython3.4で、

$ pip freeze
numpy==1.9.2
scikit-learn==0.16.1
scipy==0.15.1

Python便利。

Tornadoをデバッグモード、オートリロードで稼働させる

2015-05-24
このエントリーをはてなブックマークに追加

tornado

Wikipediaにも「Pythonで書かれたスケーラブルでノンブロッキングなWebサーバ、Webフレームワーク」と書かれたTornadoのデバッグモードをオンにしてファイルの変更を検知してリロードしてくれるようにするやり方。

import tornado.ioloop
import tornado.web


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

application = tornado.web.Application(
    [
        (r"/", MainHandler),
    ],
    debug=True
)

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

ほとんどサンプルのまんまです。

debug=True だけでオートリロードもしてくれます。簡単。これだとデバッグモード切り替えで都度コードの書き換えが必要になるのでコマンドライン引数で振る舞い変えるようにしたほうがいいでしょうね。

TornadoはPython3.2以降にも対応してるので安心です。