Think Stats kitabının üçüncü baskısını Bookshop.org ve Amazon üzerinden edinebilirsiniz (bunlar satış ortaklığı bağlantılarıdır). Ücretsiz çevrimiçi sürümü beğeniyorsanız bana bir kahve ısmarlamayı düşünebilirsiniz.
7. Değişkenler arasındaki ilişkiler#
Şimdiye kadar değişkenleri yalnızca birer birer inceledik. Bu bölümde değişkenler arasındaki ilişkilere bakmaya başlayacağız. Bir değişkeni bilmek diğeri hakkında bilgi sağlıyorsa bu iki değişken ilişkilidir. Örneğin boy ile ağırlık ilişkilidir; daha uzun kişiler daha ağır olma eğilimindedir. Elbette bu kusursuz bir ilişki değildir: kısa ve ağır ya da uzun ve hafif insanlar vardır. Yine de birinin ağırlığını tahmin etmeye çalışıyorsanız boyunu bildiğinizde, bilmediğiniz duruma göre daha doğru sonuç alırsınız.
Bu bölüm, değişkenler arasındaki ilişkileri görselleştirmenin çeşitli yollarını ve ilişkinin gücünü nicelleştirmenin bir yolu olan korelasyonu sunar.
Bu notebook’u Colab’da çalıştırmak için buraya tıklayın.
7.1. Saçılım grafikleri#
Matematikte olağanüstü iyi biriyle tanışsanız, sözel becerilerinin ortalamanın üstünde mi yoksa altında mı olmasını beklersiniz? Bir yandan insanların alanlardan birinde uzmanlaştığını, dolayısıyla birinde çok başarılı olanın diğerinde daha az başarılı olabileceğini düşünebilirsiniz. Öte yandan genel olarak zeki birinin iki alanda da ortalamanın üzerinde olmasını bekleyebilirsiniz. Hangisinin doğru olduğunu öğrenelim.
“1980–84 yılları arasında doğan 8.984 Amerikalı gençten oluşan bir örneklemin yaşamını izleyen” 1997 Ulusal Boylamsal Gençlik Araştırması’nın (NLSY97) verilerini kullanacağız. Herkese açık veri kümesi, katılımcıların üniversiteye kabulde en sık kullanılan SAT ve ACT de dâhil olmak üzere çeşitli standartlaştırılmış sınavlardaki puanlarını içerir. Sınava girenler matematik ve sözel bölümlerden ayrı puanlar aldığı için bu verilerle matematiksel ve sözel beceri arasındaki ilişkiyi inceleyebiliriz.
Bu analizde kullanacağım değişkenleri içeren bir alt küme oluşturmak için NLS Investigator’ı kullandım. İzinleri sayesinde bu alt kümeyi yeniden dağıtabiliyorum. Verileri indirme yönergeleri bu bölümün notebook’unda yer alıyor.
download("https://github.com/TerekliTahaBerk/thinkstatstr/raw/v3/data/nlsy97-extract.csv.gz")
Verileri okumak için read_csv, eksik verileri belirten özel kodları np.nan ile değiştirmek için replace kullanabiliriz.
missing_codes = [-1, -2, -3, -4, -5]
nlsy = pd.read_csv("nlsy97-extract.csv.gz").replace(missing_codes, np.nan)
nlsy.shape
(8984, 34)
nlsy.head()
| R0000100 | R0490200 | R0536300 | R0536401 | R0536402 | R1235800 | R1318200 | R1482600 | R3961900 | R3989200 | ... | R9872200 | R9872300 | R9872400 | S1552700 | U0008900 | U1845500 | U3444000 | U4949700 | Z9083800 | Z9083900 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | NaN | 2 | 9 | 1981 | 1 | NaN | 4 | NaN | NaN | ... | 293.0 | 250.0 | 333.0 | NaN | 120000.0 | NaN | NaN | NaN | 16.0 | 4.0 |
| 1 | 2 | NaN | 1 | 7 | 1982 | 1 | 145.0 | 2 | NaN | NaN | ... | 114.0 | 230.0 | 143.0 | NaN | 98928.0 | 116000.0 | 188857.0 | 180000.0 | 14.0 | 2.0 |
| 2 | 3 | NaN | 2 | 9 | 1983 | 1 | 82.0 | 2 | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 75000.0 | 16.0 | 4.0 |
| 3 | 4 | NaN | 2 | 2 | 1981 | 1 | NaN | 2 | NaN | NaN | ... | 195.0 | 230.0 | 216.0 | NaN | 85000.0 | 45000.0 | NaN | NaN | 13.0 | 2.0 |
| 4 | 5 | NaN | 1 | 10 | 1982 | 1 | NaN | 2 | NaN | NaN | ... | 293.0 | 230.0 | 231.0 | NaN | 210000.0 | 212000.0 | NaN | 240000.0 | 12.0 | 2.0 |
5 rows × 34 columns
DataFrame, araştırmadaki 8.984 katılımcının her biri için bir satır ve seçtiğim 34 değişkenin her biri için bir sütun içerir. Sütun adları tek başlarına pek anlamlı değil; bu nedenle kullanacaklarımızı daha anlaşılır adlarla değiştirelim.
nlsy["sat_verbal"] = nlsy["R9793800"]
nlsy["sat_math"] = nlsy["R9793900"]
Her iki sütunda da 200’den küçük birkaç değer var. En düşük olası puan 200 olduğundan bunları np.nan ile değiştireceğiz.
columns = ["sat_verbal", "sat_math"]
for column in columns:
invalid = nlsy[column] < 200
nlsy.loc[invalid, column] = np.nan
Ardından yalnızca iki puanın da geçerli olduğu satırları seçmek için dropna kullanacağız.
nlsy_valid = nlsy.dropna(subset=columns).copy()
nlsy_valid.shape
(1398, 36)
SAT puanları, ortalaması 500 ve standart sapması 100 olacak şekilde standartlaştırılır. NLSY örneklemindeki ortalamalar ve standart sapmalar bu değerlere yakındır.
sat_verbal = nlsy_valid["sat_verbal"]
sat_verbal.mean(), sat_verbal.std()
(np.float64(501.80972818311875), np.float64(108.36562024213643))
sat_math = nlsy_valid["sat_math"]
sat_math.mean(), sat_math.std()
(np.float64(503.0829756795422), np.float64(109.8329973731453))
Bu değişkenler arasında bir ilişki olup olmadığını görmek için şimdi bir saçılım grafiğine bakalım.
plt.scatter(sat_verbal, sat_math)
decorate(xlabel="SAT sözel", ylabel="SAT matematik")
scatter işlevinin varsayılan seçenekleriyle ilişkinin genel biçimini görebiliriz. Sınavın bir bölümünde başarılı olan kişiler diğer bölümünde de daha başarılı olma eğilimindedir.
Ancak şeklin bu sürümünde üst üste binme vardır; yani çok sayıda nokta üst üste biner ve bu durum ilişki hakkında yanıltıcı bir izlenim yaratabilir. Nokta yoğunluğunun en yüksek olduğu merkez, olması gerektiği kadar koyu görünmez; buna karşılık uç değerler gereğinden koyu görünür. Üst üste binme, aykırı değerlere gereğinden fazla görsel ağırlık verme eğilimindedir.
İşaretçilerin boyutunu küçültüp daha az üst üste gelmelerini sağlayarak grafiği iyileştirebiliriz.
plt.scatter(sat_verbal, sat_math, s=5)
decorate(xlabel="SAT sözel", ylabel="SAT matematik")
Puanlar en yakın 10’un katına yuvarlandığı için işaretçilerin satırlar ve sütunlar hâlinde hizalandığını artık görebiliyoruz. Bu süreçte bazı bilgiler kaybolur.
Bu bilgiyi geri getiremeyiz; ancak yuvarlamanın etkisini tersine çevirmek üzere rastgele gürültü eklemek anlamına gelen rastgele konum kaydırma (jitter) işlemiyle saçılım grafiğindeki etkiyi azaltabiliriz. Aşağıdaki işlev bir dizi alır ve ortalaması 0, standart sapması verilen değere eşit normal dağılımdan rastgele değerler ekler. Sonuç bir NumPy dizisidir.
def jitter(seq, std=1):
n = len(seq)
return np.random.normal(0, std, n) + seq
Puanlara standart sapması 3 olan rastgele gürültü eklediğimizde saçılım grafiğinde satırlar ve sütunlar artık görünmez.
sat_verbal_jittered = jitter(sat_verbal, 3)
sat_math_jittered = jitter(sat_math, 3)
plt.scatter(sat_verbal_jittered, sat_math_jittered, s=5)
decorate(xlabel="SAT sözel", ylabel="SAT matematik")
Jitter uygulamak, yuvarlamanın görsel etkisini azaltır ve ilişkinin biçimini daha belirgin kılar. Ancak genel olarak konumları kaydırılmış verileri yalnızca görselleştirme amacıyla kullanmalı, analizde kullanmaktan kaçınmalısınız.
Bu örnekte işaretçi boyutunu ayarlayıp verilerin konumunu rastgele kaydırdıktan sonra bile bir miktar üst üste binme var. Bir şey daha deneyelim: işaretçileri kısmen saydam yapmak için alpha anahtar sözcüğünü kullanabiliriz.
plt.scatter(sat_verbal_jittered, sat_math_jittered, s=5, alpha=0.2)
decorate(xlabel="SAT sözel", ylabel="SAT matematik")
Saydamlık kullanıldığında üst üste binen veri noktaları daha koyu görünür; böylece koyuluk yoğunlukla orantılı olur.
Saçılım grafikleri basit ve yaygın kullanılan bir görselleştirme olsa da doğru biçimde hazırlanmaları zor olabilir. Değişkenler arasındaki ilişkinin en iyi görsel gösterimini bulmak için işaretçi boyutunu, saydamlığı ve konum kaydırma miktarını ayarlarken genellikle bir miktar deneme yanılma gerekir.
7.2. Desil grafikleri#
Saçılım grafikleri değişkenler arasındaki ilişki hakkında genel bir izlenim verir; ancak ilişkinin niteliğine dair daha fazla fikir sağlayan başka görselleştirmeler de vardır. Bunlardan biri desil grafiğidir.
Desil grafiği oluşturmak için katılımcıları sözel puana göre sıralayıp desil denen 10 gruba ayıracağız. Dilimleri hesaplamak için qcut yöntemini kullanabiliriz.
deciles = pd.qcut(nlsy_valid["sat_verbal"], 10, labels=False) + 1
deciles.value_counts().sort_index()
sat_verbal
1 142
2 150
3 139
4 140
5 159
6 130
7 148
8 121
9 138
10 131
Name: count, dtype: int64
Her dilimdeki katılımcı sayısı yaklaşık olarak eşittir.
Şimdi DataFrame’i decile değerine göre gruplara ayırmak için groupby yöntemini kullanabiliriz.
df_groupby = nlsy_valid.groupby(deciles)
df_groupby
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x1406933e0>
Sonuç, grupları temsil eden bir DataFrameGroupBy nesnesidir. Bu nesneden sat_math sütununu seçebiliriz.
series_groupby = df_groupby["sat_math"]
series_groupby
<pandas.core.groupby.generic.SeriesGroupBy object at 0x14312fd70>
Sonuç, her dilimdeki matematik puanlarını temsil eden bir SeriesGroupBy nesnesidir. Her gruptaki 10., 50. ve 90. yüzdelik dilimleri hesaplamak için quantile işlevini kullanabiliriz.
low = series_groupby.quantile(0.1)
median = series_groupby.quantile(0.5)
high = series_groupby.quantile(0.9)
Desil grafiği, her dilim grubu için bu yüzdelikleri gösterir. Aşağıdaki şekilde çizgi medyanı, gölgeli bölge ise 10. ile 90. yüzdelikler arasındaki alanı gösteriyor.
xs = median.index
plt.fill_between(xs, low, high, alpha=0.2)
plt.plot(xs, median, label="medyan")
decorate(xlabel="SAT sözel puanı desili", ylabel="SAT matematik")
Başka bir seçenek olarak her gruptaki medyan sözel puanı hesaplayıp x ekseninde dilim numaraları yerine bu değerleri çizebiliriz.
xs = df_groupby["sat_verbal"].median()
plt.fill_between(xs, low, high, alpha=0.2)
plt.plot(xs, median, color="C0", label="medyan")
decorate(xlabel="SAT sözel", ylabel="SAT matematik")
Bu değişkenler arasındaki ilişki doğrusal görünüyor; yani medyan sözel puandaki her artış, medyan matematik puanında yaklaşık olarak eşit bir artışa karşılık geliyor.
Daha genel olarak katılımcıları mutlaka 10 olmak zorunda olmayan herhangi bir sayıda gruba ayırabilir ve her grupta yalnızca bu yüzdelikleri değil, başka özet istatistikleri de hesaplayabiliriz.
7.3. Korelasyon#
NLSY katılımcılarının çoğu 9. sınıftayken Peabody Bireysel Başarı Testi’nin (PIAT) matematik bölümüne girdi. Sonuçları içeren sütuna daha anlaşılır bir ad verelim.
nlsy["piat_math"] = nlsy["R1318200"]
nlsy["piat_math"].describe()
count 6044.000000
mean 93.903706
std 14.631148
min 55.000000
25% 84.000000
50% 92.000000
75% 103.000000
max 145.000000
Name: piat_math, dtype: float64
Puanların dağılımı şöyle görünür.
from empiricaldist import Cdf
cdf_piat_math = Cdf.from_seq(nlsy["piat_math"], name="PIAT matematik")
cdf_piat_math.step()
decorate(ylabel="CDF")
sınıfta PIAT’ta başarılı olan öğrencilerin 12. sınıfta SAT matematik bölümünde de başarılı olma olasılığı yüksektir. Her iki sınava da giren NLSY katılımcıları için aşağıdaki saçılım grafiği puanlar arasındaki ilişkiyi gösterir. Grafik,
thinkstatsiçindekiscatterişlevini kullanır; bu işlev işaretçi boyutunu ve saydamlığı ayarlar, isteğe bağlı olarak noktaların konumunu rastgele kaydırır.
from thinkstats import scatter
scatter(nlsy, "piat_math", "sat_math")
decorate(xlabel="PIAT matematik", ylabel="SAT matematik")
Beklendiği gibi PIAT’ta başarılı olan öğrenciler SAT matematikte de başarılı olma eğilimindedir. Matematik ve sözel beceri birbiriyle ilişkiliyse SAT sözel bölümünde de başarılı olmalarını bekleriz. Aşağıdaki şekil PIAT ile SAT sözel puanları arasındaki ilişkiyi gösteriyor.
scatter(nlsy, "piat_math", "sat_verbal")
decorate(xlabel="PIAT matematik", ylabel="SAT sözel")
PIAT puanı daha yüksek olan öğrencilerin SAT sözel puanları da ortalama olarak daha yüksektir.
Saçılım grafiklerini karşılaştırdığımızda ilk şekildeki noktalar daha sıkışık, ikinci şekildekiler ise daha dağınık görünebilir. Öyleyse PIAT matematik puanları, SAT matematik puanlarını SAT sözel puanlarına göre daha doğru tahmin ediyor demektir; böyle olması da anlamlıdır.
Bu ilişkilerin gücünü nicelleştirmek için çoğu zaman yalnızca “korelasyon” denen Pearson korelasyon katsayısını kullanabiliriz. Korelasyonu anlamak için standartlaştırmayla başlayalım.
Bir değişkeni standartlaştırmak için aşağıdaki işlevde olduğu gibi ortalamayı çıkarır ve standart sapmaya böleriz.
def standardize(xs):
"""Bir sayı dizisini standartlaştırır.
xs: sayı dizisi
döndürür: NumPy dizisi
"""
return (xs - np.mean(xs)) / np.std(xs)
Nasıl kullanıldığını göstermek için piat_math ve sat_math değerlerinin geçerli olduğu satırları seçeceğiz.
valid = nlsy.dropna(subset=["piat_math", "sat_math"])
piat_math = valid["piat_math"]
sat_math = valid["sat_math"]
Ardından PIAT matematik puanlarını standartlaştıracağız.
piat_math_standard = standardize(piat_math)
np.mean(piat_math_standard), np.std(piat_math_standard)
(np.float64(-2.4321756236287047e-16), np.float64(1.0))
Sonuçlar, z puanları olarak da bilinen standart skorlardır. Standart skorların hesaplanma biçimi nedeniyle ortalama 0’a, standart sapma ise 1’e yakındır.
SAT matematik puanlarını da standartlaştıralım.
sat_math_standard = standardize(sat_math)
np.mean(sat_math_standard), np.std(sat_math_standard)
(np.float64(-1.737268302591932e-16), np.float64(0.9999999999999998))
Aşağıdaki şekil ilk 100 katılımcıya ait bu puan dizilerini gösteriyor.
subplot işlevini 2, 1, 1 argümanlarıyla çağırmak, Matplotlib’e iki satır ve bir sütunda düzenlenmiş birden çok grafik oluşturmasını ve ilk grafiği başlatmasını söyler. İşlevi 2, 1, 2 argümanlarıyla yeniden çağırmak ikinci grafiği başlatır. axhline, eksenlerin genişliği boyunca uzanan yatay bir çizgi çizer.
Bu değişkenler açıkça ilişkilidir: biri ortalamanın üzerindeyken diğerinin de ortalamanın üzerinde olma olasılığı yüksektir. İlişkinin gücünü nicelleştirmek için standart skorları öğe öğe çarpıp çarpımların ortalamasını hesaplayacağız.
İki puan da pozitif olduğunda çarpımları pozitiftir ve ortalama çarpımı artırma eğilimindedir. İki puan da negatif olduğunda çarpımları yine pozitiftir ve ortalama çarpımı artırır. Puanlar zıt işaretli olduğunda çarpım negatiftir ve ortalamayı azaltır. Sonuç olarak ortalama çarpım, diziler arasındaki benzerliği ölçer.
np.mean(piat_math_standard * sat_math_standard)
np.float64(0.639735816517885)
Yaklaşık 0,64 olan sonuç korelasyon katsayısıdır. Şöyle yorumlanabilir: Birinin PIAT matematik puanı ortalamanın 1 standart sapma üzerindeyse SAT matematik puanının ortalama olarak ortalamanın 0,64 standart sapma üzerinde olmasını bekleriz.
Öğeleri ters sırada çarptığımızda da sonuç aynıdır.
np.mean(sat_math_standard * piat_math_standard)
np.float64(0.639735816517885)
Dolayısıyla korelasyon katsayısı simetriktir: Birinin SAT matematik puanı ortalamanın 1 standart sapma üzerindeyse PIAT matematik puanının ortalama olarak ortalamanın 0,64 standart sapma üzerinde olmasını bekleriz.
Korelasyon yaygın kullanılan bir istatistik olduğundan NumPy bunu hesaplayan bir işlev sağlar.
np.corrcoef(piat_math, sat_math)
array([[1. , 0.63973582],
[0.63973582, 1. ]])
Sonuç, her değişken için bir satır ve bir sütun içeren bir korelasyon matrisidir. Sol üstteki değer piat_math değişkeninin kendisiyle, sağ alttaki değer ise sat_math değişkeninin kendisiyle korelasyonudur. Her değişkenin kendisiyle korelasyonu 1’dir ve bu kusursuz korelasyonu gösterir.
Sağ üst ve sol alttaki değerler sırasıyla piat_math ile sat_math ve sat_math ile piat_math korelasyonlarıdır; zorunlu olarak birbirlerine eşittirler.
thinkstats, bir DataFrame ve iki sütun adı alan, iki sütunun da geçerli olduğu satırları seçip korelasyonlarını hesaplayan corrcoef işlevini sağlar.
from thinkstats import corrcoef
corrcoef(nlsy, "piat_math", "sat_math")
np.float64(0.639735816517885)
Bu işlevi piat_math ile sat_verbal korelasyonunu hesaplamak için kullanabiliriz.
corrcoef(nlsy, "piat_math", "sat_verbal")
np.float64(0.5094139146967309)
Korelasyon yaklaşık 0,51’dir. Dolayısıyla birinin PIAT matematik puanı ortalamanın bir standart sapma üzerindeyse SAT sözel puanının ortalama olarak ortalamanın 0,51 standart sapma üzerinde olmasını bekleriz.
Bekleyebileceğimiz gibi PIAT matematik puanları, SAT matematik puanlarını SAT sözel puanlarından daha iyi tahmin eder.
7.4. Korelasyonun gücü#
Daha fazla saçılım grafiği gördükçe farklı korelasyonların nasıl göründüğüne dair sezgi geliştirirsiniz. Bu sezgiyi geliştirmenize yardımcı olmak için aşağıdaki şekil, farklı korelasyonlara sahip rastgele üretilmiş verilerin saçılım grafiklerini gösteriyor.
np.random.seed(17)
xs = np.random.normal(size=300)
ys = np.random.normal(size=300)
“Rho” diye yazılan ve “ro” diye okunan Yunanca ρ harfi, korelasyon katsayısının geleneksel simgesidir.
Korelasyon negatif de olabilir. Aşağıda çeşitli negatif korelasyonlara sahip rastgele verilerin saçılım grafikleri yer alıyor.
Korelasyon katsayısı her zaman -1 ile 1 arasındadır. İki değişken arasında ilişki yoksa korelasyonları 0’dır; ancak korelasyonun 0 olması mutlaka ilişki olmadığı anlamına gelmez.
Özellikle doğrusal olmayan bir ilişki varsa korelasyon katsayısı 0’a yakın olabilir. Aşağıdaki örneklerin her birinde, değerlerden biri verildiğinde diğeri için çok daha iyi bir tahmin yapabilmemiz anlamında değişkenler arasında açık bir ilişki vardır. Buna karşın her durumda korelasyon katsayısı 0’a yakındır.
Korelasyon, değişkenler arasındaki doğrusal ilişkinin gücünü nicelleştirir. Doğrusal olmayan bir ilişki varsa korelasyon katsayısı yanıltıcı olabilir. Korelasyonun 0’a yakın olması da ilişki olmadığı anlamına gelmez.
7.5. Sıra korelasyonu#
NLSY boylamsaldır; yani aynı insan grubunu zaman içinde izler. İncelediğimiz grupta 1980 ile 1984 arasında doğan kişiler bulunuyor. SAT’a girenler muhtemelen 18 yaşlarındayken, 1990’ların sonlarında sınava girdi. Dolayısıyla 2021’de gelirleri sorulduğunda 30’larının sonu ya da 40’larının başındaydılar. Gelir verilerini içeren sütuna daha anlaşılır bir ad verelim.
nlsy["income"] = nlsy["U4949700"]
nlsy["income"].describe()
count 6051.000000
mean 104274.239960
std 108470.571497
min 0.000000
25% 38000.000000
50% 80000.000000
75% 134157.000000
max 599728.000000
Name: income, dtype: float64
Bu sütundaki değerler, katılımcı ile hanedeki diğer kişilerin tüm kaynaklardan elde ettiği ve ABD doları (USD) cinsinden bildirilen toplam gelir olan brüt aile geliridir. Gelir dağılımı şöyle görünür.
cdf_income = Cdf.from_seq(nlsy["income"])
cdf_income.step()
decorate(xlabel="Gelir (USD)", ylabel="CDF")
600.000 dolar civarındaki basamağa dikkat edin; katılımcıların anonimliklerini korumak için bu eşiğin üzerindeki değerler üstten sınırlandırılmıştır. Şimdi katılımcıların SAT matematik puanları ile yaşamlarının ilerleyen dönemindeki gelirlerinin saçılım grafiğine bakalım.
scatter(nlsy, "piat_math", "income")
decorate(xlabel="PIAT matematik", ylabel="Aile geliri (USD)")
Bu değişkenler arasında bir ilişki var gibi görünüyor. Korelasyon şöyledir.
corrcoef(nlsy, "piat_math", "income")
np.float64(0.3033858728864124)
Korelasyon yaklaşık 0,3’tür. Bu, 15 yaşındaki birinin PIAT matematik puanı ortalamanın bir standart sapma üzerindeyse 40 yaşındaki gelirinin ortalama olarak ortalamanın yaklaşık 0,3 standart sapma üzerinde olmasını beklediğimiz anlamına gelir. Bu ilişki PIAT ile SAT puanları arasındaki korelasyon kadar güçlü değildir; ancak geliri etkileyen etmenlerin sayısı düşünüldüğünde oldukça güçlüdür.
Aslında Pearson korelasyon katsayısı ilişkinin gücünü olduğundan düşük gösterebilir. Önceki saçılım grafiğinde gördüğümüz gibi iki değişkende de uçlarda belirgin bir değer fazlalığı vardır. Korelasyon katsayısı, ortalamadan sapmaların çarpımına dayandığı için bu uç değerlere duyarlıdır.
Daha dirençli bir seçenek, standartlaştırılmış puanlar yerine değerlerin sıralarına dayanan sıra korelasyonudur. Her puanın ve gelirin sırasını hesaplamak için Pandas’ın rank yöntemini kullanabiliriz.
valid = nlsy.dropna(subset=["piat_math", "income"])
piat_math_rank = valid["piat_math"].rank(method="first")
income_rank = valid["income"].rank(method="first")
method="first" argümanıyla rank, 1’den dizinin uzunluğu olan 4101’e kadar sıra değerleri atar.
income_rank.min(), income_rank.max()
(np.float64(1.0), np.float64(4101.0))
Gelir sıraları ile matematik puanı sıralarının saçılım grafiği şöyledir.
plt.scatter(piat_math_rank, income_rank, s=5, alpha=0.2)
decorate(xlabel="PIAT matematik sırası", ylabel="Gelir sırası")
Sıraların korelasyonu ise şöyledir.
np.corrcoef(piat_math_rank, income_rank)[0, 1]
np.float64(0.38148396696764847)
Sonuç yaklaşık 0,38’dir; 0,30 olan Pearson korelasyonundan biraz daha yüksektir. Sıra korelasyonu uç değerlerin etkisine daha az duyarlı olduğundan bu değişkenler arasındaki ilişkinin gücü için muhtemelen daha iyi bir ölçüdür.
thinkstats, bu bölümdeki kodu kapsayan bir rankcorr işlevi sağlar.
from thinkstats import rankcorr
rankcorr(nlsy, "piat_math", "income")
np.float64(0.38474681505344815)
Sıra korelasyonu Spearman korelasyonu olarak da bilindiği için SciPy, spearmanr adlı benzer bir işlev sağlar.
from scipy.stats import spearmanr
spearmanr(valid["piat_math"], valid["income"]).statistic
np.float64(0.38474681505344815)
Bir alıştırmada hem Pearson korelasyonunu hem sıra korelasyonunu kullanarak SAT sözel puanları ile gelir arasındaki korelasyonu hesaplama fırsatınız olacak.
7.6. Korelasyon ve nedensellik#
A ve B değişkenleri korelasyonluysa gözlenen korelasyon rastgele örneklemeden, temsil edici olmayan örneklemeden ya da evrendeki nicelikler arasında gerçek bir korelasyondan kaynaklanabilir.
Korelasyon gerçekse üç olası açıklama vardır: A, B’ye neden olur; B, A’ya neden olur; ya da başka etmenler hem A’ya hem B’ye neden olur. Bu açıklamalara “nedensel ilişkiler” denir.
Korelasyon tek başına bu açıklamalar arasında ayrım yapamaz ve hangilerinin doğru olduğunu söylemez. Bu kural çoğu zaman “Korelasyon nedensellik anlamına gelmez” sözüyle özetlenir; söz o kadar özlüdür ki kendine ait bir Vikipedi sayfası vardır.
http://wikipedia.org/wiki/Correlation_does_not_imply_causation
Öyleyse nedenselliğe kanıt sağlamak için ne yapabilirsiniz?
Zamandan yararlanın. A, B’den önce geliyorsa A, B’ye neden olabilir; tersi olamaz. Olayların sırası nedenselliğin yönünü çıkarsamamıza yardımcı olabilir, ancak başka bir şeyin hem A’ya hem B’ye neden olma olasılığını ortadan kaldırmaz.
Rastgelelikten yararlanın. Büyük bir örneklemi rastgele iki gruba ayırıp hemen her değişkenin ortalamasını hesaplarsanız farkın küçük olmasını beklersiniz. Gruplar A ve B dışındaki tüm değişkenlerde neredeyse aynıysa başka bir şeyin hem A’ya hem B’ye neden olma olasılığını eleyebilirsiniz.
Bu düşünceler, deneklerin rastgele iki ya da daha fazla gruba atandığı randomize kontrollü deneyin temelidir: müdahale grubu yeni bir ilaç gibi bir müdahale alır; kontrol grubu ise müdahale almaz ya da etkisi bilinen başka bir tedavi alır. Rastgele kontrollü deney, nedensel ilişki göstermenin en güvenilir yolu ve kanıta dayalı tıbbın temelidir.
Ne yazık ki kontrollü deneyler bazen olanaksız ya da etik dışıdır. Başka bir seçenek, benzer grupların araştırmacının denetimi dışındaki koşullar nedeniyle farklı durumlara maruz kaldığı bir doğal deney aramaktır.
Nedensel ilişkileri belirleyip ölçmek, istatistiğin nedensel çıkarım adlı dalının konusudur.
7.7. Sözlük#
saçılım grafiği (scatter plot): Veri kümesindeki her gözlem için bir nokta çizerek iki değişken arasındaki ilişkiyi gösteren görselleştirme.
üst üste binmiş (overplotted): Çok sayıda işaretçi üst üste bindiği için farklı yoğunluktaki alanların ayırt edilemediği ve ilişkinin yanlış yansıtılabildiği saçılım grafiği.
rastgele konum kaydırma (jitter): Üst üste binen değerleri daha görünür kılmak için grafikteki veri noktalarına eklenen rastgele gürültü.
desil grafiği (decile plot): Veriyi bir değişkene göre on dilime ayırıp her grup için başka bir değişkeni özetleyen grafik.
desil (decile): Veriyi sıralayıp yaklaşık olarak eşit on parçaya ayırarak oluşturulan gruplardan biri.
Pearson korelasyon katsayısı: İki değişken arasındaki doğrusal ilişkinin gücünü ve işaretini ölçen istatistik.
standart skor (standard score): Ortalamadan standart sapma birimleriyle uzaklığı gösterecek biçimde standartlaştırılmış nicelik.
korelasyon matrisi (correlation matrix): Veri kümesindeki her değişken çifti için korelasyon katsayılarını gösteren tablo.
sıra korelasyonu (rank correlation): Gerçek değerler yerine sıraları kullanarak ilişkinin gücünü dirençli biçimde nicelleştiren yöntem.
randomize kontrollü deney (randomized controlled trial): Deneklerin farklı müdahaleleri alan gruplara rastgele atandığı deney.
müdahale grubu (treatment group): Deneyde sınanan müdahaleyi alan grup.
kontrol grubu (control group): Deneyde müdahale almayan ya da etkisi bilinen bir tedavi alan grup.
doğal deney (natural experiment): Bazen rastgele atamayı taklit edebilen, doğal biçimde oluşmuş grupları kullanan deney.
nedensel çıkarım (causal inference): Neden-sonuç ilişkilerini belirleme ve nicelleştirme yöntemleri.
7.8. Alıştırmalar#
7.8.1. Alıştırma 7.1#
thinkstats modülü, bu bölümde daha önce kullandığımız kodu kapsayan decile_plot adlı bir işlev sağlar. SAT sözel ve matematik puanları arasındaki ilişkiyi görselleştirmek için şöyle çağırabiliriz.
from thinkstats import decile_plot
decile_plot(nlsy, "sat_verbal", "sat_math")
decorate(xlabel="SAT sözel", ylabel="SAT matematik")
PIAT matematik puanları ile gelirin desil grafiğini oluşturun. İlişki doğrusal görünüyor mu?
7.8.2. Alıştırma 7.2#
Gelire karşı SAT matematik puanlarının saçılım grafiğini oluşturun. Pearson korelasyonunu ve sıra korelasyonunu hesaplayın. Aralarında önemli bir fark var mı?
Gelire karşı SAT sözel puanlarının saçılım grafiğini oluşturup iki korelasyonu da hesaplayın. Gelecekteki geliri hangisi daha iyi tahmin ediyor: matematik puanı mı, sözel puan mı?
7.8.3. Alıştırma 7.3#
Bir öğrencinin lise not ortalamasının (GPA) SAT puanlarıyla nasıl korelasyonlu olduğuna bakalım. NLSY veri kümesinde GPA’yı kodlayan değişken aşağıdadır.
missing_codes = [-6, -7, -8, -9]
nlsy["gpa"] = nlsy["R9871900"].replace(missing_codes, np.nan) / 100
nlsy["gpa"].describe()
count 6004.000000
mean 2.818408
std 0.616357
min 0.100000
25% 2.430000
50% 2.860000
75% 3.260000
max 4.170000
Name: gpa, dtype: float64
GPA dağılımı şöyle görünür.
cdf_income = Cdf.from_seq(nlsy["gpa"])
cdf_income.step()
decorate(xlabel="GPA", ylabel="CDF")
GPA ile SAT matematik puanları arasındaki ilişkiyi gösteren bir saçılım grafiği oluşturup korelasyon katsayısını hesaplayın. GPA ile SAT sözel puanları arasındaki ilişki için de aynısını yapın. Hangi SAT puanı GPA’yı daha iyi tahmin ediyor?
7.8.4. Alıştırma 7.4#
Eğitim ile gelir arasındaki ilişkiyi inceleyelim. NLSY veri kümesinde her katılımcının aldığı en yüksek dereceyi bildiren bir sütun bulunur. Değerler tam sayılarla kodlanmıştır.
nlsy["degree"] = nlsy["Z9083900"]
nlsy["degree"].value_counts().sort_index()
degree
0.0 877
1.0 1167
2.0 3531
3.0 766
4.0 1713
5.0 704
6.0 64
7.0 130
Name: count, dtype: int64
Bu değerlerin kodunu aşağıdaki listelerle çözebiliriz.
positions = [0, 1, 2, 3, 4, 5, 6, 7]
labels = [
"Yok",
"GED",
"Lise diploması",
"Ön lisans derecesi",
"Lisans derecesi",
"Yüksek lisans derecesi",
"PhD",
"Mesleki derece",
]
Ardından eğitim düzeyi dağılımını temsil eden bir Pmf oluşturabiliriz.
from empiricaldist import Pmf
Pmf.from_seq(nlsy["degree"]).bar()
plt.xticks(positions, labels, rotation=30, ha="right")
decorate(ylabel="PMF")
income ile degree değişkenlerinin saçılım grafiğini oluşturun. Üst üste binmeyi önlemek için degree değerlerinin konumunu rastgele kaydırıp işaretçi boyutunu ve saydamlığı ayarlayın.
Katılımcıları degree değerine göre gruplamak için groupby yöntemini kullanın. DataFrameGroupBy nesnesinden income sütununu seçin; sonra her gruptaki medyanı, 10. ve 90. yüzdelikleri hesaplamak için quantile yöntemini kullanın. 10. ile 90. yüzdelikler arasındaki bölgeyi çizmek için fill_between, medyanları çizmek için plot kullanın.
Her ek dereceyle ilişkili gelir primi hakkında ne söyleyebilirsiniz?
7.8.5. Alıştırma 7.5#
Davranışsal Risk Faktörü Gözetim Sistemi (BRFSS) veri kümesi yaklaşık 400.000 katılımcının kendi bildirdiği boy ve ağırlık değerlerini içerir. Verileri indirme yönergeleri bu bölümün notebook’unda yer alıyor.
Boy ile ağırlık arasındaki ilişkiyi gösteren bir saçılım grafiği oluşturun. Yuvarlama nedeniyle görünen satır ve sütunları bulanıklaştırmak için veri noktalarının konumunu rastgele kaydırmanız gerekebilir. Bu kadar büyük bir örneklemde üst üste binmeyi önlemek için işaretçi boyutunu ve saydamlığı da ayarlamanız gerekir. Ayrıca iki ölçümde de aykırı değerler bulunduğundan, katılımcıların çoğunu kapsayan bir bölgeye yakınlaşmak için xlim ve ylim kullanmak isteyebilirsiniz.
Verileri şöyle yükleyebiliriz.
download("https://github.com/TerekliTahaBerk/thinkstatstr/raw/v3/data/CDBRFS08.ASC.gz")
from thinkstats import read_brfss
brfss = read_brfss()
brfss["htm3"].describe()
count 409129.000000
mean 168.825190
std 10.352653
min 61.000000
25% 160.000000
50% 168.000000
75% 175.000000
max 236.000000
Name: htm3, dtype: float64
Ağırlığa karşı boyun desil grafiğini oluşturun. İlişki doğrusal görünüyor mu? Korelasyon katsayısını ve sıra korelasyonunu hesaplayın. Aralarında önemli bir fark var mı? Bu değişkenler arasındaki ilişkiyi hangisinin daha iyi nicelleştirdiğini düşünüyorsunuz?
Think Stats: Python ile Keşifsel Veri Analizi, 3. Baskı
Telif hakkı 2024 Allen B. Downey
Kod lisansı: MIT Lisansı
Metin lisansı: Creative Commons Atıf-Gayriticari-AynıLisanslaPaylaş 4.0 Uluslararası