T-test för jämförelse av medelvärden
Genomför t-test för ett stickprov, oberoende två stickprov och parade stickprov med scipy.stats och tolka konfidensintervall.
T-test för jämförelse av medelvärden är en gratis lektion i Pandas & NumPy Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Pandas & NumPy Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Pandas & NumPy Academy innehåller totalt 4 lektioner.
Vad är ett t-test?
Ett t-test är ett hypotesprövningstest som avgör om en skillnad i medelvärden mellan grupper är statistiskt signifikant eller sannolikt beror på slumpen. Det jämför den observerade skillnaden med variationen i data och ger en t-statistik och ett p-värde. Om p ≤ 0.05 (den konventionella gränsen) förkastar vi nollhypotesen att medelvärdena är lika. Det finns tre vanliga typer: one-sample, independent two-sample och paired t-test, som används för olika experimentella upplägg.
T-test för ett urval
T-testet för ett urval testar om medelvärdet i ett urval skiljer sig signifikant från ett känt eller hypotetiskt populationsmedelvärde. Exempel: ”Skiljer sig vår genomsnittliga leveranstid signifikant från branschstandarden på tre dagar?” Använd scipy.stats.ttest_1samp(data, popmean). Nollhypotesen är H₀: mean = popmean. Ett lågt p-värde leder till att Ni förkastar H₀ och drar slutsatsen att urvalets medelvärde skiljer sig från målvärdet.
import numpy as np
from scipy import stats
np.random.seed(42)
# Delivery times in days (true mean is ~3.5, not 3)
delivery_times = np.random.normal(loc=3.5, scale=0.8, size=50)
# Test: is our mean significantly different from 3 days?
stat, p = stats.ttest_1samp(delivery_times, popmean=3.0)
print(f'Sample mean: {delivery_times.mean():.3f}')
print(f't-statistic: {stat:.3f}')
print(f'p-value: {p:.4f}')
print('Differs from 3?', 'Yes' if p < 0.05 else 'No')Oberoende t-test för två urval
Det oberoende t-testet för två stickprov jämför medelvärdena för två oberoende grupper. Exempel: ”Ger A/B-testvarianten högre genomsnittlig intäkt än kontrollen?” Använd scipy.stats.ttest_ind(group_a, group_b). Parametern equal_var är viktig: ange equal_var=False (Welchs t-test) när de två grupperna kan ha olika varians, vilket är det säkra standardvalet för de flesta verkliga data.
import numpy as np
from scipy import stats
np.random.seed(0)
# A/B test revenue per session
control = np.random.normal(loc=25.0, scale=8.0, size=80)
variant = np.random.normal(loc=28.0, scale=9.0, size=80)
# Welch's t-test (does not assume equal variances)
stat, p = stats.ttest_ind(control, variant, equal_var=False)
print(f'Control mean: {control.mean():.2f}')
print(f'Variant mean: {variant.mean():.2f}')
print(f't-statistic: {stat:.3f}')
print(f'p-value: {p:.4f}')
print('Significant difference?', 'Yes' if p < 0.05 else 'No')Ensidiga kontra tvåsidiga test
Som standard är t-test tvåsidiga: de testar om medelvärdena skiljer sig i någon riktning (större ELLER mindre än). Om Ni har en riktad hypotes (”varianten ökar intäkten”) använder Ni ett ensidigt test med parametern alternative: 'greater' eller 'less'. Ett ensidigt test har större statistisk styrka i den specifika riktningen, men ger ingen evidens om den andra riktningen. Bestäm riktningen innan Ni granskar data för att undvika HARKing (Hypothesising After Results are Known).
import numpy as np
from scipy import stats
np.random.seed(1)
control = np.random.normal(25, 8, 100)
variant = np.random.normal(27, 8, 100)
# Two-tailed (default): does mean differ at all?
stat, p_two = stats.ttest_ind(control, variant, equal_var=False,
alternative='two-sided')
# One-tailed: is variant > control?
stat, p_one = stats.ttest_ind(control, variant, equal_var=False,
alternative='less')
print(f'Two-tailed p: {p_two:.4f}')
print(f'One-tailed p (variant greater): {p_one:.4f}')Parat t-test
Det parade t-testet används när varje observation i grupp A har en naturlig motsvarighet i grupp B – till exempel mätningar före och efter en behandling på samma försökspersoner, eller i samma butiker under två olika månader. Parningen kontrollerar för variation mellan försökspersoner, vilket gör testet mer kraftfullt än ett oberoende t-test för samma data. Använd scipy.stats.ttest_rel(before, after). Elementens ordning måste vara matchad: before[i] och after[i] måste komma från samma försöksperson.
import numpy as np
from scipy import stats
np.random.seed(5)
# Blood pressure before and after medication (paired)
before = np.random.normal(130, 10, 30)
after = before - np.random.normal(5, 3, 30) # Treatment reduces BP by ~5
stat, p = stats.ttest_rel(before, after)
print(f'Mean before: {before.mean():.2f}')
print(f'Mean after: {after.mean():.2f}')
print(f't-statistic: {stat:.3f}')
print(f'p-value: {p:.4f}')
print('Treatment effective?', 'Yes' if p < 0.05 else 'No')Tolka t-statistikan
t-statistikan mäter hur många standardfel den observerade skillnaden ligger från noll. En t-statistika på 2 innebär att den observerade skillnaden ligger 2 standardfel över det som skulle förväntas under nollhypotesen. För ett tvåsidigt test vid α=0.05 med ett stort stickprov är det kritiska värdet ungefär ±1.96 – alltså ger |t| > 1.96 p < 0.05. p-värdet omvandlar t-statistikan till en sannolikhet, vilket gör den enklare att tolka utan att använda tabeller över t-fördelningen.
import numpy as np
from scipy import stats
# Demonstrate relationship between t-statistic and p-value
for t_val in [1.0, 1.96, 2.5, 3.0, 4.0]:
# degrees of freedom = large sample -> t ~ normal
p = 2 * stats.t.sf(abs(t_val), df=100) # two-tailed
print(f't = {t_val:4.2f} -> p = {p:.4f} '
f'({'significant' if p < 0.05 else 'not significant'})')Konfidensintervall för medelskillnaden
Ett p-värde ensamt visar inte effektens storlek. Beräkna alltid ett konfidensintervall för medelskillnaden. Ett 95-procentigt KI som inkluderar noll är förenligt med p > 0.05 (inte signifikant); ett som inte inkluderar noll innebär att skillnaden är signifikant. KI:t visar också om effektstorleken är praktiskt betydelsefull – en statistiskt signifikant intäktsskillnad på $0.01 kan vara irrelevant, medan en skillnad på $50 med p=0.06 fortfarande kan vara viktig för verksamheten.
import numpy as np
from scipy import stats
np.random.seed(0)
control = np.random.normal(25, 8, 80)
variant = np.random.normal(28, 8, 80)
diff = variant.mean() - control.mean()
se = np.sqrt(control.var()/len(control) + variant.var()/len(variant))
df = len(control) + len(variant) - 2
t_crit = stats.t.ppf(0.975, df=df)
ci_low = diff - t_crit * se
ci_high = diff + t_crit * se
print(f'Mean difference: {diff:.2f}')
print(f'95% CI: [{ci_low:.2f}, {ci_high:.2f}]')
print('CI excludes zero:', ci_low > 0 or ci_high < 0)Effektstorlek: Cohens d
Statistisk signifikans beror på stickprovsstorleken – med tillräckligt stora stickprov blir även obetydliga skillnader signifikanta. Cohens d mäter praktisk signifikans (effektstorlek): medelskillnaden dividerad med den poolade standardavvikelsen. Riktlinjer: d < 0.2 är försumbar, 0.2–0.5 är liten, 0.5–0.8 är medelstor och > 0.8 är stor. Rapportera alltid effektstorleken tillsammans med p-värden – ett signifikant p-värde med d = 0.05 innebär att skillnaden är verklig, men troligen inte praktiskt betydelsefull.
import numpy as np
from scipy import stats
np.random.seed(0)
g1 = np.random.normal(25, 8, 200)
g2 = np.random.normal(28, 8, 200)
stat, p = stats.ttest_ind(g1, g2)
# Cohen's d
pooled_std = np.sqrt((g1.var() + g2.var()) / 2)
cohens_d = (g2.mean() - g1.mean()) / pooled_std
print(f'p-value: {p:.4f}')
print(f'Cohen\'s d: {cohens_d:.3f}')
if cohens_d < 0.2: print('Effect: negligible')
elif cohens_d < 0.5: print('Effect: small')
elif cohens_d < 0.8: print('Effect: medium')
else: print('Effect: large')Antaganden för t-testet
Det oberoende t-testet förutsätter: (1) oberoende – observationerna inom varje grupp är oberoende av varandra; (2) normalfördelning – data i varje grupp är ungefär normalfördelad (robust för n > 30 tack vare CLT); (3) för Students t-test (equal_var=True), lika varianser. Welchs t-test (equal_var=False) lättar på antagande 3 och bör föredras. När normalfördelningen är allvarligt avviktande vid små stickprov (< 30) använder Ni i stället Mann-Whitneys U-test.
import numpy as np
from scipy import stats
np.random.seed(0)
g1 = np.random.normal(10, 2, 30)
g2 = np.random.normal(11, 5, 30) # Very different variance!
# Levene test for equal variances
stat_l, p_l = stats.levene(g1, g2)
print(f'Levene test p: {p_l:.4f}')
if p_l < 0.05:
print('Unequal variances -> use Welch\'s (equal_var=False)')
stat, p = stats.ttest_ind(g1, g2, equal_var=False)
else:
print('Equal variances OK -> Student\'s t-test')
stat, p = stats.ttest_ind(g1, g2, equal_var=True)
print(f'Result: t={stat:.3f}, p={p:.4f}')T-test på Pandas Series
I praktiken finns de data Ni vill testa i en kolumn i en Pandas DataFrame. Ni kan skicka en Pandas Series direkt till funktioner i scipy.stats – de fungerar smidigt både med Series och NumPy-arrayer. Ett vanligt arbetsflöde är att filtrera DataFrame för att få varje grupps Series, köra t-testet och lagra resultaten i en sammanfattande DataFrame. Detta mönster kan skalas till att testa många kolumn- eller grupppar i en loop.
import pandas as pd
import numpy as np
from scipy import stats
np.random.seed(0)
df = pd.DataFrame({
'group': ['A']*60 + ['B']*60,
'revenue': np.concatenate([
np.random.normal(100, 20, 60),
np.random.normal(110, 22, 60)
])
})
grp_a = df.loc[df['group'] == 'A', 'revenue']
grp_b = df.loc[df['group'] == 'B', 'revenue']
stat, p = stats.ttest_ind(grp_a, grp_b, equal_var=False)
print(f'A mean: {grp_a.mean():.2f}, B mean: {grp_b.mean():.2f}')
print(f'p-value: {p:.4f}')Problemet med multipla jämförelser
Om Ni kör många t-test samtidigt ökar risken för ett falskt positivt resultat. Om Ni kör 20 t-test med α=0.05 förväntar Ni Er 1 falskt positivt resultat av en slump. Detta är problemet med multipla jämförelser. Tillämpa Bonferroni-korrigering: dividera α med antalet test (p_threshold = 0.05 / n_tests). För större statistisk styrka med mindre konservatism kan Ni använda Benjamini-Hochbergs korrigering för falsk upptäcktsfrekvens (FDR) i statsmodels. Korrigera alltid för multipla jämförelser i A/B-tester med många mätvärden.
import numpy as np
from scipy import stats
np.random.seed(0)
n_tests = 10
results = []
for i in range(n_tests):
g1 = np.random.normal(0, 1, 50)
g2 = np.random.normal(0.1, 1, 50) # Tiny true effect
_, p = stats.ttest_ind(g1, g2)
results.append(p)
print('p-values:', [round(p, 3) for p in results])
bonferroni_thresh = 0.05 / n_tests
print(f'Bonferroni threshold: {bonferroni_thresh}')
print('Significant after Bonferroni:', sum(p < bonferroni_thresh for p in results))Snabbtest
Testa Er förståelse av begreppen inom dataanalys från den här lektionen.
Sammanfattning av lektionen
I den här lektionen har Ni lärt Er att: ttest_1samp testar ett stickprovsmedelvärde mot ett referensvärde, ttest_ind (Welchs med equal_var=False) jämför två oberoende grupper och ttest_rel hanterar parade mätningar. Rapportera alltid Cohens d tillsammans med p-värdet för att skilja statistisk från praktisk signifikans. Nästa steg är att testa samband mellan kategoriska variabler med chi-två-testet.
Lär dig Python med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”T-test för jämförelse av medelvärden” gratis?
Ja – hela texten till ”T-test för jämförelse av medelvärden” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Pandas & NumPy Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Pandas & NumPy Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”T-test för jämförelse av medelvärden”?
Genomför t-test för ett stickprov, oberoende två stickprov och parade stickprov med scipy.stats och tolka konfidensintervall. Ni övar på Pandas & NumPy Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Pandas & NumPy Academy?
Du behöver inga förkunskaper. Utbildningen i Pandas & NumPy Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”T-test för jämförelse av medelvärden”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Pandas & NumPy Academy-lektionen?
Ja. Varje Pandas & NumPy Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Deskriptiv statistik och normalitetstest
- T-test för jämförelse av medelvärden
- Chi-två-test för oberoende
- ANOVA och post-hoc-test