Wie erstelle ich ein Histogramm für eine gegebene Wahrscheinlichkeitsverteilung (zum funktionalen Test server)?

StackOverflow https://stackoverflow.com/questions/53786

Frage

Ich bin versucht, zu automatisieren, die Funktionsprüfung von einem server über eine realistische Häufigkeit Verteilung der Anfragen.(eine Art von Belastungstest, eine Art simulation)

Ich habe mich entschieden die Weibull Vertrieb als auch "Art" entspricht der distribution, die ich beobachtet habe (Rampen schnell, Tropfen off schnell, aber nicht sofort)

Ich verwende diese distribution zu erzeugen, die Anzahl der Anfragen, die gesendet werden sollen, die jeden Tag zwischen einer bestimmten start-und Ende-Datum

Ich habe gehackt, gemeinsam einen Algorithmus in Python, der irgendwie funktioniert, aber es fühlt sich notdürftigem:

how_many_days = (end_date - start_date).days
freqs = defaultdict(int)
for x in xrange(how_many_responses):
    freqs[int(how_many_days * weibullvariate(0.5, 2))] += 1
timeline = []
day = start_date
for i,freq in sorted(freqs.iteritems()):
    timeline.append((day, freq))
    day += timedelta(days=1)
return timeline

Welche besseren Möglichkeiten gibt es, dies zu tun?

War es hilfreich?

Lösung

Dies ist nicht nur schnell und wahrscheinlich nicht so genau, aber wenn Sie das PDF selbst berechnen, dann zumindest machen Sie es leichter, mehrere kleinere / größere auf einer einzigen Timeline zu legen. dev ist die Standardabweichung in dem Gauß- Rauschen, das die Rauhigkeit steuert. Beachten Sie, dass dies nicht die ‚richtige‘ Art und Weise zu erzeugen, was Sie wollen, aber es ist einfach.

import math
from datetime import datetime, timedelta, date
from random import gauss

how_many_responses = 1000
start_date = date(2008, 5, 1)
end_date = date(2008, 6, 1)
num_days = (end_date - start_date).days + 1
timeline = [start_date + timedelta(i) for i in xrange(num_days)]

def weibull(x, k, l):
    return (k / l) * (x / l)**(k-1) * math.e**(-(x/l)**k)

dev = 0.1
samples = [i * 1.25/(num_days-1) for i in range(num_days)]
probs = [weibull(i, 2, 0.5) for i in samples]
noise = [gauss(0, dev) for i in samples]
simdata = [max(0., e + n) for (e, n) in zip(probs, noise)]
events = [int(p * (how_many_responses / sum(probs))) for p in simdata]

histogram = zip(timeline, events)

print '\n'.join((d.strftime('%Y-%m-%d ') + "*" * c) for d,c in histogram)

Andere Tipps

Warum versuchen Sie nicht, The Grinder 3 Ihrem Server laden zu testen, kommt es mit all dies und mehr vorkompilierte, und es python als Skriptsprache unterstützt

Etwas länger, aber wahrscheinlich besser lesbar Nacharbeit Ihrer letzten vier Zeilen:

samples = [0 for i in xrange(how_many_days + 1)]
for s in xrange(how_many_responses):
    samples[min(int(how_many_days * weibullvariate(0.5, 2)), how_many_days)] += 1
histogram = zip(timeline, samples)
print '\n'.join((d.strftime('%Y-%m-%d ') + "*" * c) for d,c in histogram)

Dies fällt immer die Proben innerhalb des Zeitraums, aber Sie erhalten eine entsprechende Beule am Ende der Timeline von allen Proben, die über den sind [0, 1] Bereich.

Statt die Anzahl der Anfragen als fester Wert zu geben, warum nicht einen Skalierungsfaktor stattdessen verwenden? Im Moment sind Sie Anfragen als eine begrenzte Menge zu behandeln, und Randomisierung der Tage, an denen diese Anforderungen fallen. Es wäre sinnvoll erscheint Ihre Anfragen pro Tag als unabhängig zu behandeln.

from datetime import *
from random import *

timeline = []
scaling = 10
start_date = date(2008, 5, 1)
end_date = date(2008, 6, 1)

num_days = (end_date - start_date).days + 1
days = [start_date + timedelta(i) for i in range(num_days)]
requests = [int(scaling * weibullvariate(0.5, 2)) for i in range(num_days)]
timeline = zip(days, requests)
timeline

schrieb ich den Code oben kürzer (aber vielleicht jetzt auch verschleiert es?)

timeline = (start_date + timedelta(days=days) for days in count(0))
how_many_days = (end_date - start_date).days
pick_a_day = lambda _:int(how_many_days * weibullvariate(0.5, 2))
days = sorted(imap(pick_a_day, xrange(how_many_responses)))
histogram = zip(timeline, (len(list(responses)) for day, responses in groupby(days)))
print '\n'.join((d.strftime('%Y-%m-%d ') + "*" * c) for d,c in histogram)

Eine andere Lösung ist die Verwendung Rpy , die gesamte Leistung von R (darunter viele Tools setzt für Distributionen), leicht in Python.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top