Русский
Русский
English
Статистика
Реклама

Статистический тест

Python и статистический вывод часть 4

12.05.2021 06:16:40 | Автор: admin

Этот заключительный пост посвящен анализу дисперсии. Предыдущий пост см. здесь.

Анализ дисперсии

Анализ дисперсии (варианса), который в специальной литературе также обозначается как ANOVA от англ. ANalysis Of VAriance, это ряд статистических методов, используемых для измерения статистической значимости расхождений между группами. Он был разработан чрезвычайно одаренным статистиком Рональдом Фишером, который также популяризировал процедуру проверки статистической значимости в своих исследовательских работах по биологическому тестированию.

Примечание. В предыдущей и этой серии постов для термина variance использовался принятый у нас термин дисперсия и в скобках местами указывался термин варианс. Это не случайно. За рубежом существуют парные термины variance и covariance, и они по идее должны переводиться с одним корнем, например, как варианс и коварианс, однако на деле у нас парная связь разорвана, и они переводятся как совершенно разные дисперсия и ковариация. Но это еще не все. Dispersion (статистическая дисперсия) за рубежом является отдельным родовым понятием разбросанности, т.е. степени, с которой распределение растягивается или сжимается, а мерами статистической дисперсии являются варианс, стандартное отклонение и межквартильный размах. Dispersion, как родовое понятие разбросанности, и variance, как одна из ее мер, измеряющая расстояние от среднего значения - это два разных понятия. Далее в тексте для variance везде будет использоваться общепринятый термин дисперсия. Однако данное расхождение в терминологии следует учитывать.

Наши тесты на основе z-статистики и t-статистики были сосредоточены на выборочных средних значениях как первостепенном механизме проведения разграничения между двумя выборками. В каждом случае мы искали расхождение в средних значениях, деленных на уровень расхождения, который мы могли обоснованно ожидать, и количественно выражали стандартной ошибкой.

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

Длительности (сек), постранично и совмещенноДлительности (сек), постранично и совмещенно

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

Статистическая значимость на основе анализа дисперсии вытекает из соотношения двух дисперсий дисперсии между исследуемыми группами и дисперсии внутри исследуемых групп. Если существует значимое межгрупповое расхождение, которое не отражено внутри групп, то эти группы помогают объяснить часть дисперсии между группами. И напротив, если внутригрупповая дисперсия идентична межгрупповой дисперсии, то группы статистически от друг друга неразличимы.

F-распределение

F-распределение параметризуется двумя степенями свободы степенями свободы размера выборки и числа групп.

Первая степень свободы это количество групп минус 1, и вторая степень свободы размер выборки минус число групп. Если k представляет число групп, и n объем выборки, то получаем:

df_1=k-1df_2=n-k

Мы можем визуализировать разные F-распределения на графике при помощи функции библиотеки pandas plot:

def ex_2_Fisher(): '''Визуализация разных F-распределений на графике''' mu = 0 d1_values, d2_values = [4, 9, 49], [95, 90, 50] linestyles = ['-', '--', ':', '-.'] x = sp.linspace(0, 5, 101)[1:]  ax = None for (d1, d2, ls) in zip(d1_values, d2_values, linestyles): dist = stats.f(d1, d2, mu) df = pd.DataFrame( {0:x, 1:dist.pdf(x)} )  ax = df.plot(0, 1, ls=ls,  label=r'$d_1=%i,\ d_2=%i$' % (d1,d2), ax=ax) plt.xlabel('$x$\nF-статистика') plt.ylabel('Плотность вероятности \n$p(x|d_1, d_2)$') plt.show()

Кривые приведенного выше графика показывают разные F-распределения для выборки, состоящей из 100 точек, разбитых на 5, 10 и 50 групп.

F-статистика

Тестовая выборочная величина, которая представляет соотношение дисперсии внутри и между группами, называется F-статистикой. Чем ближе значение F-статистики к единице, тем более похожи обе дисперсии. F-статистика вычисляется очень просто следующим образом:

где S2b это межгрупповая дисперсия, и S2w внутригрупповая дисперсия.

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

F-тест всегда является односторонним, потому что любая дисперсия среди групп демонстрирует тенденцию увеличивать F. При этом F не может уменьшаться ниже нуля.

Внутригрупповая дисперсия для F-теста вычисляется как среднеквадратичное отклонение от среднего значения. Мы вычисляем ее как сумму квадратов отклонений от среднего значения, деленную на первую степень свободы. Например, если имеется kгрупп, каждая со средним значением xk, то мы можем вычислить внутригрупповую дисперсию следующим образом:

где SSW это внутригрупповая сумма квадратов, и xjk это значение j-ого элемента в группе .

Приведенная выше формула для вычисления SSW имеет грозный вид, но на деле довольно легко имплементируется на Python, как сумма квадратичных отклонений от среднего значения ssdev, делающая вычисление внутригрупповой суммы квадратов тривиальным:

def ssdev( xs ): '''Сумма квадратов отклонений между  каждым элементом и средним по выборке''' mu = xs.mean()  square_deviation = lambda x : (x - mu) ** 2  return sum( map(square_deviation, xs) )

Межгрупповая дисперсия для F-теста имеет похожую формулу:

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

Отсюда, SST это попросту полная сумма квадратов без какого-либо разбиения на группы. На языке Python значения SST и SSW вычисляются элементарно, как будет показано ниже.

ssw = sum( groups.apply( lambda g: ssdev(g) ) ) # внутригрупповая сумма # квадратов отклонений sst = ssdev( df['dwell-time'] ) # полная сумма квадратов по всему наборуssb = sst  ssw # межгрупповая сумма квадратов отклонений

F-статистика вычисляется как отношение межгрупповой дисперсии к внутригрупповой. Объединив определенные ранее функции ssb и ssw и две степени свободы, мы можем вычислить F-статистика.

На языке Python F-статистика из групп и двух степеней свободы вычисляется следующим образом:

msb = ssb / df1 # усредненная межгрупповаяmsw = ssw / df2 # усредненная внутригрупповаяf_stat = msb / msw

Имея возможность вычислить F-статистику из групп, мы теперь готовы использовать его в соответствующем F-тесте.

F-тест

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

Библиотека scipy предлагает функцию stats.f.sf, но она измеряет дисперсию между и внутри всего двух групп. В целях выполнения F-теста на наших 20 разных группах, нам придется имплементировать для нее нашу собственную функцию. К счастью, мы уже проделали всю тяжелую работу в предыдущих разделах, вычислив надлежащую F-статистику. Мы можем выполнить F-тест, отыскав F-статистику в F-распределении, параметризованном правильными степенями свободы. В следующем ниже примере мы напишем функцию f_test, которая все это использует для выполнения теста на произвольном числе групп:

def f_test(groups): m, n = len(groups), sum(groups.count()) df1, df2 = m - 1, n - m  ssw = sum( groups.apply(lambda g: ssdev(g)) )  sst = ssdev( df['dwell-time'] )  ssb = sst - ssw  msb = ssb / df1  msw = ssw / df2  f_stat = msb / msw return stats.f.sf(f_stat, df1, df2)    def ex_2_24(): '''Проверка вариантов дизайна веб-сайта на основе F-теста''' df = load_data('multiple-sites.tsv') groups = df.groupby('site')['dwell-time'] return f_test(groups)
0.014031745203658217

В последней строке приведенной выше функции мы преобразуем значение F-статистики в p-значение, пользуясь функцией scipy stats.f.sf, параметризованной правильными степенями свободы. P-значение является мерой всей модели, т.е. насколько хорошо разные веб-сайты объясняют дисперсию времени пребывания в целом. Нам остается только выбрать уровень значимости и выполнить проверку. Будем придерживаться 5%-ого уровня значимости.

Проверка возвращает p-значение, равное 0.014, т.е. значимый результат. Разные варианты веб-сайта действительно имеют разные дисперсии, которые нельзя просто объяснить одной лишь случайной ошибкой в выборке.

F-распределение со степенями свободы 19 и 980F-распределение со степенями свободы 19 и 980

Для визуализации распределений всех вариантов дизайна веб-сайта на одном графике мы можем воспользоваться коробчатой диаграммой, разместив распределения для сопоставления рядом друг с другом:

def ex_2_25(): '''Визуализация распределений всех вариантов  дизайна веб-сайта на одной коробчатой диаграмме''' df = load_data('multiple-sites.tsv') df.boxplot(by='site', showmeans=True) plt.xlabel('Номер дизайна веб-сайта') plt.ylabel('Время пребывания, сек.') plt.title('') plt.suptitle('') plt.show()

В приведенном выше примере показана работа функции boxplot, которая вычисляет свертку на группах и сортирует группы по номеру варианта дизайна веб-сайта. Соответственно наш изначальный веб-сайт с номером 0, на графике расположен крайним слева.

Может создастся впечатление, что вариант дизайна веб-сайта с номером 10 имеет самое длительное время пребывания, поскольку его межквартильный размах простирается вверх выше других. Однако, если вы присмотритесь повнимательнее, то увидите, что его среднее значение меньше, чем у варианта дизайна с номером 6, имеющего среднее время пребывания более 144 сек.:

def ex_2_26(): '''T-проверка вариантов 0 и 10 дизайна веб-сайта''' df = load_data('multiple-sites.tsv') groups = df.groupby('site')['dwell-time'] site_0 = groups.get_group(0)  site_10 = groups.get_group(10) _, p_val = stats.ttest_ind(site_0, site_10, equal_var=False) return p_val
0.0068811940138903786

Подтвердив статистически значимый эффект при помощи F-теста, теперь мы вправе утверждать, что вариант дизайна веб-сайта с номером 6 статистически отличается от изначального значения:

def ex_2_27(): '''t-тест вариантов 0 и 6 дизайна веб-сайта''' df = load_data('multiple-sites.tsv') groups = df.groupby('site')['dwell-time'] site_0 = groups.get_group(0)  site_6 = groups.get_group(6) _, p_val = stats.ttest_ind(site_0, site_6, equal_var=False) return p_val
0.005534181712508717

Наконец, у нас есть подтверждающие данные, из которых вытекает, что веб-сайт с номером 6 является подлинным улучшением существующего веб-сайта. В результате нашего анализа исполнительный директор AcmeContent санкционирует запуск обновленного дизайна веб-сайта. Веб-команда - в восторге!

Размер эффекта

В этой серии постов мы сосредоточили наше внимание на широко используемых в статистической науке методах проверки статистической значимости, которые обеспечивают обнаружение статистического расхождения, которое не может быть легко объяснено случайной изменчивостью. Мы должны всегда помнить, что выявление значимого эффекта это не одно и то же, что и выявление большого эффекта. В случае очень больших выборок значимым будет считаться даже крошечное расхождение в выборочных средних. В целях более глубокого понимания того, является ли наше открытие значимым и важным, мы так же должны констатировать величину эффекта.

Интервальный индекс d Коэна

Индекс dКоэна это поправка, которую применяется для того, чтобы увидеть, не является ли наблюдавшееся расхождение не просто статистически значимым, но и действительно большим. Как и поправка Бонферрони, она проста:

Здесь Sab это объединенное стандартное отклонение (не объединенная стандартная ошибка) выборок. Она вычисляется аналогично вычислению объединенной стандартной ошибки:

def pooled_standard_deviation(a, b): '''Объединенное стандартное отклонение  (не объединенная стандартная ошибка)''' return sp.sqrt( standard_deviation(a) ** 2 + standard_deviation(b) ** 2)

Так, для варианта под номером 6 дизайна нашего веб-сайта мы можем вычислить индекс dКоэна следующим образом:

def ex_2_28(): '''Вычисление интервального индекса d Коэна  для варианта дизайна веб-сайта под номером 6''' df = load_data('multiple-sites.tsv') groups = df.groupby('site')['dwell-time'] a = groups.get_group(0) b = groups.get_group(6) return (b.mean() - a.mean()) / pooled_standard_deviation(a, b)
0.38913648705499848

В отличие от p-значений, абсолютный порог для индекса d Коэна отсутствует. Считать ли эффект большим или нет частично зависит от контекста, однако этот индекс действительно предоставляет полезную, нормализованную меру величины эффекта. Значения выше 0.5, как правило, считаются большими, поэтому значение 0.38 это умеренный эффект. Он определенно говорит о значительном увеличении времени пребывания на нашем веб-сайте и что усилия, потраченные на обновление веб-сайта, определенно не были бесполезными.

Примеры исходного кода для этого поста находятся в моемрепона Github. Все исходные данные взяты врепозиторииавтора книги.

Резюме

В этой серии постов мы узнали о разнице между описательной и инференциальной статистикой, занимающейся методами статистического вывода. Мы еще раз убедились в важности нормального распределения и центральной предельной теоремы, и научились квантифицировать расхождение с популяциями, используя проверку статистических гипотез на основе z-теста, t-теста и F-теста.

Мы узнали о том, каким именно образом методология инференциальной статистики анализирует непосредственно сами выборки, чтобы выдвигать утверждения о всей популяции в целом, из которой они были отобраны. Мы познакомились с целым рядом методов интервалами уверенности, размножением выборок путем бутстрапирования и проверкой статистической значимости которые помогают разглядеть глубинные параметры популяции. Симулируя многократные испытания, мы также получили представление о трудности проверки статистической значимости в условиях многократных сравнений и увидели, как F-тест помогает решать эту задачу и устанавливать равновесие между ошибками 1-го и 2-го рода.

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

В следующей серии постов, если читатели пожелают, мы применим полученные знания о дисперсии и F-тесте к одиночным выборкам. Мы представим метод регрессионного анализа и воспользуемся им для обнаружения корреляции между переменными в выборке из спортсменов-олимпийцев.

Подробнее..

Мощность статистических тестов на единичный корень

11.12.2020 14:05:39 | Автор: admin
Цель данной статьи поделиться результатами сравнительного исследования мощности статистических тестов на единичные корни Дики-Фуллера (ADF) и Квятковского, Филлипса, Шмидта и Шина (KPSS): в случае около-нестационарных временных рядов тест ADF часто не способен отклонить нулевую гипотезу нестационарности. Это означает, что у теста ADF высокий риск ошибки второго рода, то есть вероятность не отклонить ложную нулевую гипотезу.

В данной статье мы посмотрим, насколько мощны тесты ADF и KPSS. Сгенерируем случайный процесс $y_t$, у которого нет единичного корня (то есть процесс является стационарным), $\phi < 1$:

$y_{t} = \phi y_{t-1} + \varepsilon_{t},$


и посмотрим, насколько различные статистические тесты распознают данный процесс как стационарный, а также на каких именно $\phi$ будет фейлиться тест ADF.

План эксперимента


Для различных значений $y_0$ мы сгенерируем 1000 процессов $y_t$, $t = 0, \dots, T$, где $T = 500$, и посчитаем количество отвергнутых гипотез.

Тест ADF: Истинной моделью является $y_t = y_{t-1} + \varepsilon_t$, где $\varepsilon_t \sim i.i.d$ с нулевым средним и конечной дисперсией $\sigma^2$. Мы оцениваем модель $y_t = \phi y_{t-1} + \varepsilon_t$. Критические значения для тестовой статистики $S = \frac{\hat{\phi} - 1}{\hat{\sigma}_{\hat{\phi}}}$, где $T = 500$, представлены в таблице ниже.
1% 5% 10%
-2.57 -1.94 -1.62

Тест KPSS: Истинной моделью является $y_t = r_t + \varepsilon_t$, где $r_t = r_{t-1} + u_t$, $u_t \sim i.i.d$ с нулевым средним и конечной дисперсией $\sigma^2 = 0$. Мы оцениваем ту же модель с $\sigma^2 > 0$. Критические значения для тестовой статистики множителей Лагранжа, где $T = 500$, представлены в таблице ниже.
1% 5% 10%
0.74 0.46 0.35

Начальное значение $y_0$ влияет на конечное выборочное распределение и в тесте ADF, и в тесте KPSS. На реальном фондовом рынке начальное значение $y_0$ может варьироваться достаточно широко, например, от 0.00215 до 204 100 (в абсолютных величинах). В данной статье мы проанализируем мощность тестов ADF и KPSS для малых значений $y_0$.

Генерация случайных процессов


Начнем с генерации нестационарных случайных процессов при $y_0 = 0$. Во всех последующих таблицах $T = 500$, $\sigma = 1$, а количество генерируемых случайных процессов равно 1000. Генерировать случайные процессы будем в матлабе.

T = 500;count = 1000;epsilon = zeros(T,count);for set = 1 : count    epsilon(:,set) = randn(T,1);endy = zeros(T,count);y(1,:) = 0;for t = 2 : T    y(t,:) = y(t - 1,:) + epsilon(t,:);endfigureplot(y(:,1))title('Simulated RW Process')

На рисунке ниже представлен 1 из 1000 сгенерированных нестационарных случайных процессов, который следует модели случайного блуждания ($\phi = 1$).

Тестирование на разных уровнях значимости


Затем протестируем каждый из сгенерированных случайных процессов тестами ADF и KPSS на различных уровнях значимости (1%, 5% и 10%).

h = zeros(count,1);for set = 1 : count    h(set,1) = adftest(y(:,set),'alpha',0.01);    h(set,2) = adftest(y(:,set));    h(set,3) = adftest(y(:,set),'alpha',0.1);    h(set,4) = kpsstest(y(:,set),'trend',false,'alpha',0.01);    h(set,5) = kpsstest(y(:,set),'trend',false);    h(set,6) = kpsstest(y(:,set),'trend',false,'alpha',0.1);end

Напомню, что методологический подход теста KPSS полностью отличается от подхода теста ADF, главное различие которого следует понимать в перестановке нулевой и альтернативной гипотезой.

В тесте KPSS нулевая гипотеза утверждает, что временной ряд является стационарным, альтернативная гипотеза утверждает наличие нестационарности. Простыми словами, если тест ADF отвечает 1 (true), значит, процесс стационарный. Если тест KPSS отвечает 1 (true), значит, процесс нестационарный.

Соответственно, для того, чтобы посчитать количество рядов, которые выявлены как стационарные тем или иным тестом, нужно воспользоваться следующим кодом.

nnz(h(:,1))nnz(h(:,2))nnz(h(:,3))nnz(~h(:,4))nnz(~h(:,5))nnz(~h(:,6))

Эксперимент для стационарных процессов


Теперь сгенерируем и протестируем стационарные случайные процессы с теми же начальными условиями, что и нестационарные процессы, сгенерированные и протестированные выше. Начнём с $\phi = 0.1$.

phi = 0.1;z = zeros(T,count);z(1,:) = 0;for t = 2 : T    z(t,:) = phi * z(t - 1,:) + epsilon(t,:);endfigureplot(z(:,1))title('Simulated AR(1) Process')

На рисунке ниже представлен 1 из 1000 сгенерированных стационарных случайных процессов, который следует авторегрессионной модели первого порядка ($\phi < 1$).

Протестируем каждый из сгенерированных случайных процессов тестами ADF и KPSS на различных уровнях значимости (1%, 5% и 10%).

zh = zeros(count,1);for set = 1 : count    zh(set,1) = adftest(z(:,set),'alpha',0.01);    zh(set,2) = adftest(z(:,set));    zh(set,3) = adftest(z(:,set),'alpha',0.1);    zh(set,4) = kpsstest(z(:,set),'trend',false,'alpha',0.01);    zh(set,5) = kpsstest(z(:,set),'trend',false);    zh(set,6) = kpsstest(z(:,set),'trend',false,'alpha',0.1);end

Затем посчитаем количество рядов, которые были выявлены как стационарные тем или иным тестом.

nnz(zh(:,1))nnz(zh(:,2))nnz(zh(:,3))nnz(~zh(:,4))nnz(~zh(:,5))nnz(~zh(:,6))

Продолжим тестирование для других значений $\phi$.

Результаты эксперимента


В таблице ниже показано, сколько раз процесс был выявлен как стационарный для различных тестов и различных значений $\phi$. Для $\phi = 1$ количество найденных стационарных процессов соответствует тому, что мы ожидали. Для около-нестационарных процессов $0.9 < \phi < 1$ мы получаем много ложно-положительных ответов от теста ADF. Для $\phi \leq 0.9$ мы можем получить ложно-отрицательный ответ от теста KPSS.
Тест ADF Тест KPSS
$\phi$ 1% 5% 10% 1% 5% 10%
0.1 1000 1000 1000 981 924 868
0.2 1000 1000 1000 961 885 812
0.3 1000 1000 1000 938 834 731
0.4 1000 1000 1000 893 758 642
0.5 1000 1000 1000 831 665 512
0.6 1000 1000 1000 733 516 353
0.7 1000 1000 1000 586 339 186
0.8 1000 1000 1000 349 145 66
0.9 1000 1000 1000 68 17 4
0.95 988 1000 1000 2 0 0
0.975 501 886 981 1 0 0
0.99 79 330 536 1 0 0
0.995 34 155 288 0 0 0
1 8 46 95 0 0 0
1.01 1 4 5 0 0 0

Выводы


Как мы видели, тест Дики-Фуллера не способен различить нестационарные и около-нестационарные временные ряды. Это объясняет, почему не выполняется свойство симметричности отношения коинтеграции примерно для 3% пар.

Мной были проанализированы остатки 8 несимметричных пар на Московской бирже за 2019 год: $\phi$ колебалась от 0.9593 до 0.9716, то есть временной ряд остатков был около-нестационарным.

На практике полезно классифицировать переменные с высокой степенью постоянства во времени (незначительный возврат к среднему) как нестационарные, а переменные со значительной склонностью возврата к среднему как стационарные.

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

Если временной ряд пересекает свой средний уровень, скажем, 10 раз, то эконометрический анализ обнаружит значительный возврат к среднему и, следовательно, сделает вывод о том, что временной ряд является стационарным.

Однако если мы расширим горизонт выборки, то можем получить противоречивые результаты. На более широком временном диапазоне эконометрический анализ может сделать вывод о нестационарности временного ряда.

Существует множество аргументов в пользу рассмотрения единичного корня (стохастического тренда) как удобной эконометрической аппроксимации, а не как глубокого структурного параметра.

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

Такой временной ряд не будет статистически отличаться от нестационарного процесса, и его рассмотрение в качестве стационарной переменной (на небольшой выборке), скорее всего, сделает статистический анализ невалидным и, следовательно, приведет к неверным экономическим выводам.

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

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru