pythonで多次元尺度法

最近
これをよんでます。
結構間違いがあるみたいで、
自分のタイポかコードエラーかいまいち分からんときがありますが、
データーの解析をpython書きながら学べるのはいいなあって思います。
まだ三章ですが
多次元尺度法のアルゴリズムがありました。
引数のdataは何かのベクトルの集合。
本ではRSSに用いられる単語の数です。
distanceはピアソン相関です。
別途定義してあります。
で、MDSのアルゴリズムがこんな感じになっているそうです。
①実際のn個のデータの距離を算出
②ランダムにn個の座標を発生(randamモジュールを使う)n個の(x,y)座標
③②の座標間の距離を算出
④①と③の距離の差のずれを算出(実際の距離−過程の距離)/実際の距離

⑤loc[k][0か1]-loc[j][0か1]にエラーの割合を掛けた値をgradに入れる
⑥誤差の合計を計算(絶対値の和で計算)
⑦totalerrorがlasterrorより大きい=ポイントの移動でエラーが悪化したらストップ。
⑧座標−rate*傾斜にポイントを移動
⑨locを返す。
1000回のイテレーション以内で回答になる想定?
動作を追うのは大変勉強になる。
Rとか入れていないケミストにSDFからMDS実行するコード作るといいかもしれない。
でも、、、ChemScriptってFPのビットデータ得られるんだったかなぁ。
自分だけならRのMDSの方がやっぱり楽です。

def scaledown(data, distance=pearson, rate = 0.01):
    n = len(data)
    realdist = [[distance(data[i],data[j]) for j in range(n)] for i in
            range(0,n)]

    outersum = 0.0

    loc = [[random.random(), random.random()] for i in range(n)]
    fakedist = [[0.0 for j in range(n)] for i in range(n)]

    lasterror = None

    for m in range(0,1000):
        for i in range(n):
            for j in range(n):
                fakedist[i][j] = sqrt(sum([pow(loc[i][x]-loc[j][x],2) for x in
                    range(len(loc[i]))]))
        grad = [[0.0,0.0] for i in range(n)]

        totalerror = 0
        for k in range(n):
            for j in range(n):
                if j == k: continue
                errorterm = (fakedist[j][k]-realdist[j][k])/realdist[j][k]
                grad[k][0] += ((loc[k][0]-loc[j][0])/fakedist[j][k])*errorterm
                grad[k][1] += ((loc[k][1]-loc[j][1])/fakedist[j][k])*errorterm
                totalerror += abs(errorterm)
        print totalerror

        if lasterror and lasterror <totalerror: break
        lasterror = totalerror

        for k in range(n):
            loc[k][0] -= rate*grad[k][0]
            loc[k][1] -= rate*grad[k][1]
    return loc
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s