mirosh111000

Мірошниченко_ГЙМ_ПР№9-10

Dec 14th, 2025 (edited)
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.50 KB | None | 0 0
  1. import math
  2.  
  3.  
  4. DATA_RAW = {
  5.     18: [0.60, 0.64, 0.69, 0.52, 0.65, 0.52, 0.58, 0.63, 0.69, 0.48],
  6.     24: [0.61, 0.72, 0.72, 0.58, 0.46, 0.52, 0.72, 0.59, 0.71, 0.79],
  7.     6:  [0.58, 0.59, 0.66, 0.46, 0.47, 0.56, 0.70, 0.60, 0.60, 0.64],
  8.     12: [0.70, 0.57, 0.67, 0.87, 0.52, 0.66, None, 0.59, 0.65, 0.66],
  9. }
  10.  
  11. HOURS_ORDER = [18, 24, 6, 12]
  12.  
  13.  
  14. def fmt(x, width=6, prec=2):
  15.     if x is None:
  16.         return f"{'—':>{width}}"
  17.     return f"{x:>{width}.{prec}f}"
  18.  
  19.  
  20. def print_input_table(data_raw, hours_order):
  21.     max_cols = max(len(v) for v in data_raw.values())
  22.     print("\n--- Вхідні дані ---")
  23.     header = "Години | " + " ".join([f"{j:>6d}" for j in range(1, max_cols + 1)])
  24.     print(header)
  25.     print("-" * len(header))
  26.     for h in hours_order:
  27.         row = data_raw[h] + [None] * (max_cols - len(data_raw[h]))
  28.         print(f"{h:>6d} | " + " ".join(fmt(v) for v in row))
  29.  
  30.  
  31. def clean_groups(data_raw, hours_order):
  32.     groups = {}
  33.     stats = {}
  34.     for h in hours_order:
  35.         xs = [v for v in data_raw[h] if v is not None]
  36.         groups[h] = xs
  37.         n_i = len(xs)
  38.         T_i = sum(xs)
  39.         mean_i = T_i / n_i if n_i > 0 else float("nan")
  40.         stats[h] = (n_i, T_i, mean_i)
  41.     return groups, stats
  42.  
  43.  
  44. def anova_one_way(groups, stats, hours_order):
  45.     all_x = []
  46.     for h in hours_order:
  47.         all_x.extend(groups[h])
  48.  
  49.     N = len(all_x)
  50.     T = sum(all_x)
  51.     sum_x2 = sum(x * x for x in all_x)
  52.  
  53.     C = (T * T) / N
  54.  
  55.     sum_Ti2_over_ni = 0.0
  56.     for h in hours_order:
  57.         n_i, T_i, _ = stats[h]
  58.         sum_Ti2_over_ni += (T_i * T_i) / n_i
  59.  
  60.     SS_total = sum_x2 - C
  61.     SS_factor = sum_Ti2_over_ni - C
  62.     SS_error = sum_x2 - sum_Ti2_over_ni
  63.  
  64.     a = len(hours_order)
  65.  
  66.     df_total = N - 1
  67.     df_factor = a - 1
  68.     df_error = N - a
  69.  
  70.     MS_factor = SS_factor / df_factor
  71.     MS_error = SS_error / df_error
  72.  
  73.     F_data = MS_factor / MS_error
  74.  
  75.     return {
  76.         "N": N,
  77.         "T": T,
  78.         "sum_x2": sum_x2,
  79.         "C": C,
  80.         "a": a,
  81.         "sum_Ti2_over_ni": sum_Ti2_over_ni,
  82.         "SS_total": SS_total,
  83.         "SS_factor": SS_factor,
  84.         "SS_error": SS_error,
  85.         "df_total": df_total,
  86.         "df_factor": df_factor,
  87.         "df_error": df_error,
  88.         "MS_factor": MS_factor,
  89.         "MS_error": MS_error,
  90.         "F_data": F_data,
  91.     }
  92.  
  93.  
  94. def print_table1(data_raw, stats, hours_order):
  95.     max_cols = max(len(v) for v in data_raw.values())
  96.     print("\n--- Таблиця 1. Групи за фактором A + спостереження + суми/середні ---")
  97.     header = "Година | " + " ".join([f"{j:>6d}" for j in range(1, max_cols + 1)]) + " |   T_i  | n_i |  x̄_i"
  98.     print(header)
  99.     print("-" * len(header))
  100.  
  101.     for h in hours_order:
  102.         row = data_raw[h] + [None] * (max_cols - len(data_raw[h]))
  103.         n_i, T_i, mean_i = stats[h]
  104.         print(
  105.             f"{h:>6d} | "
  106.             + " ".join(fmt(v) for v in row)
  107.             + f" | {T_i:>6.3f} | {n_i:>3d} | {mean_i:>5.4f}"
  108.         )
  109.  
  110.  
  111. def print_anova_results(res, alpha_levels=(0.05, 0.01)):
  112.     df1 = res["df_factor"]
  113.     df2 = res["df_error"]
  114.  
  115.     fcrit = {alpha: f_isf(alpha, df1, df2) for alpha in alpha_levels}
  116.  
  117.     print("\n--- Проміжні підсумки ---")
  118.     print(f"Загальна сума T = {res['T']:.4f}")
  119.     print(f"Загальна кількість N = {res['N']}")
  120.     print(f"Сума квадратів усіх x (Σx^2) = {res['sum_x2']:.4f}")
  121.     print(f"Поправковий коефіцієнт C = T^2 / N = {res['C']:.4f}")
  122.     print(f"Σ(T_i^2 / n_i) = {res['sum_Ti2_over_ni']:.4f}")
  123.  
  124.     print("\n--- Таблиця 2. Підсумкова таблиця дисперсійного аналізу ---")
  125.     print("Джерело варіації        |      SS |  df |      MS |    F_data |  F_0.05 |  F_0.01")
  126.     print("-" * 86)
  127.  
  128.     ss_a = res["SS_factor"]
  129.     ss_e = res["SS_error"]
  130.     ss_t = res["SS_total"]
  131.  
  132.     ms_a = res["MS_factor"]
  133.     ms_e = res["MS_error"]
  134.     f_data = res["F_data"]
  135.  
  136.     f05 = fcrit.get(0.05, float("nan"))
  137.     f01 = fcrit.get(0.01, float("nan"))
  138.  
  139.     print(f"Між групами (Фактор A)  | {ss_a:>7.4f} | {df1:>3d} | {ms_a:>7.4f} | {f_data:>8.4f} | {f05:>7.4f} | {f01:>7.4f}")
  140.     print(f"Всередині груп (Помилка)| {ss_e:>7.4f} | {df2:>3d} | {ms_e:>7.4f} | {'':>8} | {'':>7} | {'':>7}")
  141.     print(f"Загальна                | {ss_t:>7.4f} | {res['df_total']:>3d} | {'':>7} | {'':>8} | {'':>7} | {'':>7}")
  142.  
  143.     print("\n--- Критерій Фішера ---")
  144.     print("F_data = MS_фактор / MS_помилка")
  145.     print(f"F_data = {f_data:.6f}")
  146.     print(f"F_crit(α=0.05; df1={df1}, df2={df2}) = {f05:.6f}")
  147.     print(f"F_crit(α=0.01; df1={df1}, df2={df2}) = {f01:.6f}")
  148.  
  149.     print("\n--- Висновок ---")
  150.     for alpha in alpha_levels:
  151.         fc = fcrit[alpha]
  152.         if f_data < fc:
  153.             print(f"α = {alpha:.2f}: F_data < F_crit ⇒ H0 приймається (вплив фактору A статистично НЕ значущий).")
  154.         else:
  155.             print(f"α = {alpha:.2f}: F_data ≥ F_crit ⇒ H0 відхиляється (вплив фактору A статистично значущий).")
  156.  
  157.  
  158. def _betacf(a, b, x, max_iter=200, eps=3e-14):
  159.     am = 1.0
  160.     bm = 1.0
  161.     az = 1.0
  162.     qab = a + b
  163.     qap = a + 1.0
  164.     qam = a - 1.0
  165.  
  166.     bz = 1.0 - qab * x / qap
  167.     if abs(bz) < 1e-30:
  168.         bz = 1e-30
  169.  
  170.     aold = 0.0
  171.     for m in range(1, max_iter + 1):
  172.         em = float(m)
  173.         tem = em + em
  174.  
  175.         d = em * (b - em) * x / ((qam + tem) * (a + tem))
  176.         ap = az + d * am
  177.         bp = bz + d * bm
  178.  
  179.         d = -(a + em) * (qab + em) * x / ((a + tem) * (qap + tem))
  180.         app = ap + d * az
  181.         bpp = bp + d * bz
  182.  
  183.         aold = az
  184.         am = ap / bpp
  185.         bm = bp / bpp
  186.         az = app / bpp
  187.         bz = 1.0
  188.  
  189.         if abs(az - aold) < eps * abs(az):
  190.             return az
  191.  
  192.     return az
  193.  
  194.  
  195. def betai(a, b, x):
  196.     if x <= 0.0:
  197.         return 0.0
  198.     if x >= 1.0:
  199.         return 1.0
  200.  
  201.     ln_beta = math.lgamma(a) + math.lgamma(b) - math.lgamma(a + b)
  202.     bt = math.exp(a * math.log(x) + b * math.log(1.0 - x) - ln_beta)
  203.  
  204.     if x < (a + 1.0) / (a + b + 2.0):
  205.         return bt * _betacf(a, b, x) / a
  206.     return 1.0 - bt * _betacf(b, a, 1.0 - x) / b
  207.  
  208.  
  209. def f_cdf(x, d1, d2):
  210.     if x <= 0.0:
  211.         return 0.0
  212.     a = d1 / 2.0
  213.     b = d2 / 2.0
  214.     y = (d1 * x) / (d1 * x + d2)
  215.     return betai(a, b, y)
  216.  
  217.  
  218. def f_isf(alpha, d1, d2):
  219.     target_cdf = 1.0 - alpha
  220.  
  221.     lo = 0.0
  222.     hi = 1.0
  223.     while f_cdf(hi, d1, d2) < target_cdf:
  224.         hi *= 2.0
  225.         if hi > 1e9:
  226.             break
  227.  
  228.     for _ in range(200):
  229.         mid = (lo + hi) / 2.0
  230.         if f_cdf(mid, d1, d2) < target_cdf:
  231.             lo = mid
  232.         else:
  233.             hi = mid
  234.         if hi - lo < 1e-12 * max(1.0, hi):
  235.             break
  236.  
  237.     return (lo + hi) / 2.0
  238.  
  239.  
  240. def main():
  241.     print("=== ПР №9–10. Дисперсійний аналіз даних. ВАРІАНТ 2 ===")
  242.     print("Фактор A: година доби. Об'єкт: Syringa Emodi (вміст каротиноїдів).")
  243.  
  244.     print_input_table(DATA_RAW, HOURS_ORDER)
  245.  
  246.     groups, stats = clean_groups(DATA_RAW, HOURS_ORDER)
  247.     print_table1(DATA_RAW, stats, HOURS_ORDER)
  248.  
  249.     res = anova_one_way(groups, stats, HOURS_ORDER)
  250.     print_anova_results(res, alpha_levels=(0.05, 0.01))
  251.  
  252. if __name__ == "__main__":
  253.     main()
  254.  
Advertisement
Add Comment
Please, Sign In to add comment