diff --git a/TimeSeriesApp/App_descriptions_streamlit.py b/TimeSeriesApp/App_descriptions_streamlit.py index fd0e80f..61ea2a0 100644 --- a/TimeSeriesApp/App_descriptions_streamlit.py +++ b/TimeSeriesApp/App_descriptions_streamlit.py @@ -21,4 +21,22 @@ def convert_df(df): def intro_text(): with st.expander("О комплексе?"): - st.write("Комплекс разработан для работы с временными рядами метеорологических данных. Он позволяет совершить предобаботку ряда, а также его анализ и прогнозирование используя один из представленных в боковом меню методов. Комплекс доступен для запуска с любого устройства онлайн по ссылке https://time-series-msu-ff.streamlit.app/") + st.write( + "Комплекс разработан для работы с временными рядами метеорологических данных. Он позволяет совершить предобаботку ряда, а также его анализ и прогнозирование используя один из представленных в боковом меню методов. Комплекс доступен для запуска с любого устройства онлайн по ссылке https://time-series-msu-ff.streamlit.app/" + ) + + +def preprocessing(): + st.write( + "На этапе предобработки ряда мы можем выявить пропуски в данных, проверить ряд на стационарность и провести его сглаживание" + ) + + +def stationar_test(): + st.write( + "Проводится стандартный тест Дики-Фуллера (DF-тест), который является статистическим методом, применяемым для проверки стационарности временных рядов. Он используется для определения наличия единичного корня в ряде, что указывает на его нестационарность. \n Получаемый параметр p-value является уровнем значимости гипотезы. Если он не выходит за пределы 5%, то мы считаем наш ряд стационарным." + ) + +def moving_average(): + st.write("Сглаживание позволяет устранить шумы и случайные колебания. Оно реализуется методом скользящего среднего. Его суть заключается в преобразовании исходного ряда в новый, где каждое значение является средним арифметическим значений в окне заданной ширины") + st.latex(r''' MA(t) = \frac{1}{2n+1} \sum_{i=t-n}^{t+n} y_i''') \ No newline at end of file diff --git a/TimeSeriesApp/Time_Series_App.py b/TimeSeriesApp/Time_Series_App.py index ada537b..cdd4303 100644 --- a/TimeSeriesApp/Time_Series_App.py +++ b/TimeSeriesApp/Time_Series_App.py @@ -83,7 +83,7 @@ def df_chart_display_iloc(df, data_col_iloc): # trigonometric_args = [S_1_coef, S_1_freq, S_2_coef, S_2_freq, S_3_coef, S_3_freq, C_1_coef, C_1_freq, C_2_coef, C_2_freq, C_3_coef, C_3_freq] st.title("Комплекс для работы с временными ря дами") -st.sidebar.header("Первичная обработка ряда") +st.sidebar.header("Выбор временного ряда для обработки") txt.intro_text() @@ -104,7 +104,7 @@ def df_chart_display_iloc(df, data_col_iloc): if data_radio == "": if st.session_state.final_dataframe.empty: - st.warning("Отсутствует ряд для анализа") + st.warning("Отсутствует ряд для анализа. Загрузите или сгененируйте его в боковом меню.") # st.sidebar.write('Ожидается ответ от пользователя...') st.stop() else: @@ -112,6 +112,8 @@ def df_chart_display_iloc(df, data_col_iloc): if data_radio == "Загруженный ряд": + st.sidebar.info('Важно, чтобы временной индекс был в одной колонке в файле!', icon="ℹ️") + upload_file = st.sidebar.file_uploader(label="Загрузите файл CSV", type="CSV") if upload_file == None: st.stop() @@ -144,6 +146,8 @@ def df_chart_display_iloc(df, data_col_iloc): "Выберите параметры для генерируемого ряда", paramName_default ) + + paramDict_default = {paramName_default[i]: 0 for i in range(len(paramName_default))} # paramDict_default @@ -159,8 +163,10 @@ def df_chart_display_iloc(df, data_col_iloc): time_series = syntetic_time_series(date_range, **paramDict_default) +st.write("---") #Вставка разделителя + # Отображение ряда -"Исходный временной ряд" +st.subheader("Исходный временной ряд") df_chart_display_loc( time_series, data_col_loc=time_series.select_dtypes(include=["int", "float"]).columns, @@ -171,6 +177,11 @@ def df_chart_display_iloc(df, data_col_iloc): # НАДО ПОНЯТЬ, КАК ИЗБЕГАТ ОШИБКУ ВЕЗДЕ, ПОКА Я ЕЩЕ НЕ ЗАРУЗИЛ ДАННЫЕ, А НЕ ПИСАТЬ ВЕЗДЕ if != None + +st.sidebar.header("Предобработка ряда") +with st.sidebar.expander("Что это такое?"): + txt.preprocessing() + numeric_columns = list(time_series.select_dtypes(include=["int", "float"]).columns) other_columns = list(time_series.columns) @@ -196,7 +207,7 @@ def df_chart_display_iloc(df, data_col_iloc): # Слайдер для выбора и отображения нужного интервала ряда start_point, end_point = st.sidebar.slider( - "Выберите диапазон данных", + "Выберите диапазон данных для дальнейшей работы", 0, time_series_selected.shape[0] - 1, (0, time_series_selected.shape[0] - 1), @@ -205,7 +216,9 @@ def df_chart_display_iloc(df, data_col_iloc): time_series_selected_limited = time_series_selected.iloc[start_point:end_point] -"Выбранный временной ряд" +st.write("---") #Вставка разделителя + +st.subheader("Выбранный временной ряд") df_chart_display_iloc(time_series_selected_limited, 1) # st.write(time_series_selected.loc[start_point:end_point]) # st.line_chart(time_series_selected.iloc[start_point:end_point, 1]) @@ -213,17 +226,22 @@ def df_chart_display_iloc(df, data_col_iloc): T_s_len = end_point - start_point # Размер выбранного диапазона st.sidebar.write("Размер выбранного диапазона:", T_s_len) -MA_checkbox = st.sidebar.checkbox("Усреднить ряд", key="MA_checkbox") +MA_checkbox = st.sidebar.checkbox("Сгладить ряд", key="MA_checkbox") +with st.sidebar.expander("Что значит «сгладить»?"): + txt.moving_average() MA_step = 0 # объявление нулевого шага MA if MA_checkbox == False: pass else: + st.write("---") #Вставка разделителя + st.subheader("Сглаживание ряда") MA_step = st.sidebar.number_input( "Введите шаг скользящего среднего", min_value=1, max_value=T_s_len ) + st.write("Шаг скользящего среднего: ", MA_step, value=1) # time_series_avg = time_series_selected.loc[start_point:end_point].rolling(window=MA_step, min_periods=1).mean() - time_series_selected_limited["Усредненный"] = time_series_selected_limited.rolling( + time_series_selected_limited["Сглаженный"] = time_series_selected_limited.rolling( window=MA_step, min_periods=1 ).mean() @@ -231,31 +249,33 @@ def df_chart_display_iloc(df, data_col_iloc): col1, col2 = st.columns(2) with col1: - "Усредненный ряд" + "Сглаженный ряд" dframe_chart_MA = st.line_chart( - time_series_selected_limited.loc[MA_step:, ["Усредненный"]] + time_series_selected_limited.loc[MA_step:, ["Сглаженный"]] ) with col2: "Исходный ряд" st.line_chart(time_series_selected_limited.iloc[:, 1]) time_series_selected_limited[value_select] = time_series_selected_limited[ - "Усредненный" + "Сглаженный" ] - del time_series_selected_limited["Усредненный"] + del time_series_selected_limited["Сглаженный"] stationar_test_checkbox = st.sidebar.checkbox( "Тест на стационарность", key="stat_test_checkbox" ) +with st.sidebar.expander("Что это за тест?"): + txt.stationar_test() if stationar_test_checkbox: stat_test_res = adfuller(time_series_selected_limited.iloc[MA_step:, -1])[1] st.sidebar.write("Результаты теста на стационарность (p-value): ", stat_test_res) if stat_test_res < 0.05: - st.sidebar.write("Ряд стационарен по критерию 5%") + st.sidebar.write("Ряд стационарен") else: - st.sidebar.write("Ряд НЕ стационарен по критерию 5%") + st.sidebar.write("Ряд НЕ стационарен") st.session_state.final_dataframe = time_series_selected_limited -st.session_state +# st.session_state diff --git a/TimeSeriesApp/__pycache__/App_descriptions_streamlit.cpython-310.pyc b/TimeSeriesApp/__pycache__/App_descriptions_streamlit.cpython-310.pyc index 2d6d034..a55d33f 100644 Binary files a/TimeSeriesApp/__pycache__/App_descriptions_streamlit.cpython-310.pyc and b/TimeSeriesApp/__pycache__/App_descriptions_streamlit.cpython-310.pyc differ