Добавлены пояснения к анализу

This commit is contained in:
2026-07-24 00:52:40 +05:00
parent 33fd9f1177
commit 901a5e5c7b
2 changed files with 328 additions and 24 deletions
+60 -24
View File
@@ -7,11 +7,13 @@
- проверку значимости коэффициентов (t-критерий),
- дисперсионный анализ (ANOVA) с разложением остатка на чистую ошибку и неадекватность (если есть центр),
- оценку воспроизводимости по центральным точкам,
- исключение незначимых факторов с пересчётом модели.
- исключение незначимых факторов с пересчётом модели,
- интерпретацию результатов на естественном языке.
"""
import numpy as np
from core.table_io import handle_table_output
from core.interpreter import full_interpretation
from core.statistics import (
compute_regression,
get_center_indices,
@@ -19,7 +21,7 @@ from core.statistics import (
chi2_confidence_interval,
get_t_critical,
regression_summary,
anova_regression # функция ANOVA, добавленная в statistics.py
anova_regression
)
@@ -134,6 +136,7 @@ def analyze_single_response(response, X, k, df_res, design, alpha, factor_names)
и неадекватность (lack-of-fit).
4. Анализ центральных точек – оценка воспроизводимости.
5. Опция исключения незначимых факторов (p > alpha) и пересчёт упрощённой модели.
6. Интерпретация результатов на естественном языке.
Аргументы:
response (dict): {'name': str, 'values': list}
@@ -142,7 +145,7 @@ def analyze_single_response(response, X, k, df_res, design, alpha, factor_names)
df_res (int): степени свободы остатка (N - k - 1)
design (ExperimentDesign): объект с планом
alpha (float): уровень значимости
factor_names (list): имена факторов
factor_names (list): имена факторов (без "Свободный член")
"""
# Преобразуем значения отклика в массив numpy
y = np.array(response["values"])
@@ -209,10 +212,18 @@ def analyze_single_response(response, X, k, df_res, design, alpha, factor_names)
if not np.isnan(t_crit):
print(f"Критическое значение t (alpha={alpha}, df={df_res}): {t_crit:.4f}")
return t_crit
# Возвращаем summary для дальнейшего использования
return t_crit, summary
# ---------- Шаг 2 (выполнение): вывод статистики для полной модели ----------
t_crit = print_and_get_tcrit(beta, se, t_stats, df_res_actual, y_pred, y, k, factor_names, alpha)
t_crit, summary_full = print_and_get_tcrit(beta, se, t_stats, df_res_actual, y_pred, y, k, factor_names, alpha)
# Извлекаем показатели качества
r2 = summary_full["r2"]
r2_adj = summary_full["r2_adj"]
f_stat = summary_full["f_stat"]
f_pvalue = summary_full["f_pvalue"]
# ---------- Шаг 3: Дисперсионный анализ (ANOVA) ----------
# Определяем индексы строк плана, соответствующие центральным точкам (все активные факторы = 0)
@@ -275,6 +286,10 @@ def analyze_single_response(response, X, k, df_res, design, alpha, factor_names)
handle_table_output(anova_headers, anova_rows, title="", ask_each_time=True)
# ---------- Шаг 4: Анализ центральных точек (воспроизводимость) ----------
# Инициализируем переменные для центра
center_mean = None
center_var = None
if len(center_indices) >= 2:
y_center = y[center_indices]
center_mean, center_var = compute_center_stats(y_center)
@@ -302,27 +317,48 @@ def analyze_single_response(response, X, k, df_res, design, alpha, factor_names)
# Если все факторы значимы, упрощённая модель не отличается
if all(significant):
print("Все факторы значимы. Упрощённая модель не отличается от полной.")
return
else:
# Выбираем только значимые столбцы
X_new = X[:, significant]
# Пересчитываем регрессию
reg_new = compute_regression(X_new, y)
beta_new = reg_new["beta"]
se_new = reg_new["se"]
t_stats_new = reg_new["t_stats"]
df_res_new = reg_new["df_res"]
y_pred_new = reg_new["y_pred"]
# Выбираем только значимые столбцы
X_new = X[:, significant]
# Пересчитываем регрессию
reg_new = compute_regression(X_new, y)
beta_new = reg_new["beta"]
se_new = reg_new["se"]
t_stats_new = reg_new["t_stats"]
df_res_new = reg_new["df_res"]
y_pred_new = reg_new["y_pred"]
if np.isnan(beta_new).any():
print("Ошибка при пересчёте упрощённой модели.")
else:
# Обновляем список имён факторов
factor_names_new = ["Свободный член"] + [factor_names[i-1] for i in range(1, k+1) if significant[i]]
k_new = len(factor_names_new) - 1
if np.isnan(beta_new).any():
print("Ошибка при пересчёте упрощённой модели.")
return
print("\n=== Упрощённая модель (исключены незначимые факторы) ===")
# Выводим статистику для упрощённой модели
print_and_get_tcrit(beta_new, se_new, t_stats_new, df_res_new, y_pred_new, y, k_new, factor_names_new[1:], alpha)
print("\nСовет: для использования упрощённой модели в крутом восхождении установите шаги для исключённых факторов равными 0 в планировании эксперимента.")
# Обновляем список имён факторов
factor_names_new = ["Свободный член"] + [factor_names[i-1] for i in range(1, k+1) if significant[i]]
k_new = len(factor_names_new) - 1
# ---------- Шаг 6: Интерпретация результатов ----------
# Создаём полный список имён (включая свободный член) для интерпретатора
factor_names_full = ["Свободный член"] + factor_names
print("\n=== Упрощённая модель (исключены незначимые факторы) ===")
print_and_get_tcrit(beta_new, se_new, t_stats_new, df_res_new, y_pred_new, y, k_new, factor_names_new[1:], alpha)
# Формируем полное заключение с помощью интерпретатора
interpretation = full_interpretation(
r2=r2,
r2_adj=r2_adj,
f_stat=f_stat,
f_pvalue=f_pvalue,
beta=beta,
t_stats=t_stats,
p_values=None, # пока не вычисляем p-values для коэффициентов
factor_names=factor_names_full, # <-- передаём полный список
anova=anova,
center_mean=center_mean,
center_var=center_var,
n_center=len(center_indices) if len(center_indices) >= 2 else 0,
alpha=alpha
)
print("\nСовет: для использования упрощённой модели в крутом восхождении установите шаги для исключённых факторов равными 0 в планировании эксперимента.")
print("\n" + interpretation)