Аналіз зі складними даними, що-небудь інше?


31

Скажімо, наприклад, ви робите лінійну модель, але дані є складними.у

у=хβ+ϵ

Мій набір даних є складним, оскільки всі числа у мають вигляд . Чи є щось процедурно інше при роботі з такими даними?( a + b i )у(а+бi)

Я прошу, бо ви отримаєте складні коваріаційні матриці та випробуєте статистику, яка складно оцінюється.

Чи потрібно використовувати сполучені транспозити замість транспозитів, роблячи найменші квадрати? чи має значення комплексна коваріація?


3
Розгляньте складне число як дві окремі змінні, і таким чином видаліть i з усіх ваших рівнянь. Інакше це буде кошмар ...
sashkello

Будь-яка інформація про x чи β ?
Стийн

3
@Sashkello Що таке "кошмар"? Розміри зменшуються вдвічі, коли ви використовуєте складні числа, тому, можливо, це спрощення. Більше того, ви перетворили біваріантний DV в універсальний DV, що є величезною перевагою. PeterRabbit: так, потрібні суміжні транспозити. Складна коваріаційна матриця є ермітовою позитивно-визначеною. Як і його справжній аналог, він все ще має позитивні реальні власні значення, що стосується питання значимості.
whuber

2
@whuber Для мене немає сенсу входити в складні числа, якщо проблема як показано. Робити складні числа не простіше - інакше тут взагалі не виникне питання. Не все вийде добре зі складними числами, і це не є простою зміною, якщо ви не знаєте, що робите. Трансформація цієї проблеми в реальному просторі рівнозначна , і ви можете застосовувати всю різноманітність статистичних прийомів тоді, не переживаючи, працює вона чи ні у складному просторі.
сашкелло

1
@whuber Хороша відповідь і приємне пояснення. Я б сказав, як тільки ти
перейдеш

Відповіді:


40

Підсумок

Узагальнення регресії найменших квадратів до складних змінних є простим, що складається, головним чином, із заміни матричних транспозитів кон'югованими транспозитами у звичайних матричних формулах. Однак комплексна регресія відповідає складній багатоваріантній множинній регресії, рішення якої було б набагато складніше отримати за допомогою стандартних (реальної змінної) методи. Таким чином, коли складнозначна модель має сенс, настійно рекомендується використовувати складну арифметику для отримання рішення. Ця відповідь також включає деякі запропоновані способи відображення даних та подання діагностичних діаграм придатності.


Для простоти обговоримо випадок звичайної (універсальної) регресії, яку можна записати

zj=β0+β1шj+εj.

Я взяв на себе назву незалежної змінної і залежної змінної Z , яка є звичайною (див., Наприклад, Lars Ahlfors, комплексний аналіз ). Все, що випливає далі, прямо для того, щоб поширитись на параметри множинної регресії.WZ

Інтерпретація

Ця модель має легко візуалізувати геометричну інтерпретацію: множення на буде перемасштабіровать ш J по модулю р 1 і повернути його навколо початку координат з допомогою аргументу р 1 . Згодом додавання β 0 переводить результат на цю кількість. Ефект ε j полягає в тому, щоб трохи "затребувати" цей переклад. Таким чином, регресування z j на w j таким чином є зусиллям для розуміння набору 2D точок ( z j )β1 шjβ1β1β0εjzjшj(zj)як виникає із сузір'я 2D точок завдяки такому перетворенню, що допускає деяку помилку в процесі. Це проілюстровано нижче малюнком під назвою "Придатність як перетворення".(шj)

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

Звичайні найменші квадрати

Щоб з'єднати складний випадок з реальним випадком, напишемо

для значень залежної змінної таzj=хj+iуj

для значень незалежної змінної.шj=уj+ivj

Крім того, для параметрів запишіть

і β 1 = γ 1 + i δ 1 . β0=γ0+iδ0β1=γ1+iδ1

Кожен з нових введених термінів, звичайно, реальний, і є уявним, тоді як j = 1 , 2 , , n індексує дані.i2=-1j=1,2,,н

МНК знахідки р 0 і β 1 , що мінімізує суму квадратів відхилень,β^0β^1

j=1n||zj(β^0+β^1wj)||2=j=1n(z¯j(β^0¯+β^1¯w¯j))(zj(β^0+β^1wj)).

Формально це ідентично звичайній матричній композиції: порівняйте її з Єдина відмінність, яку ми знаходимо, полягає в тому, що транспозиція проектної матриці X ' замінюється кон'югатом транспозиції X = ˉ X . Отже, формальне рішення матриці є(z-Хβ)'(z-Хβ).Х' Х=Х¯'

β^=(ХХ)-1Хz.

У той же час, щоб побачити, що може бути досягнуто шляхом внесення цього завдання до чисто реальної змінної проблеми, ми можемо написати ціль OLS з точки зору реальних компонентів:

j=1н(хj-γ0-γ1уj+δ1vj)2+j=1н(уj-δ0-δ1уj-γ1vj)2.

Очевидно, це представляє дві пов'язані реальні регресії: одна з них регресує на u і v , інша регресує y на u і v ; і нам потрібно, щоб коефіцієнт v для x був від'ємним коефіцієнтом u для у, а коефіцієнт u для х рівний коефіцієнту v для у . Більше того, тому що загальнийхуvууvvхууухvуквадрати залишків від двох регресій мають бути зведені до мінімуму, зазвичай це не буде так, що будь-який набір коефіцієнтів дає найкращу оцінку лише для або y . Це підтверджено в прикладі нижче, в якому дві реальні регресії здійснюють окремо і порівнюють їх рішення зі складною регресією.ху

Цей аналіз робить очевидним, що переписання складної регресії з точки зору реальних частин (1) ускладнює формули, (2) затьмарює просту геометричну інтерпретацію і (3) потребує узагальненої багатовимірної множинної регресії (з нетривіальними кореляціями між змінними ) вирішувати. Ми можемо зробити краще.

Приклад

Як приклад, я беру сітку значень в цілісних точках, що знаходяться поблизу від початку в складній площині. До перетворених значень w β додаються iid помилки, що мають двовимірний гауссовий розподіл: зокрема, реальна та уявна частини помилок не є незалежними.шшβ

Важко намалювати звичайний розсіювач для складних змінних, оскільки він складався б з точок у чотирьох вимірах. Натомість ми можемо переглянути матрицю розсіювання їх реальних та уявних частин.(шj,zj)

Матриця Scatterplot

На даний момент проігноруйте відповідність і подивіться на чотири верхні рядки та чотири ліві стовпці: вони відображають дані. Кругла сітка видно в лівій верхній частині; вона має 81 бал. Розсіювання компонентів w проти компонентів z показують чіткі кореляції. Три з них мають негативні кореляції; тільки y (уявна частина z ) і u (реальна частина w ) позитивно корелюються.ш81шzуzуш

Для отримання цих даних, справжнє значення є ( - 20 + 5 я , - 3 / 4 + 3 / 4 β. Він являє собою розширення,3/2і обертання проти годинникової стрілки на 120 градусівнаступним перекладом20одиниць зліва і5одиниць вгору. Я обчислюю три підходи: складне рішення з найменшими квадратами та два рішення OLS для(xj)та(yj)окремо для порівняння.(20+5i,3/4+3/43i)3/2205(хj)(уj)

Fit            Intercept          Slope(s)
True           -20    + 5 i       -0.75 + 1.30 i
Complex        -20.02 + 5.01 i    -0.83 + 1.38 i
Real only      -20.02             -0.75, -1.46
Imaginary only          5.01       1.30, -0.92

Завжди буде так, що перехоплення, що реалізується лише для реального, погоджується з реальною частиною складного перехоплення, а уявний лише перехоплення узгоджується з уявною частиною складного перехоплення. Вочевидь, однак, що реальні і уявні лише схили не узгоджуються зі складними коефіцієнтами схилу, ані між собою, точно так, як передбачено.

Давайте докладніше розглянемо результати комплексу. По-перше, сюжет залишків дає нам вказівку на їх двобічне гауссове поширення. (Базовий розподіл має граничні стандартні відхилення та кореляцію 0,8 . Тоді ми можемо побудувати величини залишків (представлені розмірами кругових символів) та їх аргументи (представлені кольорами точно так само, як у першому сюжеті) проти встановлених значень: цей графік повинен виглядати як випадковий розподіл розмірів і кольорів, який він робить.20,8

Залишковий сюжет

Нарешті, ми можемо зобразити пристосування кількома способами. Примітка з'явилася в останніх рядках і стовпцях матриці розсіювання ( qv ) і, можливо, варто детальніше ознайомитися з цією точкою. Зліва зліва фігурують у вигляді відкритих синіх кружечків, а стрілки (що представляють собою залишки) з'єднують їх із даними, зображеними як суцільні червоні кола. Праворуч зображені як відкриті чорні кола, заповнені кольорами, що відповідають їх аргументам; вони з'єднані стрілками до відповідних значень ( z j ) . Нагадаємо , що кожна стрілка представляє собою розширення, 3 / 2 навколо початку координат, поворот на 120(шj)(zj)3/2120градусів і переклад на , плюс та двозначна помилка Гаасія.(-20,5)

Підходять як перетворення

Ці результати, графіки та діагностичні діаграми свідчать про те, що складна формула регресії працює правильно і досягає чогось іншого, ніж окремі лінійні регресії реальних та уявних частин змінних.

Код

RКод для створення даних, припадки, і ділянки , наводиться нижче. Слід зазначити , що фактичне рішення р виходить в одному рядку коду. Додаткова робота - але не надто велика - потрібна для отримання звичайних найменших квадратів: матриця дисперсії та коваріації пристосування, стандартні помилки, значення p тощо.β^

#
# Synthesize data.
# (1) the independent variable `w`.
#
w.max <- 5 # Max extent of the independent values
w <- expand.grid(seq(-w.max,w.max), seq(-w.max,w.max))
w <- complex(real=w[[1]], imaginary=w[[2]])
w <- w[Mod(w) <= w.max]
n <- length(w)
#
# (2) the dependent variable `z`.
#
beta <- c(-20+5i, complex(argument=2*pi/3, modulus=3/2))
sigma <- 2; rho <- 0.8 # Parameters of the error distribution
library(MASS) #mvrnorm
set.seed(17)
e <- mvrnorm(n, c(0,0), matrix(c(1,rho,rho,1)*sigma^2, 2))
e <- complex(real=e[,1], imaginary=e[,2])
z <- as.vector((X <- cbind(rep(1,n), w)) %*% beta + e)
#
# Fit the models.
#
print(beta, digits=3)
print(beta.hat <- solve(Conj(t(X)) %*% X, Conj(t(X)) %*% z), digits=3)
print(beta.r <- coef(lm(Re(z) ~ Re(w) + Im(w))), digits=3)
print(beta.i <- coef(lm(Im(z) ~ Re(w) + Im(w))), digits=3)
#
# Show some diagnostics.
#
par(mfrow=c(1,2))
res <- as.vector(z - X %*% beta.hat)
fit <- z - res
s <- sqrt(Re(mean(Conj(res)*res)))
col <- hsv((Arg(res)/pi + 1)/2, .8, .9)
size <- Mod(res) / s
plot(res, pch=16, cex=size, col=col, main="Residuals")
plot(Re(fit), Im(fit), pch=16, cex = size, col=col,
     main="Residuals vs. Fitted")

plot(Re(c(z, fit)), Im(c(z, fit)), type="n",
     main="Residuals as Fit --> Data", xlab="Real", ylab="Imaginary")
points(Re(fit), Im(fit), col="Blue")
points(Re(z), Im(z), pch=16, col="Red")
arrows(Re(fit), Im(fit), Re(z), Im(z), col="Gray", length=0.1)

col.w <-  hsv((Arg(w)/pi + 1)/2, .8, .9)
plot(Re(c(w, z)), Im(c(w, z)), type="n",
     main="Fit as a Transformation", xlab="Real", ylab="Imaginary")
points(Re(w), Im(w), pch=16, col=col.w)
points(Re(w), Im(w))
points(Re(z), Im(z), pch=16, col=col.w)
arrows(Re(w), Im(w), Re(z), Im(z), col="#00000030", length=0.1)
#
# Display the data.
#
par(mfrow=c(1,1))
pairs(cbind(w.Re=Re(w), w.Im=Im(w), z.Re=Re(z), z.Im=Im(z),
            fit.Re=Re(fit), fit.Im=Im(fit)), cex=1/2)

β^у

Якщо все було обчислено правильно, коваріація все одно буде визначеною позитивно. Зокрема, це означає, що коли ви будете використовувати його для обчислення коваріації або реальної частини, або уявної частини змінної, ви отримаєте додатне число, тому всі CI будуть чітко визначені.
whuber

β^

Крім того, якщо я обчислюю значення для тестової статистики, я отримую числа, наприклад, 3 + .1 * i. Для цього я очікував, що номер не має уявної частини. Це нормально? Або знак, що я роблю щось не так?
bill_e

Коли ви обчислюєте статистику тестів зі складними числами, слід очікувати отримання складних результатів! Якщо у вас є математична причина, чому статистика повинна бути реальною, то обчислення має бути помилковим. Коли уявна частина дійсно крихітна порівняно з реальною частиною, ймовірно, накопичена помилка з плаваючою комою, і зазвичай безпечно її вбити ( zapsmallв R). Інакше це знак, що щось принципово не так.
whuber

5

Після приємного довгого пошуку в Google, я знайшов релевантну інформацію щодо розуміння проблеми альтернативно. Виявляється, подібні проблеми дещо зустрічаються в статистичній обробці сигналів. Замість того, щоб починати з гауссової ймовірності, яка відповідає лінійним найменшим квадратам для реальних даних, починається з:

http://en.wikipedia.org/wiki/Complex_normal_distribution

Ця сторінка з вікіпедії дає задовільний пробіг щодо цього об’єкта.

β^

Ще одне джерело, яке я знайшов, що доходить до того ж висновку, що і whuber, але досліджує інші оцінки, такі як максимальна ймовірність, це: "Оцінки неправильних лінійних моделей регресії", від Yan et al.


1

Хоча у @whuber є гарно проілюстрована і добре пояснена відповідь, я думаю, що це спрощена модель, яка втрачає частину потужності складного простору.

шβх

z=β0+β1ш+ϵ

ϵ

Я пропоную визначити складну лінійну регресію так:

z=β0+β1ш+β2ш¯+ϵ

Є дві основні відмінності.

β2

ϵ

Повернувшись до реальної моделі, звичайне рішення з найменшими квадратами виходить з мінімізацією втрат, що є негативною ймовірністю журналу. Для нормального розподілу це парабола:

у=ах2+cх+г.

х=z-(β0+β1ш)аcг

у=а|х|2+(бх2+cх)+г.

і d дорівнюють нулю, як і раніше. a - кривизна і b - "псевдокривизна". бcгабб

[х-мкх-мк¯]Н[суу¯с¯]-1[х-мкх-мк¯]+г
с,у,мк,гсумк

Ось зображення складної нормальної густини розподілу:

Щільність складного одновимірного нормального розподілу

б

Це ускладнює регресію, хоча я впевнений, що рішення все ще є аналітичним. Я вирішив це для випадку одного входу, і я радий переписати тут своє рішення, але у мене є відчуття, що Біг може вирішити загальну справу.


Дякую за цей внесок. Я не дотримуюся цього, тому що я не впевнений (а) чому ви вводите квадратичний многочлен, (б) що ви насправді маєте на увазі під "відповідним" многочленом, або (в) якою статистичною моделлю ви підходите. Чи зможете ви детальніше розглянути ці питання?
whuber

@whuber Я переписав це як статистичну модель. Будь ласка, дайте мені знати, чи має сенс для вас.
Ніл Г

zшш¯ϵ

\ Бета-версія2

|х|2х2

1

Це питання знову виникло на Mathematica StackExchange, і моя відповідь / розширений коментар є, що слід дотримуватися відмінної відповіді @whuber.

Моя відповідь тут - це спроба трохи поширити відповідь @whuber, зробивши структуру помилок трохи більш явною. Запропонований оцінювач найменших квадратів - це те, що можна було б використовувати, якщо біваріантний розподіл помилок має нульову кореляцію між реальною та уявною складовими. (Але створені дані мають кореляцію помилок 0,8.)

ρ=0ρ0

Оцінювач даних і найменших квадратів

ρ=0

Максимальна оцінка ймовірності, якщо rho дорівнює нулю

ρ=0

ρ

Максимальна оцінка ймовірності, включаючи rho

γ0δ0ργ1

Моя думка у всьому цьому полягає в тому, що відповідна модель повинна бути зроблена повністю чітко і що символічні програми з алгебри можуть допомогти полегшити безладдя. (І, звичайно, оцінювачі максимальної вірогідності передбачають двовимірне нормальне розподіл, якого не передбачають оцінки найменших квадратів.)

Додаток: Повний код математики

(* Predictor variable *)
w = {0 - 5 I, -3 - 4 I, -2 - 4 I, -1 - 4 I, 0 - 4 I, 1 - 4 I, 2 - 4 I,
    3 - 4 I, -4 - 3 I, -3 - 3 I, -2 - 3 I, -1 - 3 I, 0 - 3 I, 1 - 3 I,
    2 - 3 I, 3 - 3 I, 4 - 3 I, -4 - 2 I, -3 - 2 I, -2 - 2 I, -1 - 2 I,
    0 - 2 I, 1 - 2 I, 2 - 2 I, 3 - 2 I, 
   4 - 2 I, -4 - 1 I, -3 - 1 I, -2 - 1 I, -1 - 1 I, 0 - 1 I, 1 - 1 I, 
   2 - 1 I, 3 - 1 I, 
   4 - 1 I, -5 + 0 I, -4 + 0 I, -3 + 0 I, -2 + 0 I, -1 + 0 I, 0 + 0 I,
    1 + 0 I, 2 + 0 I, 3 + 0 I, 4 + 0 I, 
   5 + 0 I, -4 + 1 I, -3 + 1 I, -2 + 1 I, -1 + 1 I, 0 + 1 I, 1 + 1 I, 
   2 + 1 I, 3 + 1 I, 4 + 1 I, -4 + 2 I, -3 + 2 I, -2 + 2 I, -1 + 2 I, 
   0 + 2 I, 1 + 2 I, 2 + 2 I, 3 + 2 I, 
   4 + 2 I, -4 + 3 I, -3 + 3 I, -2 + 3 I, -1 + 3 I, 0 + 3 I, 1 + 3 I, 
   2 + 3 I, 3 + 3 I, 4 + 3 I, -3 + 4 I, -2 + 4 I, -1 + 4 I, 0 + 4 I, 
   1 + 4 I, 2 + 4 I, 3 + 4 I, 0 + 5 I};
(* Add in a "1" for the intercept *)
w1 = Transpose[{ConstantArray[1 + 0 I, Length[w]], w}];

z = {-15.83651 + 7.23001 I, -13.45474 + 4.70158 I, -13.63353 + 
    4.84748 I, -14.79109 + 4.33689 I, -13.63202 + 
    9.75805 I, -16.42506 + 9.54179 I, -14.54613 + 
    12.53215 I, -13.55975 + 14.91680 I, -12.64551 + 
    2.56503 I, -13.55825 + 4.44933 I, -11.28259 + 
    5.81240 I, -14.14497 + 7.18378 I, -13.45621 + 
    9.51873 I, -16.21694 + 8.62619 I, -14.95755 + 
    13.24094 I, -17.74017 + 10.32501 I, -17.23451 + 
    13.75955 I, -14.31768 + 1.82437 I, -13.68003 + 
    3.50632 I, -14.72750 + 5.13178 I, -15.00054 + 
    6.13389 I, -19.85013 + 6.36008 I, -19.79806 + 
    6.70061 I, -14.87031 + 11.41705 I, -21.51244 + 
    9.99690 I, -18.78360 + 14.47913 I, -15.19441 + 
    0.49289 I, -17.26867 + 3.65427 I, -16.34927 + 
    3.75119 I, -18.58678 + 2.38690 I, -20.11586 + 
    2.69634 I, -22.05726 + 6.01176 I, -22.94071 + 
    7.75243 I, -28.01594 + 3.21750 I, -24.60006 + 
    8.46907 I, -16.78006 - 2.66809 I, -18.23789 - 
    1.90286 I, -20.28243 + 0.47875 I, -18.37027 + 
    2.46888 I, -21.29372 + 3.40504 I, -19.80125 + 
    5.76661 I, -21.28269 + 5.57369 I, -22.05546 + 
    7.37060 I, -18.92492 + 10.18391 I, -18.13950 + 
    12.51550 I, -22.34471 + 10.37145 I, -15.05198 + 
    2.45401 I, -19.34279 - 0.23179 I, -17.37708 + 
    1.29222 I, -21.34378 - 0.00729 I, -20.84346 + 
    4.99178 I, -18.01642 + 10.78440 I, -23.08955 + 
    9.22452 I, -23.21163 + 7.69873 I, -26.54236 + 
    8.53687 I, -16.19653 - 0.36781 I, -23.49027 - 
    2.47554 I, -21.39397 - 0.05865 I, -20.02732 + 
    4.10250 I, -18.14814 + 7.36346 I, -23.70820 + 
    5.27508 I, -25.31022 + 4.32939 I, -24.04835 + 
    7.83235 I, -26.43708 + 6.19259 I, -21.58159 - 
    0.96734 I, -21.15339 - 1.06770 I, -21.88608 - 
    1.66252 I, -22.26280 + 4.00421 I, -22.37417 + 
    4.71425 I, -27.54631 + 4.83841 I, -24.39734 + 
    6.47424 I, -30.37850 + 4.07676 I, -30.30331 + 
    5.41201 I, -28.99194 - 8.45105 I, -24.05801 + 
    0.35091 I, -24.43580 - 0.69305 I, -29.71399 - 
    2.71735 I, -26.30489 + 4.93457 I, -27.16450 + 
    2.63608 I, -23.40265 + 8.76427 I, -29.56214 - 2.69087 I};

(* whuber 's least squares estimates *)
{a, b} = Inverse[ConjugateTranspose[w1].w1].ConjugateTranspose[w1].z
(* {-20.0172+5.00968 \[ImaginaryI],-0.830797+1.37827 \[ImaginaryI]} *)

(* Break up into the real and imaginary components *)
x = Re[z];
y = Im[z];
u = Re[w];
v = Im[w];
n = Length[z]; (* Sample size *)

(* Construct the real and imaginary components of the model *)
(* This is the messy part you probably don't want to do too often with paper and pencil *)
model = \[Gamma]0 + I \[Delta]0 + (\[Gamma]1 + I \[Delta]1) (u + I v);
modelR = Table[
   Re[ComplexExpand[model[[j]]]] /. Im[h_] -> 0 /. Re[h_] -> h, {j, n}];
(* \[Gamma]0+u \[Gamma]1-v \[Delta]1 *)
modelI = Table[
   Im[ComplexExpand[model[[j]]]] /. Im[h_] -> 0 /. Re[h_] -> h, {j, n}];
(* v \[Gamma]1+\[Delta]0+u \[Delta]1 *)

(* Construct the log of the likelihood as we are estimating the parameters associated with a bivariate normal distribution *)
logL = LogLikelihood[
   BinormalDistribution[{0, 0}, {\[Sigma]1, \[Sigma]2}, \[Rho]],
   Transpose[{x - modelR, y - modelI}]];

mle0 = FindMaximum[{logL /. {\[Rho] -> 
      0, \[Sigma]1 -> \[Sigma], \[Sigma]2 -> \[Sigma]}, \[Sigma] > 
    0}, {\[Gamma]0, \[Delta]0, \[Gamma]1, \[Delta]1, \[Sigma]}]
(* {-357.626,{\[Gamma]0\[Rule]-20.0172,\[Delta]0\[Rule]5.00968,\[Gamma]1\[Rule]-0.830797,\[Delta]1\[Rule]1.37827,\[Sigma]\[Rule]2.20038}} *)

(* Now suppose we don't want to restrict \[Rho]=0 *)
mle1 = FindMaximum[{logL /. {\[Sigma]1 -> \[Sigma], \[Sigma]2 -> \[Sigma]}, \[Sigma] > 0 && -1 < \[Rho] < 
     1}, {\[Gamma]0, \[Delta]0, \[Gamma]1, \[Delta]1, \[Sigma], \[Rho]}]
(* {-315.313,{\[Gamma]0\[Rule]-20.0172,\[Delta]0\[Rule]5.00968,\[Gamma]1\[Rule]-0.763237,\[Delta]1\[Rule]1.30859,\[Sigma]\[Rule]2.21424,\[Rho]\[Rule]0.810525}} *)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.