« Schemeでチャーチ数 |Main| 日記 »

« Pythonで箇条書きをHTMLに変換 | Python | Pythonでタブ区切りデータを出力する方法 »

Pythonでウィンドウをずらしながら平均、分散、回帰直線の傾き、相関係数を求める。

有名な方の分散を求める(平均を中に含んでいる)式を素直に使って計算すると、ループを2回なめないといけませんが、式をいじると1回のループで平均と分散が同時に出る、というのはたぶん有名な話だと思います。今回はそれに似ていて、n個のデータからサイズmの連続している部分を切り出して、そのそれぞれの統計を行う方法のハックです。普通にやるとO(mn - m^2)くらいかかるわけですが、これがO(n - m)になっていると思います。たぶん。

水曜日に始めたC言語の勉強で、せっかくだからパフォーマンスが要求されるようなプログラムを作ろうと思って考えたのがこれです。ってアルゴリズムの部分で高速化しても「Cで書いてよかった」という満足感は味わえないんですがね…。

class RingCalc:
    def __init__(self, size):
        self.size = size
        self.Sx = size * (size - 1) / 2
        self.Sx2 = sum([x * x for x in range(size)])

    def setValues(self, values):
        self.values = values[:self.size]
        self.index = 0
        self.initCalc()
        for v in values[self.size:]:
            self.append(v)

    def append(self, value):
        oldValue = self.values[self.index]
        self.values[self.index] = value
        self.index += 1
        self.index %= self.size
        
        self.stepCalc(oldValue, value)

    def initCalc(self):
        self.sumY = sum(self.values)
        self.sumY2 = sum([y * y for y in self.values])
        self.sumXY = sum([x * y for (x, y) in enumerate(self.values)])
        
        self.calced()

    def stepCalc(self, oldValue, value):
        self.sumY = self.sumY - oldValue + value
        self.sumY2 = self.sumY2 - oldValue ** 2 + value ** 2
        self.sumXY = self.sumXY - self.sumY + self.size * value

        self.calced()
        
    def calced(self):
        from math import sqrt
        n = self.size
        Sy2 = self.sumY2
        Sy = self.sumY
        Sxy = self.sumXY
        Sx = self.Sx
        Sx2 = self.Sx2
        SySy = float(Sy * Sy)
        SxSy = float(Sx * Sy)
        SxSx = float(Sx * Sx)
        Vxy = Sxy * n - SxSy
        Vxx = Sx2 * n - SxSx
        Vyy = Sy2 * n - SySy
        print "ave:", Sy / n
        print "var:", Vyy / n / (n - 1)
        print "katamuki:", Vxy / Vxx
        print "cor:", Vxy / sqrt (Vyy * Vxx)

トラックバック(Trackback)

Trackback URL: http://www.nishiohirokazu.org/mt/mt-tb.cgi/91

フィードバック

by satomi ninomiya | 2007年07月19日 12:23

西尾さん。この間のPython Edge 2007で司会をしていた二宮です。お疲れ様です。Pythonで相関係数を計算してみようと思ってネットで情報を探していたら、西尾さんのHPに行きつきました。PythonはエクセルのようなCORREL関数は持っていないのでしょうか?お時間のある時に、御願いします。

相関係数くらいであれば加減乗除で簡単に実装できるので理解を深めるためにも一度実装してみた方がいいかと思います。

ご意見・ご感想をお送りください(フィードバック)

(フィードバックはメールで送信され、基本的に表示されませんが、内容によっては公開させていただくこともございます。ご了承ください。Your comment doesn't appear the page immediately. If the comment has value to other people, it will be put on the page or subsequent entries. Thank you.)

上の情報は、いずれも未記入でかまいません。 All of above questions are optional.