7 Temmuz 2017 Cuma

Python - Veri Analizi ve Görselleştirilmesi


Bu yazı kapsamında bir dizi değişken ve bu değişkenlere bağlı bir hedef "y" değişkeninden oluşan örnek bir veri seti üzerinde analiz çalışması yapılmış; ekstrem değer (outlier) , sabit değer içeren değişkenler ve seçilen herhangi bir değişkenin (sütunun) hedef y değişkeni ile ilişkisine dair çıkarımlar ve grafik üzerinde görselleştirilmeler gerçekleştirilmiştir.


Not: Bu yazıda kaggle adresinde yayınlanan bir yarışmanın veri seti ve örnek uygulamalarından yararlanılmıştır.


Kullanacağımız veri seti içeriği şu şekilde (Daha önceki bir yazımda da incelemiştim);


Veri setinde :

y                :   Hedef değerler (X0,X1.... parametrelerine göre değişiklik gösteren)

X0-X8       :   Kategorik değerler içeren veriler

X10-X385 :   Binary değer içeren veriler

olmak üzere toplam 377 sütun bulunmakta.

İlk olarak hedef y değerlerini ayrı bir değişkene kopyalayıp grafik üzerinde görelim.
y = df['y']

plt.figure(figsize=(8,6))
plt.scatter(range(y.shape[0]), np.sort(y.values))
plt.xlabel('index', fontsize=12)
plt.ylabel('y', fontsize=12)
plt.show()



Hedef y değerlerini sıralı hale getirip grafik üzerinde incelediğimizde, 265 değerinin diğer değerlere göre son derece ekstrem olduğunu görebiliyoruz. Yani bir nevi istisna bir değer, herkesin bildiği güzel ve anlamlı bir sözümüz vardır halk arasında, "İstisnalar kaideyi bozmaz". Evet istisnalar kaideyi bozmaz ve bozmamalı, biz de bu mantıktan hareketle makine öğrenmesinde önişlem aşaması olarak outlier olan değerleri bulup eleyebiliriz, çünkü bu değerleri supervised bir sınıflandırıcıda kullanmak sınıflandırıcımızın kaidesini/dengesini bozabilir :)

outlier olan değeri filtreleyelim ve "y" sütununu silelim. (df dataframe inin y değeri 200 den küçük olanları al )
df = df[df.y<200]
df.drop(['y'], axis=1, inplace=True)

Böylece veri setimizden bir değer eksilmiş oldu. Şimdi veri setimizdeki kolonların tiplerini otomatik bulalım.
dtype_df = df.dtypes.reset_index()

Hangi veri tipinden kaç tane olduğunu bulalım.
dtype_df.columns = ["Count", "Column Type"]
dtype_df = dtype_df.groupby("Column Type").aggregate('count')


Yazının başlarında veri içeriğini tanıtırken belirtmiştim, fakat burada otomatik olarak bulmuş olduk. 368 tane int64 değerler(binary değerler) içeren sütun ve 8 adet object tipinde değerler içeren sütun mevcut. Object tipindeki kolonlar kategorik değerler oluyor.

Daha önceki yazımda önişlem olarak kategorik verilerin dönüştürülmesi işleminden bahsetmiştim. Makine öğrenmesi teknikleri uygulamadan evvel yapılması gereken işlemlerden birisi de boş alanları bulmak ve bunları eğer mümkünse uygun değerlerle doldurmaktır. Veri setimizdeki boş alanları (missing values) bulalım.
missing_df = df.isnull().sum(axis=0).reset_index()
missing_df.columns = ['column_name', 'missing_count']
missing_df = missing_df.ix[missing_df['missing_count']>0]
missing_df = missing_df.sort_values(by='missing_count')
Neyse ki boş alan yok , yeni bir konudan/problemden kurtulduk :)

Toplamda 377 değişkenimiz vardı, kategorik olanları gözardı edip  geriye kalan değişkenlerin içerdiği değerleri inceleyelim.0-1 'lerden oluşan bu kolonlar içerisinde acaba sabit değerler içeren kolonlar var mı ? Ki bunları kullanmak sınıflandırıcı için anlamsız olacaktır. Örneğin ; 'X10' sütununu inceleyelim
# .unique()  ile farkli degerleri listeleyebiliriz
x = df['X10'].unique()

x'in içeriğine bakacak olursak sadece 0 ve 1 değerleri vardır. .unique() metotu dataframe in kolonlarındaki(pd.Series tipinde) farklı değerleri liste halinde geri döndürüyor. Eğer sadece 1 eleman geri döndürüyorsa, o kolonda hep aynı değerler bulunuyor anlamına geliyor.
Bir döngü içerisinde unique ve nonunique değerler içeren değişkenleri bulup, iki ayrı dictionary içerisinde saklayalım..
unique_values_dict = {}
nonunique_values_dict = {}

for col in df.columns:
    if col not in ["ID", "y", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X8"]:
        unique_values = df[col].unique()
        if len(unique_values)==1 :
            value = str(unique_values[0])
            unique_values_dict[col] = value
        else:
            value = str(np.sort(unique_values))
            nonunique_values_dict[col]=value

print("Sadece aynı degeri iceren kolonlar: ",unique_values_dict)



unique_values_dict içerisinde hangi sütunların hangi sabit değerleri içerdiğini görebilirsiniz. Muhtemelen bu sütunları da göz ardı edebiliriz çünkü sonuca bir etkileri olmayacaktır.
Şimdi ise değişkenler ile hedef y değerlerimiz arasındaki ilişkiyi grafik üzerinde nasıl gösterebileceğimize  göz atalım. Bunun için bir fonksiyon tanımlıyorum:
def plot_cetagorical_data( df,var_name,y, plot_type ):

    col_order = np.sort(df[var_name].unique()).tolist()
    plt.figure(figsize=(12,6))
    
    if (plot_type=='stripplot'):
        sns.stripplot(x=var_name, y=y, data=df, order=col_order)
    elif (plot_type=='boxplot'):
        sns.boxplot(x=var_name, y=y, data=df, order=col_order)
    
    plt.xlabel(var_name, fontsize=12)
    plt.ylabel('y', fontsize=12)
    plt.title("y 'nin "+var_name+ " değişkenine göre değişimi", fontsize=15)
    plt.show()

Tanımladığım bu fonksiyon ile seçilen bir sütuna göre, hedef y değerlerinin değişimini görselleştirebiliriz. Görselleştirme seçeneği olarak 'stripplot' ve 'boxplot' seçenekleri ekledim. X3 kategorik sütunumuzu inceleyecek olursak ;

plot_cetagorical_data(df,'X3',y,'stripplot')




boxplot ile çizdirecek olursak;
plot_cetagorical_data(df,'X3',y,'boxplot')






Böylece kategorik değişkenlerimizin hedef değerlere göre değişimini görselleştirip, üzerinden yorumlar/çıkarımlar yapabiliriz.

Binary değişlenlerimize geri dönelim ve her bir binary değişkende ne kadar 0 ve 1 olduğunu görüntüleyelim. Belki bu bilgi de veriyi yorumlamakta bize yardımcı olabilir. col_list ile kolon isimlerini, zero_count_list ile sıfır sayılarını ve  one_count_list ile bir sayılarını saklayacağız.
col_list = []
zero_count_list = []
one_count_list = []
for key in nonunique_values_dict:
    if (nonunique_values_dict[key] == "[0 1]"):
       temp0 = (df[key]==0).sum()
       temp1 = (df[key]==1).sum()
#       print("column ", key , "  -> 0:",temp0, " 1:",temp1)
       zero_count_list.append(temp0) 
       one_count_list.append(temp1)
       col_list.append(key)



Hangi kolonda kaç tane 1 kaç tane 0 değer olduğunu bulduk. Şimdi sadece 30 değişkenin 0 ve 1 sayılarını grafik olarak gösterelim. ( Hepsi çok uzun olacağı için 30 kolonu gösterdim sadece )
ind=np.arange(30)
x = len(ind)
width = 0.35

plt.figure(figsize=(6,6))

p1 = plt.barh(ind, zero_count_list[:x], width, color='red', label= 'Zero count')
p2 = plt.barh(ind, one_count_list[:x], width, left=zero_count_list[:x], color="blue", label= 'One count')

plt.yticks(ind, col_list)
plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
           ncol=2, mode="expand", borderaxespad=0.)
plt.show()






Böylelikle örnek bir veri seti üzerinde temel bazı analizler yapmış olduk, eksiği gediği olabilir, ki ben de bu konuda yeni yeni bir şeyler öğreniyorum. Umarım en azından başlangıç aşamasında da olsa birileri için faydalı bir Türkçe kaynak/örnek olabilir.

1 yorum:

  1. merhabalar hocam öncelikler çok güzel bir kaynak olmuş hazırladıklarınız teşekkür ederim. Ben bir soru soracaktım. Benim elimde bir likert ölçekli memnuniyet anketi var ve bu ankette bazı koşullu sorular var. hzırladıklarınızdan faydalandım fakat analiz noktasında python da analiz etme konusunda yeni olduğum için ne yapabileceğim konusunda fikirsiz kaldım. yol gösterirseniz sevinirim.

    YanıtlaSil