0

回答ありがとうございます。以前は StackOverflow を使用したことがなかったので、回答の数とその速度に驚きました。素晴らしいです。

私はまだ適切に回答を行っていませんが、問題の仕様にいくつかの情報を追加する必要があると考えました. 下の画像を参照してください。

ポイントが足りないので画像は掲載できませんが、http://journal.acquitane.com/2010-01-20/image003.jpgで画像をご覧いただけます

この画像は、私が達成しようとしていることをより詳しく説明している可能性があります。したがって、ページ全体の水平線がチャートの価格ポイントであることがわかります。これで、それぞれの 0.5% 以内の線のクラスター化が得られました。これは良いことであり、これらのクラスターを自動的に識別したい理由です。チャートで、S2 & MR1、R2 & WPP1 にクラスターがあることがわかります。

そのため、毎日これらの価格を作成し、0.5% 以内のものを手動で特定できます。-しかし、この質問の目的は、pythonルーチンでそれを行う方法です。

ラベルを付けてリストを再作成しました (以下を参照)。2 つの異なる日付のものであるため、表示価格が画像の価格と一致しないことに注意してください。

[YR3,175.24,8] [SR3,147.85,6] [YR2,144.13,8] [SR2,130.44,6] [YR1,127.79,8] [QR3,127.42,5] [SR1,120.94,6] [ QR2,120.22,5] [MR3,118.10,3] [WR3,116.73,2] [DR3,116.23,1] [WR2,115.93,2] [QR1,115.83,5] [MR2,115.56,3] [DR2 ,115.53,1] [WR1,114.79,2] [DR1,114.59,1] [WPP,113.99,2] [DPP,113.89,1] [MR1,113.50,3] [DS1,112.95,1] [WS1, 112.85,2] [DS2,112.25,1] [WS2,112.05,2] [DS3,111.31,1] [MPP,110.97,3] [WS3,110.91,2] [50MA,110.87,4] [MS1,108.91 ,3] [QPP,108.64,5] [MS2,106.37,3] [MS3,104.31,3] [QS1,104.25,5] [SPP,103.53,6] [200MA,99.42,7] [QS2,97.05, 5] [YPP,96.68,8] [SS1,94.03,6] [QS3,92.66,5] [YS1,80.34,8] [SS2,76.62,6] [SS3,67.12,6] [YS2,49.23,8] ] [YS3,32.89,8]

グループ C は間違っており、含めるべきではないという点で、元のリストを間違えました。ご指摘ありがとうございます。

また、0.5% は固定されていません。この値は日々変化しますが、問題を特定するための例として 0.5% を使用しました。

再度、感謝します。マーク

PS。私は今、答えをチェックすることでひび割れます。

やあ:

株価を操作する必要があります。Python を使い始めたばかりです (ただし、どの言語でもこれを実装するのは難しいと思います)。これをPythonでうまく実装する方法についてのアイデアを探しています。

ありがとうマーク

問題: サブリストに 2 つの項目 (株価、重量) があるリスト (FloorLevels (以下を参照)) のリストがあります。株価が互いに 0.5% 以内にある場合、株価をグループに分けたいと考えています。グループの強さは、その総重量によって決まります。例えば:

Group-A
115.93,2
115.83,5
115.56,3
115.53,1
-------------
TotalWeight:12
-------------
Group-B
113.50,3
112.95,1
112.85,2
-------------
TotalWeight:6
-------------    

FloorLevels[   
[175.24,8]
[147.85,6]
[144.13,8]
[130.44,6]
[127.79,8]
[127.42,5]
[120.94,6]
[120.22,5]
[118.10,3]
[116.73,2]
[116.23,1]
[115.93,2]
[115.83,5]
[115.56,3]
[115.53,1]
[114.79,2]
[114.59,1]
[113.99,2]
[113.89,1]
[113.50,3]
[112.95,1]
[112.85,2]
[112.25,1]
[112.05,2]
[111.31,1]
[110.97,3]
[110.91,2]
[110.87,4]
[108.91,3]
[108.64,5]
[106.37,3]
[104.31,3]
[104.25,5]
[103.53,6]
[99.42,7]
[97.05,5]
[96.68,8]
[94.03,6]
[92.66,5]
[80.34,8]
[76.62,6]
[67.12,6]
[49.23,8]
[32.89,8]
]
4

7 に答える 7

3

k-means クラスタリングを繰り返し使用することをお勧めします。略して KMC と呼びましょう。kKMC はシンプルで強力なクラスタリング アルゴリズムですが、目標とするクラスタの数を「指定」する必要があります。あなたはそれを事前に知りません(私があなたを正しく理解していれば)- 「一緒にクラスター化された」2つのアイテムが互いに離れてkいる以上の最小のものを望んでいるだけです。X%したがって、k等しいものから始め1ます -- すべてがまとめられており、クラスタリング パスは必要ありません;-) -- クラスタの直径を確認します (クラスタの「直径」は、ジオメトリでの用語の使用から、任意の 2 つの間の最大距離です)。クラスターのメンバー)。

直径が の場合> X%、 を設定k += 1し、クラスターの数として KMC を実行しk、チェックを繰り返します。

擬似コード:

def markCluster(items, threshold):
    k = 1
    clusters = [items]
    maxdist = diameter(items)
    while maxdist > threshold:
        k += 1
        clusters = Kmc(items, k)
        maxdist = max(diameter(c) for c in clusters)
    return clusters

もちろん、適切なPython 関数があるdiameterと仮定します。Kmc

これはあなたが望むようなものですか?diameterもしそうなら、私たちはあなたにandを書く方法を示すことに移ることができますKmc(あなたが扱うべき数が比較的限られている場合は純粋な Pythonitemsで、それ以外の場合は などの強力なサードパーティのアドオン フレームワークを活用することによってnumpy) -- しかし、それはもしあなたが実際にかなり違うものが欲しいなら、そのようなトラブルに行く価値はありません。

于 2010-01-25T05:38:57.700 に答える
2

の各株が、* 1.05 >=および/ 1.05 <=の場合、株sはグループに属しますよね?GtGstst

各グループに株式を追加するにはどうすればよいですか? 在庫が 95、100、101、105 の場合、グループを 100 で開始してから 101 を追加すると、最終的に {100, 101, 105} になります。100 の後に 95 を実行すると、{100, 95} になります。

すべての可能な順列を考慮する必要がありますか? もしそうなら、あなたのアルゴリズムは非効率的になります。

于 2010-01-25T04:47:48.357 に答える
2

問題をより詳細に指定する必要があります。「株価が互いに 0.5% 以内にある場合にグループ分けする」とはどういう意味ですか?

可能性:

(1) グループの各メンバーは、グループの他のすべてのメンバーの 0.5% 以内です。

(2) リストをソートし、ギャップが 0.5% を超える場所で分割します

116.23 は 115.93 の 0.5% 以内であることに注意してください -- abs((116.23 / 115.93 - 1) * 100) < 0.5-- ただし、グループ A とグループ C に 1 つの数値を入れています。

簡単な例: a, b, c = (0.996, 1, 1.004)... a と b は適合し、b と c は適合しますが、a と c は適合しないことに注意してください。それらをどのようにグループ化しますか? またその理由は? 入力リストの順序は適切ですか?

可能性 (1) ab,c または a,bc ... を生成します。タイブレーク ルールをお願いします
可能性 (2) abc を生成します (大きなギャップがないため、1 つのグループのみ)

于 2010-01-25T05:09:09.887 に答える
1

それらを難しい「グループ」に分類することはできません。価格(1.0、1.05、1.1)がある場合、1番目と2番目は同じグループに含まれ、2番目と3番目は同じグループに含まれる必要がありますが、1番目と3番目は含まれません。

あなたが役に立つと思うかもしれない何かをするための速くて汚い方法:

def make_group_function(tolerance = 0.05):
    from math import log10, floor
    # I forget why this works. 
    tolerance_factor = -1.0/(-log10(1.0 + tolerance))
    # well ... since you might ask
    # we want: log(x)*tf - log(x*(1+t))*tf = -1, 
    # so every 5% change has a different group. The minus is just so groups 
    # are ascending .. it looks a bit nicer.
    #
    # tf = -1/(log(x)-log(x*(1+t)))
    # tf = -1/(log(x/(x*(1+t))))
    # tf = -1/(log(1/(1*(1+t)))) # solved .. but let's just be more clever
    # tf = -1/(0-log(1*(1+t)))
    # tf = -1/(-log((1+t))
    def group_function(value):
        # don't just use int - it rounds up below zero, and down above zero
        return int(floor(log10(value)*tolerance_factor))
    return group_function

使用法:

group_function = make_group_function()
import random
groups = {}
for i in range(50):
    v = random.random()*500+1000
    group = group_function(v)
    if group in groups:
        groups[group].append(v)
    else:
        groups[group] = [v]

for group in sorted(groups):
    print 'Group',group
    for v in sorted(groups[group]):
        print v
    print
于 2010-01-25T05:35:06.020 に答える
0

特定の株価セットに対して、互いに0.5%以内の株式をグループ化する方法はおそらく複数あります。価格をグループ化するためのいくつかの追加のルールがなければ、答えがあなたが本当に望むことをすることを確実にする方法はありません。

于 2010-01-25T05:20:20.780 に答える
0

どの値が適切に適合するかを選択する適切な方法は別として、これはオブジェクト指向を少し取り入れるだけで対処がはるかに簡単になる問題です。

ここでは 2 つのクラスを作成しましたが、最低限の望ましい動作が含まれていますが、これにより分類がはるかに簡単になります。Group クラスでそれを操作するための 1 つのポイントが得られます。

新しいメンバーが追加されると、グループを含めるための制限が変化するという意味で、次のコードが正しくないことがわかります。分離基準が同じままであっても、マルチパスアプローチを使用するように get_groups メソッドを書き直す必要があります。難しいことではありませんが、コードが長すぎてここでは役に立ちません。

from copy import copy

class Group(object):
    def __init__(self,data=None, name=""):
        if data:
            self.data = data
        else:
            self.data = []
        self.name = name

    def get_mean_stock(self):
        return sum(item[0] for item in self.data) / len(self.data)

    def fits(self, item):
        if 0.995 < abs(item[0]) / self.get_mean_stock() < 1.005:
            return True
        return False

    def get_weight(self):
        return sum(item[1] for item in self.data)

    def __repr__(self):
        return "Group-%s\n%s\n---\nTotalWeight: %d\n\n" % (
            self.name,
            "\n".join("%.02f, %d" % tuple(item) for item in self.data ),
            self.get_weight())


class StockGrouper(object):
    def __init__(self, data=None):
        if data:
            self.floor_levels = data
        else:
            self.floor_levels = []

    def get_groups(self):
        groups = []
        floor_levels = copy(self.floor_levels)
        name_ord = ord("A") - 1
        while floor_levels:
            seed = floor_levels.pop(0)
            name_ord += 1
            group = Group([seed], chr(name_ord))
            groups.append(group)
            to_remove = []
            for i, item in enumerate(floor_levels):
                if group.fits(item):
                    group.data.append(item)
                    to_remove.append(i)
            for i in reversed(to_remove):
                floor_levels.pop(i)
        return groups

テスト:

floor_levels = [  [stock. weight] ,... <paste the data above> ]
s = StockGrouper(floor_levels)
s.get_groups()
于 2010-01-25T13:19:34.540 に答える
0

グループ化要素には itertools.groupby() を使用できますか? データがソートされると、グループ化の多くの作業がすでに行われているため、反復の現在の値が前回と 0.5% 未満異なるかどうかをテストし、 itertools.groupby() を関数が false を返すたびに新しいグループ。

于 2010-01-25T16:45:44.850 に答える