RaspberryPi3にカメラをつないでみた

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

RaspberryPi3を買ってずっと放置してたんだけど、久々に起動してみた。ついでにカメラモジュールも買いました。

つなぎ方とかカメラからのキャプチャ画像の保存とか、そういうのは解説サイトがいっぱいあるので割愛します。

カメラモジュールは2,000円もしないものなんですけどすごく手軽で2,592×1,944のきれいな写真が撮れました。これは楽しい。

テレビの画面をRaspberryPi3で撮影したらカメラ目線の右京さんが。これはブログ用にリサイズしたものですけど、元画像は2.5MBのきれいな画像でした。

ケースとか用意してないからいろいろとむき出しで、撮影するときはカメラを手で持ってました。これはなんとかしないとなあ。

いろいろと遊んでみたいことがあってRaspberryPi3とかカメラモジュール買ったんですけど、すっかり放置してしまいました。ちゃんと遊ばないといけませんね。

PythonでジョブをQueueにいれつつMulti Processでさばいていく方法

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

先日書いた「PythonでたまったQueueをMulti Threadでさばいていく方法」のMulti Process版

ProcessPoolExecutorではプロセス間で通信できないようだったのでmultiprocessingを使って書きました

import time
from datetime import datetime
from multiprocessing import Process, JoinableQueue


def worker(queue):
    while True:
        _job = queue.get()
        if _job is None:
            queue.task_done()
            break

        print(datetime.now())
        print(_job)
        queue.task_done()
        time.sleep(1)

def main():
    _process = []
    _queue = JoinableQueue()
    _docs = ["a", "b", "c", "d", "e", "f", "g"]
    for _i in range(2):
        _p = Process(target=worker, args=(_queue,))
        _p.start()
        _process.append(_p)

    for _d in _docs:
        _queue.put(_d)

    for _i in range(2):
        _queue.put(None)

    _queue.join()

if __name__ == "__main__":
    main()

思っていたよりマルチスレッド版とは違いが出ました

ジョブの投入が終わってからNoneを入れてるのは、「Noneっていうジョブが来たら終了してね」っていうサインを送ったっていう意図です、Queueが空になったくらいじゃ返ってきてくれません

2017-12-20 09:12:35.840879
a
2017-12-20 09:12:35.841184
b
2017-12-20 09:12:36.842196
c
2017-12-20 09:12:36.842427
d
2017-12-20 09:12:37.843443
e
2017-12-20 09:12:37.843636
f
2017-12-20 09:12:38.844696
g

PythonでたまったQueueをMulti Threadでさばいていく方法

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

Queueにはいったジョブを指定したThread数で順番にさばいていきたいよ、っていうときに使います
あんまり大量にQueueにいれるとメモリからあふれて落ちるんだろうな

import threading
import queue
import time
from datetime import datetime

QUEUE = queue.Queue()


def worker():
    while True:
        _docs = QUEUE.get()
        job_worker(_docs)
        QUEUE.task_done()

def job_worker(docs):
    print(datetime.now())
    print(docs)
    time.sleep(1)
    return None

def main():

    _threads = []
    for _i in range(2):
        _t = threading.Thread(target=worker)
        _t.daemon = True
        _t.start()
        _threads.append(_t)

    _docs = ["a", "b", "c", "d", "e", "f", "g"]
    for _doc in _docs:
        QUEUE.put(_doc)

    QUEUE.join()

if __name__ == "__main__":
    main()

実行するとこんな出力になります、threadがふたつなのでふたつずつ処理されてますね

2017-12-17 17:55:49.769058
a
2017-12-17 17:55:49.769201
b
2017-12-17 17:55:50.770286
c
2017-12-17 17:55:50.770461
d
2017-12-17 17:55:51.771527
e
2017-12-17 17:55:51.771687
f
2017-12-17 17:55:52.772768
g

Python3.6で書いたサンプルです

PythonのSciPyで値の標準化

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

「平均が0、分散が1」ってやつです。
平均引いて標準偏差で割ればいいので大した計算量ではないのですが、SciPyを使うと関数一発。便利すぎる。

import numpy as np
from scipy.stats import zscore


def main():
    _array = np.array([1, 2, 3, 4, 5])
    _n = zscore(_array)

    print(_n)
    print(np.mean(_n))
    print(np.var(_n))


if __name__ == "__main__":
    main()
$ python standardization.py
[-1.41421356 -0.70710678  0.          0.70710678  1.41421356]
0.0
1.0

PythonでTwitterのStreaming APIを受信する

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

全Tweetの1%と言われるPublic streamsのsampleを受信してみます。

OAuthやらStreamやら、どう実装するかなーと調べてみるとRequests: 人間のためのHTTP があれば十分なことがわかったし、親切なサンプルコードも書かれてたのであっさり実装できてしまった。

OAuth 1 Authentication

Streaming Requests

import json

import requests
from requests_oauthlib import OAuth1


def main():
    _auth = OAuth1(
        API_KEY,
        API_SECRET,
        ACCESS_TOKEN,
        ACCESS_SECRET
    )

    _stream = requests.get(
        "https://stream.twitter.com/1.1/statuses/sample.json?language=ja",
        auth=_auth,
        stream=True,
    )

    for _line in _stream.iter_lines():

        _doc = json.loads(_line.decode("utf-8"))
        print(json.dumps(_doc, ensure_ascii=False, indent=2))


if __name__ == '__main__':
    main()

日本語のツイートだけ取得したかったのでlanguage=jaを追加しています。Requests便利すぎ。

CentOS7にPython3.6.0をソースからインストールした

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

久々に新しくec2に私用でインスタンスたてたのでこれまでずっとAmazon Linux使ってたけどCentOS7にしてみた。ついでに先日リリースされたPython3.6.0をインストールしてみました。

cd /usr/local/src/
sudo wget https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tgz
sudo tar zxfv Python-3.6.0.tgz
sudo chown -R centos. Python-3.6.0
cd Python-3.6.0
./configure --enable-shared --enable-optimizations
sudo make
sudo make install

「chownはなんのため?」と思われるでしょうが、tarボールを解凍したらパーミッションが501.gamesになっていて触れなかったのでcentosユーザーに変えました。なんでこうなったのかは知らんのですが、同じホストでPython3.5.2のソースコードをDLして試したらパーミッションはcentos.centosだったので、tarした環境の問題なんじゃないかと。

makeとmake installで30分以上待ちました。テストですごい時間かかってた。t2.microだったからなんだろうけど、3.5のころはここまで時間かかんなかった気がするんだよなぁ。

で、このまま起動しようとするとライブラリがみえないっていって怒られるので

sudo vi /etc/ld.so.conf

「/usr/local/lib」を追記

sudo /sbin/ldconfig
$ /usr/local/bin/python3
Python 3.6.0 (default, Dec 31 2016, 00:18:38)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.

無事起動しました。

デフォルトのpythonを置き換えることはしなくて、併存です。どうせvenv使うんだし、それで十分です。最近はpyenv使う人が多いのかもしれないけど、標準でインストールされるvenvで十分なのであれこれインストールしたりはしません。

最近GCPが話題になっていて、AWSよりずっと安いっていう話も聞くんですけど、別にAWSにそんなに不満もないのでまだしばらくはAWS使おうかなと。

「Pokemon」で検索しても「Pokémon」がヒットするようにしよう

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

ふと気がつくと前回ブログ書いたのが5か月前という有様。安心してください、生きてますよ。

éとか、英字の上につくダッシュみたいな記号、アクセント記号って呼び方してましたけどダイアクリティカルマークっていうのが正しいんですね。

日本語の場合あんまり気にしないけど、海外のブランド名にもダイアクリティカルマーク付いてるの多いですよね。

例えばelasticsearchの公式にサンプルとして置いてある英語のアナライザーだと「Pokémon」は「Pokemon」で検索してもヒットしません。Solrも同様です。

まあ同義語展開しておけば済むんですけど、大量にある商品名とかブランド名の同義語をメンテするのとか気が遠くなるのでそれは避けたい。

で、elasticsearchにはちゃんとフィルターが用意されていて、前述のアナライザーに追記するだけでOK。

"filter": [
  "english_possessive_stemmer",
  "lowercase",
  "english_stop",
  "english_keywords",
  "english_stemmer",
  "asciifolding"
]

順番は最後で平気なはず。たぶん。
これでちゃんとヒットするようになりましたとさ。

当たり前ですが、Solrにもちゃんと同様のフィルターが用意されてます。ありがたい。

ASCII文字の置換してるだけみたいだけど、他の文字列に影響与えないか要検証。怖い怖い。

Pythonでitertoolsを使ってパラメータの総当り

2016-06-28
このエントリーをはてなブックマークに追加
import itertools

_x = ['0', '1', '2']
_y = ['a', 'b', 'c']

for _i, _j in itertools.product(_x, _y):
	print(_i, _j)

パラメータAには複数のパターン、パラメータBにも複数のパターン。それらの総当りパターンを出力したいっていう時に便利。

0 a
0 b
0 c
1 a
1 b
1 c
2 a
2 b
2 c
Tags:

scikit-learnのTfidfVectorizerで単語ごとのスコアを取得する

2016-06-17
このエントリーをはてなブックマークに追加
from sklearn.feature_extraction.text import TfidfVectorizer


def main():
    _docs = [
        'A friend to all is a friend to none.',
        'One good turn deserves another.',
        'He who runs after two hares will catch neither.',
        'It’s no use crying over spilt milk.',
        'Time and tide wait for no man.',
    ]

    _v = TfidfVectorizer(analyzer=text_split)
    _score =_v.fit_transform(_docs)

    print(_score.toarray())
    print(_v.get_feature_names())

def text_split(val):
    return val.split(' ')

if __name__ == '__main__':
    main()

$ python tf.py
[[ 0.2773501   0.          0.          0.          0.          0.2773501
   0.          0.2773501   0.          0.          0.          0.          0.
   0.          0.5547002   0.          0.          0.2773501   0.          0.
   0.          0.          0.2773501   0.          0.          0.          0.
   0.5547002   0.          0.          0.          0.          0.          0.        ]
 [ 0.          0.          0.          0.4472136   0.          0.          0.
   0.          0.          0.4472136   0.          0.          0.4472136
   0.          0.          0.4472136   0.          0.          0.          0.
   0.          0.          0.          0.          0.          0.          0.
   0.          0.4472136   0.          0.          0.          0.          0.        ]
 [ 0.          0.33333333  0.          0.          0.          0.
   0.33333333  0.          0.          0.          0.33333333  0.          0.
   0.          0.          0.          0.33333333  0.          0.          0.
   0.33333333  0.          0.          0.          0.33333333  0.          0.
   0.          0.          0.33333333  0.          0.          0.33333333
   0.33333333]
 [ 0.          0.          0.38775666  0.          0.          0.          0.
   0.          0.          0.          0.          0.38775666  0.          0.
   0.          0.          0.          0.          0.          0.38775666
   0.          0.31283963  0.          0.38775666  0.          0.38775666
   0.          0.          0.          0.          0.38775666  0.          0.
   0.        ]
 [ 0.          0.          0.          0.          0.38775666  0.          0.
   0.          0.38775666  0.          0.          0.          0.
   0.38775666  0.          0.          0.          0.          0.38775666
   0.          0.          0.31283963  0.          0.          0.          0.
   0.38775666  0.          0.          0.          0.          0.38775666
   0.          0.        ]]

[‘A’, ‘He’, ‘It’s’, ‘One’, ‘Time’, ‘a’, ‘after’, ‘all’, ‘and’, ‘another.’, ‘catch’, ‘crying’, ‘deserves’, ‘for’, ‘friend’, ‘good’, ‘hares’, ‘is’, ‘man.’, ‘milk.’, ‘neither.’, ‘no’, ‘none.’, ‘over’, ‘runs’, ‘spilt’, ‘tide’, ‘to’, ‘turn’, ‘two’, ‘use’, ‘wait’, ‘who’, ‘will’]

Pythonで標準偏差と偏差値を求めてみる

2016-04-04
このエントリーをはてなブックマークに追加
import numpy as np


def main():

    _v = np.array([35, 40, 45, 50, 100])

    _avg = np.average(_v)
    _std = np.std(_v)
    print(_avg, _std)

    _std_score = (((_v - _avg) * 10) / _std) + 50
    print(_std_score)

if __name__ == "__main__":

    # 偏差値@Wikipedia
    main()
54.0 23.5372045919
[ 41.92767352  44.05196996  46.1762664   48.30056285  69.54352728]

なんで標準偏差は関数があるのに偏差値はないんだろう。
あと、なんで偏差値は50を足すんだろう。0を中央にしてもいいと思うんだ。
学生向けに使うことが多い値だからマイナスというネガティブな値にマッピングされるされるのを避けたのかな。