PythonでunixタイムスタンプをDatetimeオブジェクトに変換する

2015-05-22
このエントリーをはてなブックマークに追加
from datetime import datetime
print(datetime.fromtimestamp(1432049226))

これだけ。

MacでローカルのMySQL5.6にPython3.4で接続する際にlibmysqlclient.18.dylibが無いとエラーが出た

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

mysqlclient使って

import MySQLdb

しただけで

Library not loaded: libmysqlclient.18.dylib

ってエラー吐いたんだけどlibmysqlclient.18.dylibは

/usr/local/mysql-5.6.16-osx10.7-x86_64/lib/libmysqlclient.18.dylib

にありました。なので、

sudo ln -s /usr/local/mysql-5.6.16-osx10.7-x86_64/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib

シンボリックリンク張って無事に繋がるようになりました。

久々にローカルで作業するとつまんないことで躓く。。。

iOS Developer Programを更新した

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

ios-developer-program

まあライセンスを更新しただけなんですけど、円安と消費税率アップのお陰で去年の1.5倍位になっててビビった。去年は8,400円だったろうに。。。

もう何年も個人でアプリ出せてないし、今年は更新するのやめておこうかなーと思ってたんですけど、出しておきたいアプリが一本あって、コアになる部分は書き上がってるので勿体無いなぁと。

ということで、今年こそ数年ぶりのアプリをリリースします!

これ毎年言ってる気がする。。。

ハルロックを読んで電子工作に興味津々になった

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

もうタイトルのまんまなんですけど、特に2巻と3巻(まだ3巻までしか出てません)。猫ツイッターとかすごい面白そう。

や っ て み た い つ く っ て み た い 。

なに作るか全然プランはないし電子工作なんてやったことないから最初っから難しいのなんて作れないだろう。

まあ、最初は平日の朝、家から一定の距離離れたら青葉がメンションくれるツールでも作るかな。(それ工作しなくてもいいよねとか聞こえない。)

aoba

Python3で並列処理してみた

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

Python3っていうか、3.3以降です。

from concurrent.futures import ProcessPoolExecutor
import time


def work(job):
	time.sleep(job)
	print(job)

def main():
	_jobs = [5, 1, 2]
	_e = ProcessPoolExecutor(max_workers=2)
	for _j in _jobs:
		_e.submit(work, _j)

if __name__ == '__main__':
	main()

簡単なサンプルなんですけど、ワーカー2つ作って並列にworkというメソッドを実行してくれます。
実行すると

$ python sample.py
1
2
5

こんな感じに出力されます。5,1,2って順番で処理投げ込んでるのに1,2,5の順番で終わってます。

Pythonでmultiprocessingを使って並列処理 で書いたサンプルも簡単でしたけど、ProcessPoolExecutor使うともっと簡単です。

ProcessPoolExecutor使って4並列で走るツール書いて実行したらこんな感じになりました。
ProcessPoolExecutor
これはいい。

Python3でGZipされたログファイルを読み込む

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

ApachetとかNginxのログは圧縮して保存してケースが多いんですけど、それを読むときにいちいち解凍してるのもめんどくさいのでgzipのまんま読んでみるサンプル。

import gzip


def main():

    _f = gzip.open('/path/to/logfile.gz', 'rb')
    _line = _f.readline()

    while _line:
        _text = _line.decode('utf-8')
        print(_text)
        _line = _f.readline()

    _f.close()


if __name__ = '__main__':
    main()

ファイルを読み込むだけだと文字列はなくてバイト配列なのでそれをデコードしてます。テキストファイルを読み込む時となんら変わりはないのですが、デコードが必要なのでそれを忘れるとあれ?ってなってしまうので要注意。

最初.split(‘\t’)ができなくてあれ?ってなりました。

Python3.4で動かしたコードですけど、2.7でも動くはずです。

2015.01.28 追記

    _f = gzip.open('/path/to/logfile.gz', 'rt')
    _line = _f.readline()

    while _line:
        print(_line)
        _line = _f.readline()

ファイル開くときにテキストモードで開けばもっとスマートです。@yosida95 に教えてもらいました。感謝!

最新のFFmpegをソースからインストールする

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

スマフォで撮った動画をアップしてブラウザで表示させたい!っていう要望があったとしたら今どきならmpeg4とoggに変換しておいてvideoタグで表示させてやるのが手っ取り早いかと。「YouTubeAPI叩いてアップすりゃいいじゃん」とか聞こえない。

動画を変換するならFFmpegが便利なんですけど、yumでインストールしようとすると0.6という非常に古いバージョンをインストールしようとします(’14.11.27現在)ので、ここはソースからインストールしようと。

sudo rpm -Uhv http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm

sudo yum install yasm-devel yasm
sudo yum install libogg libogg-devel
sudo yum install faac faac-devel
sudo yum install xvidcore xvidcore-devel zlib-devel zlib
sudo yum install libvorbis libvorbis-devel
sudo yum install libtheora libtheora-devel

git clone git://git.videolan.org/x264.git

cd x264
sudo ./configure –enable-shared
sudo make
sudo make install

sudo git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
sudo ./configure –enable-gpl –enable-version3 –enable-nonfree –enable-shared –enable-libfaac –enable-libx264 –enable-libtheora –enable-libvorbis
sudo make
sudo make install

vi /etc/ld.so.conf
/usr/local/lib

sudo ldconfig

$ ffmpeg -version
ffmpeg version N-67254-g0c42f47 Copyright (c) 2000-2014 the FFmpeg developers
built on Oct 30 2014 06:36:01 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-4)

ライブラリ、コーデックの類は依存関係がめんどくさいのでyumで。x264だけyumで入るバージョンが古かったのでgitから落としてきました。

スマートフォンから動画をアップしてブラウザで閲覧、っていうのであればmp4とoggがあれば足りるだろうということで最低限しかいれてません。これで足りてる、はず。IE8以下は知らない。

WebMってどうなったんだろ。

12/04追記、configureに–enable-libtheora –enable-libvorbis が足りなかったので追加。

Tags:

Pythonでコサイン類似度を使ってテキストの類似度を計算する

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

テキストの類似度って言っても出現する単語の回数比較でしか無いので文意解釈はしてないです。あくまで「出現した文字の一致度」ですね。

Word2Vecとかを使ってテキストを拡張してあげれば少しは文意を加味した類似度といえるのかもです。

from scipy.spatial.distance import cosine
import unittest


class SentenceSimilarity(object):

    def __init__(self):
        self._A = None
        self._B = None

    @property
    def A(self):
        return self._A

    @property
    def B(self):
        return self._B

    @A.setter
    def A(self, v):
        self._A = [i for i in v.replace(' ', ',').split(',') if len(i) > 0]

    @B.setter
    def B(self, v):
        self._B = [i for i in v.replace(' ', ',').split(',') if len(i) > 0]

    def distance(self):

        if self._A is None or self._B is None:
            return False

        if len(self._A) < 2 or len(self._B) < 2:
            return False

        return self._distance()

    def _distance(self):

        _words = []
        _words.extend(self._A)
        _words.extend(self._B)

        _words = list(set(_words))
        _words.sort()

        _listA = [self._A.count(_w) for _w in _words]
        _listB = [self._B.count(_w) for _w in _words]

        try:
            return 1 - cosine(_listA, _listB)
        except:
            return False


class TestSentenceSimilarity(unittest.TestCase):

    def setUp(self):
        pass

    def test_0(self):

        _sentence = SentenceSimilarity()
        _sentence.A = '今期 業績 予想 未定 期限切れ 肉 問題 販売減'
        _sentence.B = '都市 対抗 野球 西濃運輸 初優勝 佐伯 富士 重工'
        self.assertGreater(_sentence.distance(), 0.0)


    def test_1(self):

        _sentence = SentenceSimilarity()
        _sentence.A = '今期 業績 予想 未定 期限切れ 肉 問題 販売減'

        self.assertEqual(_sentence.distance(), False)

    def test_2(self):

        _sentence = SentenceSimilarity()
        _sentence.A = '今期'
        _sentence.B = '都市'

        self.assertEqual(_sentence.distance(), False)

    def test_3(self):

        _sentence = SentenceSimilarity()
        _sentence.A = '今期,業績,予想,未定'
        _sentence.B = '都市,業績,予想,未定'

        _sentence.B = '業績 対抗 野球 西濃運輸 初優勝'

        self.assertGreater(_sentence.distance(), 0.0)

if __name__ == '__main__':
    unittest.main()

使い方はテストをみていただければご理解いただけるかと。

コサイン類似度の計算なんて

return 1 - cosine(_listA, _listB)

の部分でしかやってなくて、残りは全部下ごしらえです。

_sentence = SentenceSimilarity()
_sentence.A = ‘今期 業績 予想 未定 期限切れ 肉 問題 販売減’
_sentence.B = ‘都市 対抗 野球 西濃運輸 初優勝 佐伯 富士 重工’

インスタンス作って、AとB(命名が安直ですいません)にカンマ切り、もしくはスペース切りの文字列を指定します。なので事前に分かち書きをしておく必要があります。

まあ文章を渡してメソッドの中で分かち書きしてもいいんですけどね。手元にあったのが分かち書き済みだったので今回はそのまま使いました。

_sentence.distance()

で、類似度を求めます。類似度を求める前に_Aと_Bの和集合を作って、和集合の単語リストにある単語が_Aと_Bそれぞれで幾つずつ出現するかを求めます。

上記例だと和集合は[今期,業績,予想,未定,期限切れ,肉,問題,販売減,都市,対抗,野球,西濃運輸,初優勝,佐伯,富士,重工]となり、
_listAは[1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0]
_listBは[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1]
になるはずです。で、これらをベクトルにしてコサイン類似度を求めます。今は0と1だけですが複数回出現する単語があれば当然2以上の値も出てきます。

コサイン類似度は0から1の値で返ってきて、値が大きければ大きいほど類似しています。上記サンプルだと0が返ってくるはずです。ぜんぜん違う、ってことですね。

アイテムベースのレコメンドに使えると思います。サービスとして提供するレコメンドエンジンであればこんな単純な計算じゃないでしょうね。

Python 3.4.2, scipy 0.14.0 で書きました。

scikit-learnを使ってMovieLensの映画評価データをクラスタリングしてみた

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

使ったのはMovieLens 100k
「100,000 ratings from 1000 users on 1700 movies.」
だそうです。

from sklearn.cluster import KMeans


def main():

    _items = []
    _f = open('./rating.csv' )
    _lines = _f.readlines()

    for _line in _lines:
        _items.append(_line.split(','))

    _f.close()

    km = KMeans(init='k-means++')
    km.fit(_items)

    print(km.labels_)


if __name__ == '__main__':
    main()

すげえ簡単。。。

CSVは1行が1人分で全部の映画のレーティング情報(0が観てない、評価は1から5)が入っています。1000ユーザーが1700本の映画を評価(未鑑賞含む)してます。

だいたいこんな感じ。

5,3,4,3,3,5,4,1,5,3,2,5,5,5,5,5,3,4,,,,,,,,
4,0,0,0,0,0,0,0,0,2,0,0,4,4,0,0,0,0,,,,,,,,

得られる結果は

[0 1 4 4 3 2 6 3 4 6 3 7 6 2 1 5 1 6 4 7 1 3 3 7,,,,,,,

インデックス2番のユーザーさんと3番のユーザーさんは好きな映画が似る傾向にありそうですね。

Python 3.4.2、scikit-learn 0.15.2 で試しました。

scikit-learnを使ってテキスト文書をクラスタリングしてみた

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

Clustering text documents using k-means (K平均法を使ってテキスト文書をクラスタリングする)というそのまんまのサンプルがあったので写経して最低限だけ削りだしてみた。

K平均法とかTF-IDFとか潜在意味解析の説明は割愛。

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.decomposition import TruncatedSVD
from sklearn.preprocessing import Normalizer


def main():

    _items = [
        'わたし まけ まし た わ',
        'わたし まけ まし た わ',
        'わたし まけ まし た わ',
        'わたし まけ まし た わ',
        'となり の きゃく は よく かき くう きゃく だ',
        'にわ には にわ なかにわ には にわ にわとり が いる',
        'バカ と テスト と 召喚獣',
        '俺 の 妹 が こんな に 可愛い わけ が ない'
    ]

    vectorizer = TfidfVectorizer(
        use_idf=True
    )
    X = vectorizer.fit_transform(_items)

    lsa = TruncatedSVD(10)
    X = lsa.fit_transform(X)
    X = Normalizer(copy=False).fit_transform(X)

    km = KMeans(
        init='k-means++',
    )
    km.fit(X)

    print(km.labels_)


if __name__ == '__main__':
    main()

テキストは分かち書きされてる状態(空白区切りになってます)でドキュメント単位でリストにいれておく。これを元データとしてTfidfVectorizerに突っ込みます。ここでドキュメントがベクトル化されます。

で、潜在意味解析を通した上でK平均法でクラスタリング。至って単純。
km.labels_を出力すると

[1 1 1 1 0 2 4 3]

こんな感じで出力されるのですが、これは「データセットのインデックス0,1,2,3は1番クラスタ、インデックス4は0番クラスタ、、、」ということです。これを使って元データをグルーピングしておきます。

すっごい簡単。使い方はこれであってる、と思う。たぶん。あ、ドキュメント数は少なくても1,000以上ないときれいにクラスタリングされなそうだし、テキストももっと長くないと納得のいく結果は出力されにくいんじゃないかと。

自分のツイートを使ったり青空文庫を使ったりで気軽に試せそうです。

Python 3.4.2、scikit-learn==0.15.2 で動かしました。

昨日Mahoutの記事書いたばっかりなのにね。