Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import numpy as np
- import pandas as pd
- from scipy.stats import chi2_contingency, chi2
- def build_observed_table() -> pd.DataFrame:
- data = {
- "Дитина +": [84, 12],
- "Дитина –": [8, 8],
- }
- index = ["Мати +", "Мати –"]
- df_obs = pd.DataFrame(data, index=index)
- return df_obs
- def compute_relative_frequencies(df_obs: pd.DataFrame):
- N = df_obs.values.sum()
- joint = df_obs / N
- row_marginals = df_obs.sum(axis=1) / N
- col_marginals = df_obs.sum(axis=0) / N
- return joint, row_marginals, col_marginals
- def compute_expected_frequencies(df_obs: pd.DataFrame) -> pd.DataFrame:
- N = df_obs.values.sum()
- row_totals = df_obs.sum(axis=1)
- col_totals = df_obs.sum(axis=0)
- expected = pd.DataFrame(index=df_obs.index, columns=df_obs.columns, dtype=float)
- for i in df_obs.index:
- for j in df_obs.columns:
- expected.loc[i, j] = row_totals[i] * col_totals[j] / N
- return expected
- def compute_chi_square_manual(df_obs: pd.DataFrame, expected: pd.DataFrame) -> tuple[float, pd.DataFrame]:
- contributions = (df_obs - expected) ** 2 / expected
- chi2_value = contributions.values.sum()
- return chi2_value, contributions
- def compute_measures(chi2_value: float, N: int):
- phi = np.sqrt(chi2_value / N)
- C = np.sqrt(chi2_value / (chi2_value + N))
- return phi, C
- def interpret_correlation_strength(r: float) -> str:
- abs_r = abs(r)
- if abs_r < 0.3:
- return "майже відсутній"
- elif 0.3 <= abs_r < 0.5:
- return "слабкий"
- elif 0.5 <= abs_r < 0.7:
- return "помірний"
- elif 0.7 <= abs_r < 1.0:
- return "сильний"
- else:
- return "функціональний"
- def print_header() -> None:
- print("=== Аналіз взаємозв'язку між резус-фактором матері та дитини (Варіант 2) ===")
- def main() -> None:
- print_header()
- df_obs = build_observed_table()
- print("1. Вихідна таблиця спряженості (частоти n_ij):")
- print(df_obs)
- N = int(df_obs.values.sum())
- print(f"\nЗагальний обсяг вибірки N = {N}\n")
- row_totals = df_obs.sum(axis=1)
- col_totals = df_obs.sum(axis=0)
- print("Рядкові підсумки (n_i·):")
- print(row_totals)
- print("\nСтовпчикові підсумки (n_·j):")
- print(col_totals)
- joint, row_marginals, col_marginals = compute_relative_frequencies(df_obs)
- print("\n2. Спільні відносні частоти p_ij = n_ij / N:")
- print(joint.round(4))
- print("\nМаргінальні відносні частоти p_i· та p_·j:")
- print("p_i·:")
- print(row_marginals.round(4))
- print("\np_·j:")
- print(col_marginals.round(4))
- print("\n3. Умовні ймовірності P(Дитина + | Мати +) та P(Дитина + | Мати –):")
- p_child_pos_given_mother_pos = df_obs.loc["Мати +", "Дитина +"] / row_totals["Мати +"]
- p_child_pos_given_mother_neg = df_obs.loc["Мати –", "Дитина +"] / row_totals["Мати –"]
- print(f"P(Дитина + | Мати +) = {p_child_pos_given_mother_pos:.4f}")
- print(f"P(Дитина + | Мати –) = {p_child_pos_given_mother_neg:.4f}")
- expected = compute_expected_frequencies(df_obs)
- print("\n4. Теоретичні (очікувані) частоти m_ij = (n_i· * n_·j) / N:")
- print(expected.round(4))
- chi2_manual, contributions = compute_chi_square_manual(df_obs, expected)
- print("\n5. Внески в χ² по кожній клітинці:")
- print(contributions.round(4))
- print(f"\nЗначення критерію χ² (без поправки Йейтса) = {chi2_manual:.4f}")
- chi2_scipy_no, p_no, df_dof, _ = chi2_contingency(df_obs, correction=False)
- chi2_scipy_y, p_y, df_dof_y, _ = chi2_contingency(df_obs, correction=True)
- print("\nПеревірка через scipy.stats.chi2_contingency:")
- print(f"χ² (без поправки) = {chi2_scipy_no:.4f}, p-value = {p_no:.6f}, df = {df_dof}")
- print(
- f"χ² (з поправкою Йейтса) = {chi2_scipy_y:.4f}, p-value = {p_y:.6f}, df = {df_dof_y}"
- )
- alpha = 0.05
- dfree = 1
- chi2_crit = chi2.ppf(1 - alpha, df=dfree)
- print(f"\n6. Критичне значення χ² при α = {alpha}, df = {dfree}:")
- print(f"χ²_crit = {chi2_crit:.4f}")
- print("\nПорівняння з критичним значенням:")
- sign1 = ">" if chi2_manual > chi2_crit else "≤"
- sign2 = ">" if chi2_scipy_y > chi2_crit else "≤"
- print(f"χ² (без поправки) = {chi2_manual:.4f} {sign1} χ²_crit")
- print(f"χ² (з поправкою Йейтса) = {chi2_scipy_y:.4f} {sign2} χ²_crit")
- phi, C = compute_measures(chi2_manual, N)
- p11 = joint.loc["Мати +", "Дитина +"]
- p1dot = row_marginals["Мати +"]
- pdot1 = col_marginals["Дитина +"]
- num_r = p11 - p1dot * pdot1
- den_r = np.sqrt(p1dot * (1 - p1dot) * pdot1 * (1 - pdot1))
- R = num_r / den_r if den_r != 0 else np.nan
- print("\n7. Міри тісноти зв'язку:")
- print(f"Фі-коефіцієнт φ = sqrt(χ² / N) = {phi:.4f}")
- print(f"Коефіцієнт контингенції C = sqrt(χ² / (χ² + N)) = {C:.4f}")
- print(f"Коефіцієнт кореляції R (Пірсона) = {R:.4f}")
- strength = interpret_correlation_strength(R)
- print("\n8. Висновок:")
- if chi2_manual > chi2_crit:
- print(
- f"Оскільки χ² = {chi2_manual:.4f} > χ²_crit = {chi2_crit:.4f}, нульову гіпотезу про "
- f"незалежність резус-фактора матері та дитини відхиляємо на рівні значущості α = {alpha}."
- )
- print(
- "Отже, між резус-фактором матері та резус-фактора дитини існує статистично значущий зв'язок."
- )
- else:
- print(
- f"Оскільки χ² = {chi2_manual:.4f} ≤ χ²_crit = {chi2_crit:.4f}, немає підстав відхиляти "
- f"нульову гіпотезу про незалежність ознак."
- )
- print(
- "Статистично значущого зв'язку між резус-фактором матері та дитини не виявлено."
- )
- print(
- f"\nЗа значенням R ≈ {R:.3f} (φ ≈ {phi:.3f}, C ≈ {C:.3f}) тісноту зв'язку за шкалою "
- f"Чеддока можна охарактеризувати як {strength}."
- )
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment