Скачиваний:
0
Добавлен:
06.02.2025
Размер:
936.56 Кб
Скачать

МИНОБРНАУКИ РОССИИ САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА) Кафедра биотехнических систем

ОТЧЕТ по лабораторной работе №1

по дисциплине «Моделирование биологических процессов и систем»

ТЕМА: ВРЕМЕННЫЕ РЯДЫ. РАСЧЕТ СКОЛЬЗЯЩИХ СТАТИСТИК

Вариант 1

Студентка гр. 0501

________________

Слободина Ю.А

Преподаватель

 

Тероева Ю. А.

 

 

 

Санкт-Петербург

2023

ЛАБОРАТОРНАЯ РАБОТА № 1

ВРЕМЕННЫЕ РЯДЫ. РАСЧЕТ СКОЛЬЗЯЩИХ СТАТИСТИК

ЦЕЛЬ РАБОТЫ: изучение влияния размера окна фильтра скользящего среднего на результаты фильтрации (на примере 10-ти

секундного тренда ЧСС).

Задачи: написать код, построить графики.

Основные теоретические положения

Временной ряд (Time Series) – это последовательность значений,

описывающих протекающий во времени процесс и измеренных в последовательные моменты времени (чаще - через равные промежутки).

В этой лабораторной работе на примере анализа 10-тисекундного тренда ЧСС рассмотрим такой метод анализа временных рядов как скользящее среднее (moving average). Он может быть полезен при анализе данных, собранных в результате длительного мониторинга (например, за неделю) или же для визуальной демонстрации наблюдаемых в данных зависимостей.

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

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

1.Простое скользящее среднее (SMA - Simple Moving Average)

2.Взвешенное скользящее среднее (WMA - Weighted Moving Average)

Формула для WMA использует разные веса для точек данных. Как правило, вес уменьшается с каждой точкой. Это позволит уменьшить факт

«отставания от реальности».

Выбор весов зависит от характера динамики исследуемого ряда.

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

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

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

Полный код программы

1. data = CSV.read("hr10.csv", DataFrame)

2.

3. test = collect(Int64, 10:10:100)

4.

5.fs = 0.1 #1 отчет на 10 секунд

6.# вариант 1, то есть наш фрагмент берем через 0.1 ч от начала записи

7.# то есть через 6 минут = 360 секунд

8.begin_ = Int(fs*360)

9.data = data[!,1]

10.data = data[Int(begin_):length(data)] #для графика всего массива

11.#data = data[begin_:66] #для визуализации работы фильтров в увеличенном

масштабе

12.

13.# входной сигнал inp - вектор точек

14.inp = data

15.#inp = test # для проверки на тестовых данных

16.out = fill(0.0, size(inp)) # выход - массив такой же длины

18.#slide_flt_mean_3 = SlideMeanFilter{eltype(inp)}(3)

19.#after_mean_3 = exe(slide_flt_mean_3, inp, out)

21.#out = fill(0.0, size(inp))

23.#slide_flt_mean_6 = SlideMeanFilter{eltype(inp)}(6)

24.#after_mean_6 = exe(slide_flt_mean_6, inp, out)

26.#out = fill(0.0, size(inp))

28.#slide_flt_mean_9 = SlideMeanFilter{eltype(inp)}(9)

29.#after_mean_9 = exe(slide_flt_mean_9, inp, out)

31.#out = fill(0.0, size(inp))

33.#slide_flt_linear_3 = SlideMeanFilter_Linear{eltype(inp)}(3)

34.#after_linear_3 = exe(slide_flt_linear_3, inp, out)

36.#out = fill(0.0, size(inp))

38.#slide_flt_linear_6 = SlideMeanFilter_Linear{eltype(inp)}(6)

39.#after_linear_6 = exe(slide_flt_linear_6, inp, out)

41.#out = fill(0.0, size(inp))

43.#slide_flt_linear_9 = SlideMeanFilter_Linear{eltype(inp)}(9)

44.#after_linear_9 = exe(slide_flt_linear_9, inp, out)

46.plot(inp, label = "inp") # график массива

47.

48.# получение графиков по заданию

49.#plot!(after_mean_3, label = "SMA_3", marker = :circle)

50.#plot!(after_mean_6, label = "SMA_6", marker = :circle)

51.#plot!(after_mean_9, label = "SMA_9", marker = :circle)

53.#plot!(after_linear_3, label = "LWMA_3", marker = :square)

54.#plot!(after_linear_6, label = "LWMA_6", marker = :square)

55.#plot!(after_linear_9, label = "LWMA_9", marker = :square)

Файл "lab-1_p_6.jl"

using CSV using Plots

using DataFrames

mutable struct SlideMeanFilter{T} buf::Vector{T} # кольцевой буфер k::Int # состояние фильтра

need_restart::Bool #маркер инициализации фильтра

# конструктор объектов типа SlideMeanFilterтребуется задать только

размер окна

function SlideMeanFilter{T}(window) where T new(fill(T(0), window - 1), 1, true)

end

end

#функция вызова фильтра (от execute)

#принимает аргумент типа SlideMeanFilter и одну точку сигнала

function exe(obj::SlideMeanFilter{T}, x::T) where T buf, k = obj.buf, obj.k

if obj.need_restart # инициализация на первой точке

#заполняем буфер первой точкой fill!(buf, x)

#отмечаем, что инициализация уже не требуется obj.need_restart = false

end

sum_x = x

#сумма всех элементов в буфере + 1 новая точка for xi in buf

sum_x +=xi

end

#собственно, сам расчет среднего

window = length(buf) + 1 y = sum_x / window

#в буфер записываем новую точку buf[k] = x

k += 1

#@show(buf)

#проверка, не кончился ли буфер

if k > length(buf)

# возвращаемся в его начало k = 1

end

# фиксируем состояние фильтра obj.k = k

return y

end

function exe(obj::SlideMeanFilter{T}, inp::AbstractVector{T}, out::AbstractVector) where T

for i in eachindex(inp) x = inp[i]

y = exe(obj, x) out[i] = y

end

return out

end

Файл «lab-1_p_8.jl»

using CSV using Plots

using DataFrames

mutable struct SlideMeanFilter_Linear{T} buf::Vector{T} # кольцевой буфер need_restart::Bool #маркер инициализации фильтра

# конструктор объектов типа SlideMeanFilterтребуется задать только

размер окна

window::Int

deminator::Int

function SlideMeanFilter_Linear{T}(window) where T deminator = sum(collect(Int64, 1:1:window)) new(fill(T(0), window - 1), true, window, deminator)

end

end

#функция вызова фильтра (от execute)

#принимает аргумент типа SlideMeanFilter и одну точку сигнала

function exe(obj::SlideMeanFilter_Linear{T}, x::T) where T buf = obj.buf

if obj.need_restart # инициализация на первой точке

#заполняем буфер первой точкой fill!(buf, x)

#отмечаем, что инициализация уже не требуется obj.need_restart = false

end

sum_x = x*obj.window #последний элмент умножаем на значение окна, это первое слагаемое

# сумма всех элементов в буфере + 1 новая точка for i in eachindex(buf)

sum_x += i*buf[i]

end

#вычисление среднего

y = sum_x /obj.deminator

temp = buf[2:length(buf)] # делаем срез от буфера со второго значения

и до конца

append!(temp, x) #добавляем х, получили новый буфер, "движение" окна по значениям

obj.buf = temp #обновляем буфер return y

end

function exe(obj::SlideMeanFilter_Linear{T}, inp::AbstractVector{T}, out::AbstractVector) where T

for i in eachindex(inp) x = inp[i]

y = exe(obj, x) out[i] = y

end return out

end

Файл «linear_v2.jl»

using CSV using Plots

using DataFrames

mutable struct SlideMeanFilter_lin_2{T} buf::Vector{T} # кольцевой буфер k::Int # состояние фильтра

need_restart::Bool #маркер инициализации фильтра window::Int

deminator::Int

# конструктор объектов типа SlideMeanFilterтребуется задать только

размер окна

function SlideMeanFilter_lin_2{T}(window) where T deminator = sum(collect(Int64, 1:1:window))

new(fill(T(0), window - 1), 1, true, window, deminator)

end

end

#функция вызова фильтра (от execute)

#принимает аргумент типа SlideMeanFilter и одну точку сигнала

function exe(obj::SlideMeanFilter_lin_2{T}, x::T) where T buf, k = obj.buf, obj.k

if obj.need_restart # инициализация на первой точке

#заполняем буфер первой точкой fill!(buf, x)

#отмечаем, что инициализация уже не требуется obj.need_restart = false

end

sum_x = x*obj.window

coeff = length(buf) - k + 1 #поправочный коэффициент для расчета линейного веса

# сумма всех элементов в буфере + 1 новая точка for i in eachindex(buf)

w = i + coeff # вычисление веса

if w > length(buf)

w = w - length(buf) # поправка с учетом кругового буфера

end

sum_x +=w * buf[i]

end

# собственно, сам расчет среднего

y = sum_x / obj.deminator

#в буфер записываем новую точку buf[k] = x

k += 1

#@show(buf)

#проверка, не кончился ли буфер if k > length(buf)

# возвращаемся в его начало k = 1

end

# фиксируем состояние фильтра obj.k = k

return y

end

function exe(obj::SlideMeanFilter_lin_2{T}, inp::AbstractVector{T}, out::AbstractVector) where T

for i in eachindex(inp) x = inp[i]

y = exe(obj, x) out[i] = y

end

return out end

Полученные графики

На рисунках 1-6 представлен входной сигнал и сигнал после разных видов скользящего среднего.

Рисунок 1 – График всего сигнала и после SMA с окном 9

Рисунок 2 – График сигнала и после SMA с окнами 3, 6, 9

Рисунок 3 – График сигнала и после LWMA с окнами 3, 6, 9

Рисунок 4 – График сигнала и после SMA и LWMA с окном 3

Соседние файлы в предмете Моделирование биологических процессов и сетей