mirosh111000

Мірошниченко_ГЙМ_Ат№2

Dec 11th, 2025
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.93 KB | None | 0 0
  1. import numpy as np
  2. import pandas as pd
  3. from scipy.stats import chi2_contingency, chi2
  4.  
  5.  
  6. def build_observed_table() -> pd.DataFrame:
  7.  
  8.     data = {
  9.         "Дитина +": [84, 12],
  10.         "Дитина –": [8, 8],
  11.     }
  12.     index = ["Мати +", "Мати –"]
  13.     df_obs = pd.DataFrame(data, index=index)
  14.     return df_obs
  15.  
  16.  
  17. def compute_relative_frequencies(df_obs: pd.DataFrame):
  18.  
  19.     N = df_obs.values.sum()
  20.     joint = df_obs / N
  21.  
  22.     row_marginals = df_obs.sum(axis=1) / N
  23.     col_marginals = df_obs.sum(axis=0) / N
  24.  
  25.     return joint, row_marginals, col_marginals
  26.  
  27.  
  28. def compute_expected_frequencies(df_obs: pd.DataFrame) -> pd.DataFrame:
  29.  
  30.     N = df_obs.values.sum()
  31.  
  32.     row_totals = df_obs.sum(axis=1)
  33.     col_totals = df_obs.sum(axis=0)
  34.  
  35.     expected = pd.DataFrame(index=df_obs.index, columns=df_obs.columns, dtype=float)
  36.     for i in df_obs.index:
  37.         for j in df_obs.columns:
  38.             expected.loc[i, j] = row_totals[i] * col_totals[j] / N
  39.  
  40.     return expected
  41.  
  42.  
  43. def compute_chi_square_manual(df_obs: pd.DataFrame, expected: pd.DataFrame) -> tuple[float, pd.DataFrame]:
  44.  
  45.     contributions = (df_obs - expected) ** 2 / expected
  46.     chi2_value = contributions.values.sum()
  47.     return chi2_value, contributions
  48.  
  49.  
  50. def compute_measures(chi2_value: float, N: int):
  51.  
  52.     phi = np.sqrt(chi2_value / N)
  53.     C = np.sqrt(chi2_value / (chi2_value + N))
  54.     return phi, C
  55.  
  56.  
  57. def interpret_correlation_strength(r: float) -> str:
  58.  
  59.     abs_r = abs(r)
  60.     if abs_r < 0.3:
  61.         return "майже відсутній"
  62.     elif 0.3 <= abs_r < 0.5:
  63.         return "слабкий"
  64.     elif 0.5 <= abs_r < 0.7:
  65.         return "помірний"
  66.     elif 0.7 <= abs_r < 1.0:
  67.         return "сильний"
  68.     else:
  69.         return "функціональний"
  70.  
  71.  
  72. def print_header() -> None:
  73.     print("=== Аналіз взаємозв'язку між резус-фактором матері та дитини (Варіант 2) ===")
  74.    
  75.  
  76. def main() -> None:
  77.     print_header()
  78.  
  79.     df_obs = build_observed_table()
  80.     print("1. Вихідна таблиця спряженості (частоти n_ij):")
  81.     print(df_obs)
  82.  
  83.     N = int(df_obs.values.sum())
  84.     print(f"\nЗагальний обсяг вибірки N = {N}\n")
  85.  
  86.     row_totals = df_obs.sum(axis=1)
  87.     col_totals = df_obs.sum(axis=0)
  88.  
  89.     print("Рядкові підсумки (n_i·):")
  90.     print(row_totals)
  91.  
  92.     print("\nСтовпчикові підсумки (n_·j):")
  93.     print(col_totals)
  94.  
  95.     joint, row_marginals, col_marginals = compute_relative_frequencies(df_obs)
  96.  
  97.     print("\n2. Спільні відносні частоти p_ij = n_ij / N:")
  98.     print(joint.round(4))
  99.  
  100.     print("\nМаргінальні відносні частоти p_i· та p_·j:")
  101.     print("p_i·:")
  102.     print(row_marginals.round(4))
  103.     print("\np_·j:")
  104.     print(col_marginals.round(4))
  105.  
  106.     print("\n3. Умовні ймовірності P(Дитина + | Мати +) та P(Дитина + | Мати –):")
  107.  
  108.     p_child_pos_given_mother_pos = df_obs.loc["Мати +", "Дитина +"] / row_totals["Мати +"]
  109.     p_child_pos_given_mother_neg = df_obs.loc["Мати –", "Дитина +"] / row_totals["Мати –"]
  110.  
  111.     print(f"P(Дитина + | Мати +) = {p_child_pos_given_mother_pos:.4f}")
  112.     print(f"P(Дитина + | Мати –) = {p_child_pos_given_mother_neg:.4f}")
  113.  
  114.     expected = compute_expected_frequencies(df_obs)
  115.     print("\n4. Теоретичні (очікувані) частоти m_ij = (n_i· * n_·j) / N:")
  116.     print(expected.round(4))
  117.  
  118.     chi2_manual, contributions = compute_chi_square_manual(df_obs, expected)
  119.  
  120.     print("\n5. Внески в χ² по кожній клітинці:")
  121.     print(contributions.round(4))
  122.     print(f"\nЗначення критерію χ² (без поправки Йейтса) = {chi2_manual:.4f}")
  123.  
  124.     chi2_scipy_no, p_no, df_dof, _ = chi2_contingency(df_obs, correction=False)
  125.     chi2_scipy_y, p_y, df_dof_y, _ = chi2_contingency(df_obs, correction=True)
  126.  
  127.     print("\nПеревірка через scipy.stats.chi2_contingency:")
  128.     print(f"χ² (без поправки) = {chi2_scipy_no:.4f}, p-value = {p_no:.6f}, df = {df_dof}")
  129.     print(
  130.         f"χ² (з поправкою Йейтса) = {chi2_scipy_y:.4f}, p-value = {p_y:.6f}, df = {df_dof_y}"
  131.     )
  132.  
  133.     alpha = 0.05
  134.     dfree = 1
  135.     chi2_crit = chi2.ppf(1 - alpha, df=dfree)
  136.     print(f"\n6. Критичне значення χ² при α = {alpha}, df = {dfree}:")
  137.     print(f"χ²_crit = {chi2_crit:.4f}")
  138.  
  139.     print("\nПорівняння з критичним значенням:")
  140.     sign1 = ">" if chi2_manual > chi2_crit else "≤"
  141.     sign2 = ">" if chi2_scipy_y > chi2_crit else "≤"
  142.     print(f"χ² (без поправки) = {chi2_manual:.4f} {sign1} χ²_crit")
  143.     print(f"χ² (з поправкою Йейтса) = {chi2_scipy_y:.4f} {sign2} χ²_crit")
  144.  
  145.     phi, C = compute_measures(chi2_manual, N)
  146.  
  147.     p11 = joint.loc["Мати +", "Дитина +"]
  148.     p1dot = row_marginals["Мати +"]
  149.     pdot1 = col_marginals["Дитина +"]
  150.     num_r = p11 - p1dot * pdot1
  151.     den_r = np.sqrt(p1dot * (1 - p1dot) * pdot1 * (1 - pdot1))
  152.     R = num_r / den_r if den_r != 0 else np.nan
  153.  
  154.     print("\n7. Міри тісноти зв'язку:")
  155.     print(f"Фі-коефіцієнт φ = sqrt(χ² / N) = {phi:.4f}")
  156.     print(f"Коефіцієнт контингенції C = sqrt(χ² / (χ² + N)) = {C:.4f}")
  157.     print(f"Коефіцієнт кореляції R (Пірсона) = {R:.4f}")
  158.  
  159.     strength = interpret_correlation_strength(R)
  160.  
  161.     print("\n8. Висновок:")
  162.     if chi2_manual > chi2_crit:
  163.         print(
  164.             f"Оскільки χ² = {chi2_manual:.4f} > χ²_crit = {chi2_crit:.4f}, нульову гіпотезу про "
  165.             f"незалежність резус-фактора матері та дитини відхиляємо на рівні значущості α = {alpha}."
  166.         )
  167.         print(
  168.             "Отже, між резус-фактором матері та резус-фактора дитини існує статистично значущий зв'язок."
  169.         )
  170.     else:
  171.         print(
  172.             f"Оскільки χ² = {chi2_manual:.4f} ≤ χ²_crit = {chi2_crit:.4f}, немає підстав відхиляти "
  173.             f"нульову гіпотезу про незалежність ознак."
  174.         )
  175.         print(
  176.             "Статистично значущого зв'язку між резус-фактором матері та дитини не виявлено."
  177.         )
  178.  
  179.     print(
  180.         f"\nЗа значенням R ≈ {R:.3f} (φ ≈ {phi:.3f}, C ≈ {C:.3f}) тісноту зв'язку за шкалою "
  181.         f"Чеддока можна охарактеризувати як {strength}."
  182.     )
  183.  
  184.  
  185. if __name__ == "__main__":
  186.     main()
  187.  
Advertisement
Add Comment
Please, Sign In to add comment