最新の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の記事書いたばっかりなのにね。

Mahoutをローカルモード(Hadoopを使わない)で使うための設定

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

0.8あたりからMahoutはHDFSからデータ読み込むのがデフォルトになったのか、ファイルを読み込んでもらおうとしても「HADOOP_HOMEが無いよ!」ってエラー吐いて先に進んでくれません。

Hadoopいれろや、ってことなんですけどたいしてメモリ積んでないVMでHadoopいれると結構ツラいものがあるし、たかだか数百万件のログ読ますのにHadoopいれるのもなぁ、という感じでローカルモードで使う方法調べた時のメモ。使ったのはMahout 0.9です。

/usr/lib/にDLしてきたMahoutを置いて、.bash_profileに

export JAVA_HOME=/usr/lib/jvm/jre-1.7.0
export PATH=$JAVA_HOME/bin:$PATH

export MAHOUT_HOME=/usr/lib/mahout-distribution-0.9
export PATH=$PATH:$MAHOUT_HOME/bin
export MAHOUT_LOCAL=TRUE
export CLASSPATH=:$MAHOUT_HOME/lib/hadoop/hadoop-core-1.2.1.jar:$MAHOUT_HOME/lib:$CLASSPATH

って記述。

細かいことは割愛なんですけど、ポイントは「export MAHOUT_LOCAL=TRUE」の部分で、あとは通常の設定となんも変わらず。

ただ、最近Mahout使うよりPythonで書くほうが多いのであんまりMahout触ってない。