Участок статистической информации о множественных записях экспериментов с Сиборном - PullRequest
0 голосов
/ 05 января 2019

У меня есть рандомизированный алгоритм, который я повторяю несколько раз, чтобы я мог оценить его статистически. Кадры данных из экспериментов могут быть сгруппированы для расчета среднего значения и медианы.

Теперь я хотел бы представить исходную информацию вместе со статистикой, которую я тоже рассчитал, с Seaborn. Таким образом, у меня есть до 100 Dataframes с такими данными.

module, coverage, timestamp
examples.monkey, 32.142857142857146, 1546513589.59586
examples.monkey, 35.714285714285715, 1546513589.609822
examples.monkey, 35.714285714285715, 1546513589.617172
...
util.container, 27.586206896551722 ,1546513594.559889
util.container, 27.586206896551722 ,1546513594.579989
util.container, 27.586206896551722 ,1546513594.598491

Я могу просто напечатать несколько временных рядов с линейными графиками следующим образом.

sns.set(style="darkgrid")
for df in dfs:
    min_timestamp = df['timestamp'].min()
    df["time"] = df["timestamp"] - min_timestamp

keys = ["Run " + str(i) for i in range(len(dfs))]
glued = pd.concat(dfs, keys=keys).reset_index(level=0).rename(columns={'level_0': 'run'})
ax = sns.lineplot(hue="module", x="time", y="coverage", ci="sd", units="run", estimator=None, data=glued)
plt.show()

В результате получается такой график: Plot from different algorithm runs

Затем я могу вычислить среднее значение и добавить его к графику следующим образом:

sns.set(style="darkgrid")
for df in dfs:
    min_timestamp = df['timestamp'].min()
    df["time"] = df["timestamp"] - min_timestamp

keys = ["Run " + str(i) for i in range(len(dfs))]
glued = pd.concat(dfs, keys=keys).reset_index(level=0).rename(columns={'level_0': 'Run'})
sns.lineplot(hue="module", x="time", y="coverage", ci="sd", units="Run", estimator=None, data=glued)

means = glued.groupby(by=["module", "time"], as_index=False).mean()
means["run"] = "Mean"
sns.lineplot(hue="module", x="time", y="coverage", estimator="mean", palette=sns.xkcd_palette(["red", "black"]),  err_style="band", data=means)

plt.show()

Однако сюжет, который следует из этого, довольно бесполезен. Похоже на это.

Plot from different algorithm runs with mean

Мне бы очень хотелось что-то наподобие примеров из Морского Рога, где мои измерения напечатаны в виде области со средним значением, которое хорошо видно. Seaborn examples

Теперь я подозреваю, что получаю это уродливое изображение, потому что у кадра данных со средним гораздо больше точек данных. Алгоритм выполняет измерения в случайных интервалах, поэтому временные метки не перекрываются большую часть времени. Поскольку измерения расположены так близко друг к другу и между ними проведена линия, мы получаем картину этого широкого штриха.

Мои конкретные вопросы сейчас таковы: имеет ли здесь смысл линейный график, а также, если это правильный подход, заранее рассчитайте среднее значение? Если подход правильный, как я могу это исправить, если нет, что еще вы используете?

Я также загрузил некоторые примеры результатов в виде CSV-файлов здесь на случай, если вы захотите попробовать: 1 2 3 4 5

1 Ответ

0 голосов
/ 06 января 2019

Я не уверен, что вы правильно используете lineplot во втором примере. Весь смысл в том, чтобы позволить seaborn вычислить статистику и построить график оценки ± ci для вас. Я не вижу смысла вычислять среднее значение в кадре данных, а затем просить seaborn построить среднее значение для этого кадра.

Но, в любом случае, ваша проблема в том, что seaborn собирает только те значения y, которые имеют точно такое же значение x. С документация :

По умолчанию график агрегируется по нескольким значениям y для каждого значения. х и показывает оценку центральной тенденции и уверенности интервал для этой оценки.

Как вы правильно догадались, ваши значения слишком случайны и редко пересекаются, что означает, что морские корни не могут вычислить значимое среднее значение. На мой взгляд, решение состоит в том, чтобы уменьшить временное разрешение ваших измерений, чтобы все измерения, сделанные за период (скажем, 0,1 единицы времени), имели одинаковое значение времени, что позволит морским корням усреднять их вместе.

glued["roundtime"] = glued["time"].round(1)  # 1 significant digit
ax = sns.lineplot(hue="module", x="roundtime", y="coverage", ci="sd", estimator='mean', data=glued)

enter image description here

...