mirosh111000

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

Nov 27th, 2025
439
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 14.20 KB | None | 0 0
  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. from scipy import stats
  5. import math
  6.  
  7.  
  8. VARIANT = 2
  9. VARIABLE_NAME = "Вага, кг"
  10.  
  11. UNIFORM_MIN = 40
  12. UNIFORM_MAX = 90
  13.  
  14. N_OBS = 100
  15.  
  16. RANDOM_SEED = 42
  17.  
  18. def generate_uniform_data(min_val: float, max_val: float, n: int, seed: int = None) -> np.ndarray:
  19.     rng = np.random.default_rng(seed)
  20.     raw = rng.uniform(min_val, max_val, n)
  21.     rounded = np.round(raw, 0).astype(int)
  22.     return rounded
  23.  
  24.  
  25. def stats_by_formulas(x: np.ndarray) -> dict:
  26.     x = np.asarray(x, dtype=float)
  27.     n = x.size
  28.     x_sorted = np.sort(x)
  29.     x_min = x_sorted[0]
  30.     x_max = x_sorted[-1]
  31.     R = x_max - x_min
  32.  
  33.     x_mean = x.sum() / n
  34.  
  35.     if n % 2 == 1:
  36.         median = x_sorted[n // 2]
  37.     else:
  38.         median = 0.5 * (x_sorted[n // 2 - 1] + x_sorted[n // 2])
  39.  
  40.     values, counts = np.unique(x, return_counts=True)
  41.     mode = values[np.argmax(counts)]
  42.  
  43.     d = np.mean(np.abs(x - x_mean))
  44.  
  45.     var_pop = np.mean((x - x_mean) ** 2)
  46.     sigma_pop = np.sqrt(var_pop)
  47.  
  48.     var_unbiased = var_pop * n / (n - 1)
  49.     sigma_unbiased = np.sqrt(var_unbiased)
  50.  
  51.     V_R = (R / x_mean) * 100.0
  52.     V_d = (d / x_mean) * 100.0
  53.     V_sigma = (sigma_pop / x_mean) * 100.0
  54.  
  55.     centered = x - x_mean
  56.     A = (centered ** 3).sum() / (n * (sigma_pop ** 3)) if sigma_pop != 0 else np.nan
  57.  
  58.     E = (centered ** 4).sum() / (n * (sigma_pop ** 4)) - 3 if sigma_pop != 0 else np.nan
  59.  
  60.     return {
  61.         "n": n,
  62.         "min": x_min,
  63.         "max": x_max,
  64.         "R": R,
  65.         "mean": x_mean,
  66.         "median": median,
  67.         "mode": mode,
  68.         "d": d,
  69.         "var_pop": var_pop,
  70.         "sigma_pop": sigma_pop,
  71.         "var_unbiased": var_unbiased,
  72.         "sigma_unbiased": sigma_unbiased,
  73.         "V_R": V_R,
  74.         "V_d": V_d,
  75.         "V_sigma": V_sigma,
  76.         "A": A,
  77.         "E": E,
  78.     }
  79.  
  80.  
  81. def stats_by_functions(x: np.ndarray) -> dict:
  82.     x = np.asarray(x, dtype=float)
  83.     n = x.size
  84.     x_min = np.min(x)
  85.     x_max = np.max(x)
  86.     R = x_max - x_min
  87.  
  88.     x_mean = x.mean()
  89.     median = np.median(x)
  90.     mode = float(pd.Series(x).mode().iloc[0])
  91.  
  92.     d = np.mean(np.abs(x - x_mean))
  93.  
  94.     var_pop = np.var(x, ddof=0)
  95.     sigma_pop = np.std(x, ddof=0)
  96.     var_unbiased = np.var(x, ddof=1)
  97.     sigma_unbiased = np.std(x, ddof=1)
  98.  
  99.     V_R = (R / x_mean) * 100.0
  100.     V_d = (d / x_mean) * 100.0
  101.     V_sigma = (sigma_pop / x_mean) * 100.0
  102.  
  103.     A = stats.skew(x, bias=False)
  104.     E = stats.kurtosis(x, fisher=True, bias=False)
  105.  
  106.     return {
  107.         "n": n,
  108.         "min": x_min,
  109.         "max": x_max,
  110.         "R": R,
  111.         "mean": x_mean,
  112.         "median": median,
  113.         "mode": mode,
  114.         "d": d,
  115.         "var_pop": var_pop,
  116.         "sigma_pop": sigma_pop,
  117.         "var_unbiased": var_unbiased,
  118.         "sigma_unbiased": sigma_unbiased,
  119.         "V_R": V_R,
  120.         "V_d": V_d,
  121.         "V_sigma": V_sigma,
  122.         "A": A,
  123.         "E": E,
  124.     }
  125.  
  126.  
  127. def stats_by_addin(x: np.ndarray) -> dict:
  128.     x = np.asarray(x, dtype=float)
  129.     desc = stats.describe(x)
  130.     n = desc.nobs
  131.     x_min, x_max = desc.minmax
  132.     R = x_max - x_min
  133.     x_mean = desc.mean
  134.  
  135.     var_unbiased = float(desc.variance)
  136.     sigma_unbiased = float(np.sqrt(var_unbiased))
  137.  
  138.     var_pop = var_unbiased * (n - 1) / n
  139.     sigma_pop = float(np.sqrt(var_pop))
  140.  
  141.     A = float(desc.skewness)
  142.     E = float(desc.kurtosis)
  143.  
  144.     median = float(np.median(x))
  145.     mode = float(pd.Series(x).mode().iloc[0])
  146.     d = float(np.mean(np.abs(x - x_mean)))
  147.  
  148.     V_R = (R / x_mean) * 100.0
  149.     V_d = (d / x_mean) * 100.0
  150.     V_sigma = (sigma_pop / x_mean) * 100.0
  151.  
  152.     return {
  153.         "n": n,
  154.         "min": x_min,
  155.         "max": x_max,
  156.         "R": R,
  157.         "mean": x_mean,
  158.         "median": median,
  159.         "mode": mode,
  160.         "d": d,
  161.         "var_pop": var_pop,
  162.         "sigma_pop": sigma_pop,
  163.         "var_unbiased": var_unbiased,
  164.         "sigma_unbiased": sigma_unbiased,
  165.         "V_R": V_R,
  166.         "V_d": V_d,
  167.         "V_sigma": V_sigma,
  168.         "A": A,
  169.         "E": E,
  170.     }
  171.  
  172.  
  173. from typing import Tuple
  174.  
  175. def check_homogeneity(V_sigma: float) -> str:
  176.     if V_sigma <= 30.0:
  177.         return f"Вибірка однорідна (V_sigma = {V_sigma:.2f}% ≤ 30%)"
  178.     else:
  179.         return f"Вибірка НЕ є однорідною (V_sigma = {V_sigma:.2f}% > 30%)"
  180.  
  181. def critical_values_A_E(n: int) -> Tuple[float, float]:
  182.     D_A = 6 * (n - 1) / ((n + 1) * (n + 3))
  183.     D_E = 24 * n * (n - 2) * (n - 3) / (((n + 1) ** 2) * (n + 3) * (n + 5))
  184.     return D_A, D_E
  185.  
  186. def check_normality(A: float, E: float, n: int) -> str:
  187.     D_A, D_E = critical_values_A_E(n)
  188.     sigma_A = math.sqrt(D_A)
  189.     sigma_E = math.sqrt(D_E)
  190.     crit_A = 3 * sigma_A
  191.     crit_E = 5 * sigma_E
  192.  
  193.     cond_A = abs(A) <= crit_A
  194.     cond_E = abs(E) <= crit_E
  195.  
  196.     lines = []
  197.     lines.append(f"A = {A:.4f}, D(A) = {D_A:.4f}, 3·sqrt(D(A)) = {crit_A:.4f}")
  198.     lines.append(f"E = {E:.4f}, D(E) = {D_E:.4f}, 5·sqrt(D(E)) = {crit_E:.4f}")
  199.     if cond_A and cond_E:
  200.         lines.append("Форма розподілу МОЖЕ вважатися близькою до нормальної (обидві нерівності виконуються).")
  201.     else:
  202.         lines.append("Форма розподілу НЕ є близькою до нормальної (хоча б одна з нерівностей порушена).")
  203.     return "\n".join(lines)
  204.  
  205. def sturges_intervals(n: int) -> int:
  206.     if n <= 1:
  207.         return 1
  208.     k = 1 + 3.322 * math.log10(n)
  209.     return int(round(k))
  210.  
  211. def build_intervals(x: np.ndarray, k: int) -> np.ndarray:
  212.     x = np.asarray(x, dtype=float)
  213.     x_min = float(np.min(x))
  214.     x_max = float(np.max(x))
  215.     boundaries = np.linspace(x_min, x_max, k + 1)
  216.     boundaries = np.round(boundaries, 1)
  217.     return boundaries
  218.  
  219. def grouping_manual(x: np.ndarray, boundaries: np.ndarray) -> pd.DataFrame:
  220.     x = np.asarray(x, dtype=float)
  221.     n = x.size
  222.     k = len(boundaries) - 1
  223.  
  224.     intervals_left = []
  225.     intervals_right = []
  226.     midpoints = []
  227.     freqs = []
  228.  
  229.     for i in range(k):
  230.         left = boundaries[i]
  231.         right = boundaries[i + 1]
  232.  
  233.         if i < k - 1:
  234.             mask = (x >= left) & (x < right)
  235.         else:
  236.             mask = (x >= left) & (x <= right)
  237.  
  238.         count = int(mask.sum())
  239.  
  240.         intervals_left.append(left)
  241.         intervals_right.append(right)
  242.         midpoints.append(0.5 * (left + right))
  243.         freqs.append(count)
  244.  
  245.     freqs = np.array(freqs, dtype=int)
  246.     rel_freq = freqs / n
  247.     cum_freq_pct = np.cumsum(rel_freq) * 100.0
  248.  
  249.     df = pd.DataFrame({
  250.         "L": intervals_left,
  251.         "U": intervals_right,
  252.         "midpoint": midpoints,
  253.         "n_manual": freqs,
  254.         "p_manual": rel_freq,
  255.         "K_manual_pct": cum_freq_pct,
  256.     })
  257.     return df
  258.  
  259. def grouping_addin(x: np.ndarray, boundaries: np.ndarray, df_manual: pd.DataFrame) -> pd.DataFrame:
  260.     x = np.asarray(x, dtype=float)
  261.     k = len(boundaries) - 1
  262.  
  263.     freqs_addin, _ = np.histogram(x, bins=boundaries)
  264.  
  265.     n = x.size
  266.     rel_freq_addin = freqs_addin / n
  267.     cum_freq_addin_pct = np.cumsum(rel_freq_addin) * 100.0
  268.  
  269.     df = df_manual.copy()
  270.     df["n_addin"] = freqs_addin
  271.     df["p_addin"] = rel_freq_addin
  272.     df["K_addin_pct"] = cum_freq_addin_pct
  273.     return df
  274.  
  275. def theoretical_uniform_counts(boundaries: np.ndarray, n: int, a: float, b: float) -> np.ndarray:
  276.     probs = (boundaries[1:] - boundaries[:-1]) / (b - a)
  277.     counts = n * probs
  278.     return counts
  279.  
  280. def plot_hist_addin(x: np.ndarray, boundaries: np.ndarray):
  281.     plt.figure(figsize=(8, 5))
  282.     plt.hist(x, bins=boundaries, edgecolor="black", alpha=0.7)
  283.     plt.title("Гістограма (аналог статистичної надбудови)")
  284.     plt.xlabel(VARIABLE_NAME)
  285.     plt.ylabel("Частота")
  286.     plt.grid(axis="y", alpha=0.3)
  287.  
  288. def plot_hist_polygon_cumulative(df_group_manual: pd.DataFrame):
  289.     fig, ax1 = plt.subplots(figsize=(8, 5))
  290.  
  291.     L = df_group_manual["L"].values
  292.     U = df_group_manual["U"].values
  293.     mid = df_group_manual["midpoint"].values
  294.     n_manual = df_group_manual["n_manual"].values
  295.     K_manual_pct = df_group_manual["K_manual_pct"].values
  296.  
  297.     widths = U - L
  298.     ax1.bar(mid, n_manual, width=widths * 0.9, edgecolor="black", alpha=0.6, label="Гістограма (ручне)")
  299.  
  300.     ax1.plot(mid, n_manual, "o-", label="Полігон")
  301.     ax1.set_xlabel(VARIABLE_NAME)
  302.     ax1.set_ylabel("Частота")
  303.     ax1.set_title("Гістограма та полігон (ручне групування)")
  304.     ax1.grid(alpha=0.3)
  305.  
  306.     ax2 = ax1.twinx()
  307.     ax2.plot(mid, K_manual_pct, "s-", color="purple", label="Кумулята")
  308.     ax2.set_ylabel("Накопичена частота, %")
  309.  
  310.     lines1, labels1 = ax1.get_legend_handles_labels()
  311.     lines2, labels2 = ax2.get_legend_handles_labels()
  312.     ax1.legend(lines1 + lines2, labels1 + labels2, loc="upper left")
  313.  
  314. def plot_empirical_vs_theoretical(df_group_manual: pd.DataFrame, theor_counts: np.ndarray):
  315.     plt.figure(figsize=(8, 5))
  316.  
  317.     mid = df_group_manual["midpoint"].values
  318.     n_manual = df_group_manual["n_manual"].values
  319.  
  320.     plt.bar(mid, n_manual, width=(df_group_manual["U"].values - df_group_manual["L"].values) * 0.9,
  321.             edgecolor="black", alpha=0.6, label="Емпірична гістограма")
  322.  
  323.     plt.plot(mid, theor_counts, "o-", label="Теоретичний розподіл")
  324.  
  325.     plt.xlabel(VARIABLE_NAME)
  326.     plt.ylabel("Частота")
  327.     plt.title("Емпіричний vs теоретичний розподіл")
  328.     plt.grid(alpha=0.3)
  329.     plt.legend()
  330.  
  331. def run_lab(show_plots: bool = True):
  332.     x = generate_uniform_data(UNIFORM_MIN, UNIFORM_MAX, N_OBS, seed=RANDOM_SEED)
  333.     df = pd.DataFrame({"X": x})
  334.  
  335.     print(f"Практична робота 1-3. Варіант {VARIANT}. Випадкова величина: {VARIABLE_NAME}")
  336.     print(f"Розподіл: рівномірний на [{UNIFORM_MIN}; {UNIFORM_MAX}], n = {N_OBS}")
  337.     print("\nПерші 10 спостережень (округлені значення):")
  338.     print(df.head(10))
  339.  
  340.     stats_formulas = stats_by_formulas(x)
  341.     stats_funcs = stats_by_functions(x)
  342.     stats_addin = stats_by_addin(x)
  343.  
  344.     all_keys = list(stats_formulas.keys())
  345.     table = pd.DataFrame({
  346.         "Показник": all_keys,
  347.         "За формулами": [stats_formulas[k] for k in all_keys],
  348.         "Стат. функції": [stats_funcs[k] for k in all_keys],
  349.         "Надбудова": [stats_addin[k] for k in all_keys],
  350.     })
  351.     table.set_index("Показник", inplace=True)
  352.  
  353.     print("\n=== Показники варіації (три способи) ===")
  354.     print(table)
  355.  
  356.     homog_text = check_homogeneity(stats_formulas["V_sigma"])
  357.     print("\n=== Однорідність вибірки ===")
  358.     print(homog_text)
  359.  
  360.     normality_text = check_normality(stats_formulas["A"], stats_formulas["E"], stats_formulas["n"])
  361.     print("\n=== Перевірка близькості до нормального розподілу ===")
  362.     print(normality_text)
  363.  
  364.     k = sturges_intervals(N_OBS)
  365.     print(f"\nКількість інтервалів (формула Стерджеса): k = {k}")
  366.     boundaries = build_intervals(x, k=k)
  367.     df_group_manual = grouping_manual(x, boundaries)
  368.     df_group = grouping_addin(x, boundaries, df_group_manual)
  369.  
  370.     print("\n=== Групування даних (ручне + надбудова) ===")
  371.     print(df_group)
  372.  
  373.     theor_counts = theoretical_uniform_counts(boundaries, N_OBS, UNIFORM_MIN, UNIFORM_MAX)
  374.  
  375.     print("\nТеоретичні частоти для рівномірного розподілу:")
  376.     print(theor_counts)
  377.  
  378.     if show_plots:
  379.         plot_hist_addin(x, boundaries)
  380.         plot_hist_polygon_cumulative(df_group_manual)
  381.         plot_empirical_vs_theoretical(df_group_manual, theor_counts)
  382.         plt.show()
  383.  
  384.  
  385. run_lab(show_plots=True)
  386.  
  387.  
  388.  
  389.  
  390.  
  391. print(f"--- РОЗВ'ЯЗАННЯ КОНТРОЛЬНОЇ ЗАДАЧІ ---")
  392. import numpy as np
  393. import pandas as pd
  394. import matplotlib.pyplot as plt
  395. from scipy import stats
  396.  
  397. data = [
  398.     21, 17, 27, 20, 22, 12, 24, 13, 20, 19, 22, 16, 22,
  399.     9, 21, 16, 23, 16, 21, 24, 18, 11, 22, 15, 23, 21,
  400.     10, 15, 18, 15, 21, 14, 15, 18, 22, 15, 17, 19, 17,
  401.     18, 17, 24, 18, 19, 16, 17, 15, 17, 25, 16
  402. ]
  403.  
  404. x = np.array(data)
  405. n = len(x)
  406. print(f"Обсяг вибірки n = {n}")
  407.  
  408. unique_elements, counts_elements = np.unique(x, return_counts=True)
  409.  
  410. var_series = pd.DataFrame({
  411.     'Варіанта (xi)': unique_elements,
  412.     'Частота (ni)': counts_elements
  413. })
  414.  
  415. print("\n1. Варіаційний ряд:")
  416. print(var_series.to_string(index=False))
  417.  
  418. mean_val = np.mean(x)
  419.  
  420. median_val = np.median(x)
  421.  
  422. mode_result = stats.mode(x, keepdims=True)
  423. mode_val = mode_result.mode[0]
  424. mode_count = mode_result.count[0]
  425.  
  426. std_dev = np.std(x, ddof=1)
  427. cv = (std_dev / mean_val) * 100
  428.  
  429. print("\n2. Статистичні показники:")
  430. print(f"{'Середня арифметична (x̄)':<35} {mean_val:.4f}")
  431. print(f"{'Медіана (Me)':<35} {median_val:.4f}")
  432. print(f"{'Мода (Mo)':<35} {mode_val} (зустрічається {mode_count} разів)")
  433. print(f"{'Середнє кв. відхилення (σ або S)':<35} {std_dev:.4f}")
  434. print(f"{'Коефіцієнт варіації (V)':<35} {cv:.2f} %")
  435.  
  436. homogeneity = "ОДНОРІДНА" if cv <= 30 else "НЕОДНОРІДНА"
  437. print(f"-> Оскільки V = {cv:.2f}%, сукупність є {homogeneity} (поріг 30%).")
  438.  
  439. plt.figure(figsize=(10, 6))
  440.  
  441. plt.plot(unique_elements, counts_elements, marker='o', linestyle='-', color='b', linewidth=2, markersize=8)
  442.  
  443. for i, txt in enumerate(counts_elements):
  444.     plt.annotate(txt, (unique_elements[i], counts_elements[i]),
  445.                  textcoords="offset points", xytext=(0,10), ha='center')
  446.  
  447. plt.title('Лінійний графік варіаційного ряду (Полігон розподілу)')
  448. plt.xlabel('Кількість зерен у колосі ($x_i$)')
  449. plt.ylabel('Частота ($n_i$)')
  450. plt.xticks(unique_elements)
  451. plt.grid(True, linestyle='--', alpha=0.7)
  452.  
  453. print("\n3. Графік побудовано.")
  454. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment