Фільтр Калмана, керівництво повного ідіота, про програмування, алгоритмах і не тільки
Фільтр Калмана, керівництво повного ідіота

Отже, що ж таке фільтр Калмана. Припустимо у вас є якась величина X змінюється в часі. У вас є якийсь прилад, що вимірює величину X з деякою погрішністю. Ви хочете оцінити, чого насправді дорівнює величина X. Наприклад, в разі акцій Xk може бути істинною ціною акції в момент часу k (вона визначається доходами компанії, курсом валют, очікуваннями інвесторів ітп). У нас є тільки один спосіб виміряти цю величину - піти на біржу і подивитися котирування. Але котирування на біржі схильні до впливу багатьох чинників, ціни коливаються в широкому діапазоні і виміряна величина Yk може відрізнятися від Xx. Алгоритм Калмана дозволяє нам оцінити справжнє значення Xk на основі історії зміни вимірюваної величини Yk. При цьому, природно, робиться ряд припущень про зв'язок між Y і X і характер зміни X.
Припущення номер 1
Тобто величина X в момент часу k являє собою лінійну комбінацію величини X в минулий момент часу, керуючого сигналу U і шуму W. В реальних задачах часто керуючий сигнал U відсутня.
Що таке керуючий сигнал? Повернемося до нашого прикладу з акціями. Припустимо, що ФРС США активно друкує гроші, наприклад 600 млрд доларів, ці гроші ллються широкою рікою на ринок і неминуче рухають ціни акцій вгору. Це і є керуючий сигнал.
Але повернемося до нашої формулою, нам буде потрібно зробити ще одне важливе уточнення. Шум w повинен мати нормальний розподіл з дисперсією dW. На практиці, часто так воно і є, тут на руку нам грає центральна гранична теорема. адже шум це, як правило, сукупність величезної кількості невідомих чинників.
Припущення номер 2
Тобто наша вимірювана величина Y це лінійна комбінація реальної величини X і похибки вимірювання V. При цьому, робиться додаткове припущення що похибка вимірювання теж має нормальний розподіл зі своєю дисперсією dV. Дуже часто на практиці H = 1.
Що ми тільки що зробили? Ми побудували модель, що описує нашу систему, при цьому, зауважте, поки ніякого фільтра Калмана не згадувалося.
Що ми хочемо зробити?
Ми хочемо отримати якесь рівняння
що дозволяє нам оцінювати справжнє значення X виходячи з історичних оцінок і вимірюваних величин. Прискіпливий Новомосковсктель помітить, що тут я непослідовно використовую X, дійсно раніше я використовував X для позначення істинного значення величини, а тепер для оцінки істинного значення. Це важливий момент, адже реально істинного значення ми ніколи не зможемо дізнатися. Я просто намагаюся не захаращувати формули новими сутностями.
Далі зазвичай йдуть багатосторінкові математичні викладки, що включають в себе взяття приватних похідних, екстраполяції, корекції. Опустимо все це, хто цікавиться легко знайдуть масу матеріалу в гуглі. Зрештою, виходить вираз для оцінки X:
Де Kk - це Калмановский коефіцієнт посилення. Саме цю величину, в процесі роботи і визначає алгоритм фільтра Калмана. При цьому фільтр Калмана знаходить оптимальну величину коефіцієнта посилення при заданих дисперсіях dW і dV. Чим краще ви оціните ці дисперсії, тим краще буде працювати фільтр Калмана.
А тепер, уявіть, що X і Y це не одномірні величини, а вектор. A, B і H - матриці. Похибка і шум V і W теж вектори. Виявляється, що при цьому, все рівняння будуть працювати точно так само, і алгоритм фільтра Калмана легко узагальнюється на багатовимірні величини.
А тепер, за традицією, приклад на R
Фільтр Калмана можна знайти в декількох модулях R, для прикладу я буду використовувати реалізацію з модуля dlm. В даному прикладі ми застосуємо фільтр Калмана до значень індексу S-P500.
Припустимо, що керуючого сигналу немає, це звичайно, насправді, не так, але оцінка керуючого сигналу це окреме завдання. Крім того, окремими завданнями є оцінки параметрів дисперсій dV і dW. Для нашого прикладу я просто підібрав деякі значення емпіричним шляхом. Якщо ж підійти до цього завдання грунтовно, то їх цілком можна оцінити виходячи з волатильності на ринку.
Для порівняння, на графік, зеленим кольором, було додано 10-денний експоненціальне ковзне середнє Вийшла картинка:

Велике спасибі Новомосковсктелю по імені Kirill за знайдену в коді прикладу помилку.
SergE San Francisco, California, United States Hi, I am a senior software engineer in a big web company. Mainly interested in data mining and machine learning. My 'native' programming language is Java, though I believe Haskell and FP in general is better. I have decent experience with C # and .Net stack as well. In my spare time I'm happy to compete with smart people on Topcoder and Kaggle. My TC profile is here. Kaggle profile here If you want to talk, just send a message: e d u n o v @ g m a i l. c o m View my complete profile