Wie erstelle ich ein Histogramm für eine gegebene Wahrscheinlichkeitsverteilung (zum funktionalen Test server)?
-
09-06-2019 - |
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?
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.