Eda with Python
“Python, veri biliminde keşifsel veri analizi (EDA) için güçlü ve esnek bir araçtır, sayısız kütüphane ve modülü ile veri setlerini kolayca manipüle edip görselleştirmenize olanak tanır. Bu dil, verilerinizin hikayesini anlamak ve veri temelli kararlar almak için derinlemesine analizler yapmanıza yardımcı olur.”
Bu projede veri analizi ve Eda yaparak insan kaynakları datasını analiz edeceğiz. Bu çalışmada uçtan uca bir Eda çalışmasını yapılması aşamasındaki bütün detayları görebileceksiniz.
KODLAMA GÖREVİ: VERİ SETİNİ İÇE AKTARIN VE TEMEL İSTATİSTİKSEL VERİ ANALİZİNİ YAPIN
- Panda kütüphanesini import edin
- Satır ve sütunları görüntüleyin
- CSV dosyasını impoert edin
- Veri tipini elde edin
- .head() işlevini kullanarak ilk birkaç satırı görüntüleyebilirsiniz.
- .tail() kullanarak son birkaç satırı görüntüleyebilirsiniz.
- Employee_df veri çerçevesi için ortalama değerleri hesaplayın
import pandas as pd
import numpy as np
df = pd.read_csv("Human_Resources.csv")
df.sample(3)
Age MonthlyIncome Attrition BusinessTravel DailyRate Department DistanceFromHome Education EducationField EmployeeCount ... RelationshipSatisfaction StandardHours StockOptionLevel TotalWorkingYears TrainingTimesLastYear WorkLifeBalance YearsAtCompany YearsInCurrentRole YearsSinceLastPromotion YearsWithCurrManager
933 28 2080.0 No Travel_Rarely 640 Research & Development 1 3 Technical Degree 1 ... 2 80 0 5 2 2 3 2 1 2
262 32 2176.0 No Travel_Rarely 128 Research & Development 2 1 Technical Degree 1 ... 4 80 0 9 5 3 6 2 0 4
1321 47 2105.0 No Travel_Rarely 207 Research & Development 9 4 Life Sciences 1 ... 3 80 0 7 2 3 2 2 2 0
df.columns
Index(['Age', 'MonthlyIncome', 'Attrition', 'BusinessTravel', 'DailyRate',
'Department', 'DistanceFromHome', 'Education', 'EducationField',
'EmployeeCount', 'EmployeeNumber', 'EnvironmentSatisfaction', 'Gender',
'HourlyRate', 'JobInvolvement', 'JobLevel', 'JobRole',
'JobSatisfaction', 'MaritalStatus', 'MonthlyRate', 'NumCompaniesWorked',
'Over18', 'OverTime', 'PercentSalaryHike', 'PerformanceRating',
'RelationshipSatisfaction', 'StandardHours', 'StockOptionLevel',
'TotalWorkingYears', 'TrainingTimesLastYear', 'WorkLifeBalance',
'YearsAtCompany', 'YearsInCurrentRole', 'YearsSinceLastPromotion',
'YearsWithCurrManager'],
dtype='object')
df.describe().T
count mean std min 25% 50% 75% max
Age 1470.0 36.923810 9.135373 18.0 30.00 36.0 43.00 60.0
MonthlyIncome 1467.0 6505.155419 4711.297846 1009.0 2911.00 4908.0 8378.00 19999.0
DailyRate 1470.0 802.485714 403.509100 102.0 465.00 802.0 1157.00 1499.0
DistanceFromHome 1470.0 9.192517 8.106864 1.0 2.00 7.0 14.00 29.0
Education 1470.0 2.912925 1.024165 1.0 2.00 3.0 4.00 5.0
EmployeeCount 1470.0 1.000000 0.000000 1.0 1.00 1.0 1.00 1.0
EmployeeNumber 1469.0 1025.556161 601.646166 1.0 492.00 1022.0 1556.00 2068.0
EnvironmentSatisfaction 1470.0 2.721769 1.093082 1.0 2.00 3.0 4.00 4.0
HourlyRate 1470.0 65.891156 20.329428 30.0 48.00 66.0 83.75 100.0
JobInvolvement 1470.0 2.729932 0.711561 1.0 2.00 3.0 3.00 4.0
JobLevel 1470.0 2.063946 1.106940 1.0 1.00 2.0 3.00 5.0
JobSatisfaction 1470.0 2.728571 1.102846 1.0 2.00 3.0 4.00 4.0
MonthlyRate 1468.0 14310.966621 7121.294449 2094.0 8043.75 14235.5 20463.25 26999.0
NumCompaniesWorked 1470.0 2.693197 2.498009 0.0 1.00 2.0 4.00 9.0
PercentSalaryHike 1469.0 15.206263 3.659047 11.0 12.00 14.0 18.00 25.0
PerformanceRating 1469.0 3.153165 0.360270 3.0 3.00 3.0 3.00 4.0
RelationshipSatisfaction 1470.0 2.712245 1.081209 1.0 2.00 3.0 4.00 4.0
StandardHours 1470.0 80.000000 0.000000 80.0 80.00 80.0 80.00 80.0
StockOptionLevel 1470.0 0.793878 0.852077 0.0 0.00 1.0 1.00 3.0
TotalWorkingYears 1470.0 11.279592 7.780782 0.0 6.00 10.0 15.00 40.0
TrainingTimesLastYear 1470.0 2.799320 1.289271 0.0 2.00 3.0 3.00 6.0
WorkLifeBalance 1470.0 2.761224 0.706476 1.0 2.00 3.0 3.00 4.0
YearsAtCompany 1470.0 7.008163 6.126525 0.0 3.00 5.0 9.00 40.0
YearsInCurrentRole 1470.0 4.229252 3.623137 0.0 2.00 3.0 7.00 18.0
YearsSinceLastPromotion 1470.0 2.187755 3.222430 0.0 0.00 1.0 3.00 15.0
YearsWithCurrManager 1470.0 4.123129 3.568136 0.0 2.00 3.0 7.00 17.0
df.head(3)
Age MonthlyIncome Attrition BusinessTravel DailyRate Department DistanceFromHome Education EducationField EmployeeCount ... RelationshipSatisfaction StandardHours StockOptionLevel TotalWorkingYears TrainingTimesLastYear WorkLifeBalance YearsAtCompany YearsInCurrentRole YearsSinceLastPromotion YearsWithCurrManager
0 41 5993.0 Yes Travel_Rarely 1102 Sales 1 2 Life Sciences 1 ... 1 80 0 8 0 1 6 4 0 5
1 49 NaN No Travel_Frequently 279 Research & Development 8 1 Life Sciences 1 ... 4 80 1 10 3 3 10 7 1 7
2 37 2090.0 Yes Travel_Rarely 1373 Research & Development 2 2 Other 1 ... 2 80 0 7 3 3 0 0 0 0
3 rows × 35 columns
df.tail(3)
Age MonthlyIncome Attrition BusinessTravel DailyRate Department DistanceFromHome Education EducationField EmployeeCount ... RelationshipSatisfaction StandardHours StockOptionLevel TotalWorkingYears TrainingTimesLastYear WorkLifeBalance YearsAtCompany YearsInCurrentRole YearsSinceLastPromotion YearsWithCurrManager
1467 27 6142.0 No Travel_Rarely 155 Research & Development 4 3 Life Sciences 1 ... 2 80 1 6 0 3 6 2 0 3
1468 49 5390.0 No Travel_Frequently 1023 Sales 2 3 Medical 1 ... 4 80 0 17 3 2 9 6 0 8
1469 34 4404.0 No Travel_Rarely 628 Research & Development 8 3 Medical 1 ... 1 80 0 6 3 4 4 3 1 2
3 rows × 35 columns
GÖREV: Bu çalışmada dikkate alınan ortalama, maksimum ve minimum çalışan yaşını farklı bir strateji kullanarak hesaplayın
df["Age"].mean()
36.923809523809524
df["Age"].max()
60
df["Age"].min()
18
df.sample(3)
Age MonthlyIncome Attrition BusinessTravel DailyRate Department DistanceFromHome Education EducationField EmployeeCount ... RelationshipSatisfaction StandardHours StockOptionLevel TotalWorkingYears TrainingTimesLastYear WorkLifeBalance YearsAtCompany YearsInCurrentRole YearsSinceLastPromotion YearsWithCurrManager
974 27 5071.0 No Travel_Frequently 793 Sales 2 1 Life Sciences 1 ... 2 80 0 8 3 3 6 2 0 0
439 31 9824.0 Yes Travel_Frequently 534 Research & Development 20 3 Life Sciences 1 ... 1 80 0 12 2 3 1 0 0 0
1275 51 13116.0 No Travel_Rarely 942 Research & Development 3 3 Technical Degree 1 ... 4 80 0 15 2 3 2 2 2 2
KODLAMA GÖREVİ: EKSİK VERİLERLE BAŞA ÇIKMA
- Null değerlerine sahip satırları bulalım
- Dikkat Satır dizini 6’da birçok eksik değer var
- Sütun başına toplam eksik öğe sayısını görelim
- Null değeri içeren herhangi bir satırı bırakın
- Veri çerçevesi boyutunun 7 öğe azaltılarak 1470’ten 1463’e düşürüldüğünü unutmayın.
- Örneğin 1. satırın artık mevcut olmadığına dikkat edin!
- Hala eksik değerlerimiz olup olmadığını kontrol edelim
- Eksik değerlerle başa çıkmak için alternatif (daha akıllı) bir yöntem keşfedelim
- Ham verileri Pandas kullanarak tekrar okuyalım.
- Ortalama aylık geliri hesaplayın
- Belirli bir sütunu belirli bir değerle doldurmak için fillna yı kullanabilirsiniz.
df.sample(3)
Age MonthlyIncome Attrition BusinessTravel DailyRate Department DistanceFromHome Education EducationField EmployeeCount ... RelationshipSatisfaction StandardHours StockOptionLevel TotalWorkingYears TrainingTimesLastYear WorkLifeBalance YearsAtCompany YearsInCurrentRole YearsSinceLastPromotion YearsWithCurrManager
982 38 2610.0 No Travel_Frequently 693 Research & Development 7 3 Life Sciences 1 ... 4 80 3 4 2 3 4 2 0 3
875 44 4541.0 No Travel_Rarely 200 Research & Development 29 4 Other 1 ... 2 80 0 20 3 3 20 11 13 17
735 48 4240.0 No Travel_Rarely 277 Research & Development 6 3 Life Sciences 1 ... 4 80 0 19 0 3 2 2 2 2
df.columns
Index(['Age', 'MonthlyIncome', 'Attrition', 'BusinessTravel', 'DailyRate',
'Department', 'DistanceFromHome', 'Education', 'EducationField',
'EmployeeCount', 'EmployeeNumber', 'EnvironmentSatisfaction', 'Gender',
'HourlyRate', 'JobInvolvement', 'JobLevel', 'JobRole',
'JobSatisfaction', 'MaritalStatus', 'MonthlyRate', 'NumCompaniesWorked',
'Over18', 'OverTime', 'PercentSalaryHike', 'PerformanceRating',
'RelationshipSatisfaction', 'StandardHours', 'StockOptionLevel',
'TotalWorkingYears', 'TrainingTimesLastYear', 'WorkLifeBalance',
'YearsAtCompany', 'YearsInCurrentRole', 'YearsSinceLastPromotion',
'YearsWithCurrManager'],
dtype='object')
df.shape
(1470, 35)
df.isnull().sum()[df.isnull().sum()>0]
MonthlyIncome 3
Department 1
EducationField 1
EmployeeNumber 1
Gender 1
JobRole 1
MaritalStatus 1
MonthlyRate 2
PercentSalaryHike 1
PerformanceRating 1
dtype: int64
df.dropna(inplace=True)
df.isnull().sum()[df.isnull().sum()>0]
Series([], dtype: int64)
df_1 = pd.read_csv("Human_Resources.csv")
df_1.sample(3)
Age MonthlyIncome Attrition BusinessTravel DailyRate Department DistanceFromHome Education EducationField EmployeeCount ... RelationshipSatisfaction StandardHours StockOptionLevel TotalWorkingYears TrainingTimesLastYear WorkLifeBalance YearsAtCompany YearsInCurrentRole YearsSinceLastPromotion YearsWithCurrManager
303 31 6929.0 No Travel_Rarely 218 Sales 7 3 Technical Degree 1 ... 2 80 1 10 3 2 8 7 7 7
1255 33 8564.0 Yes Travel_Rarely 211 Sales 16 3 Life Sciences 1 ... 3 80 0 11 2 2 0 0 0 0
864 41 2107.0 Yes Non-Travel 906 Research & Development 5 2 Life Sciences 1 ... 1 80 1 5 2 1 1 0 0 0
df_1.shape
(1470, 35)
df_1.isnull().sum()[df_1.isnull().sum()>0]
MonthlyIncome 3
Department 1
EducationField 1
EmployeeNumber 1
Gender 1
JobRole 1
MaritalStatus 1
MonthlyRate 2
PercentSalaryHike 1
PerformanceRating 1
dtype: int64
Bu data geçmiş dönemde 3 yıl yönettiğim bir telekomikasyon firmasının Inbound ve Outbound Churn ekiplerinde yaşadığım deneyimlere dayanarak oluşturulmuştur. Data oluşturma aşamasında ChatGPT’den destek alınmış, ChatGPT’nin yetersiz kaldığı noktalarda Python yardımıyla BI toollarında kullanılabilecek hale getirilmiştir. Datanın manipülasyon gerektirdiği aşamalar BI toolunda yapılmak üzere göz ardı edilmiştir. Bu sayfada bu datada yaptığım EDA çalışmasının tüm adımlarını görebilecek, Power BI alanında ise analiz edilmiş haline ulaşabileceksiniz.
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
ch = pd.read_csv("C:/Users/Hp/Downloads/extended_churn_dataset_7000_records.csv")
ch.head(5)
ch.shape
(7000, 31)
ch.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7000 entries, 0 to 6999
Data columns (total 31 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Müşteri ID 7000 non-null object
1 Müşteri Durumu 7000 non-null object
2 Müşterinin Adı-Soyadı 7000 non-null object
3 Telefon Numarası 7000 non-null int64
4 İl 7000 non-null object
5 Cinsiyet 7000 non-null object
6 Doğum Tarihi 7000 non-null object
7 İlk Abonelik Tarihi 7000 non-null object
8 Kullandığı Paket Adı 7000 non-null object
9 Kullandığı Paket İçeriği 7000 non-null object
10 Kullandığı Paket Tahhüt Süresi 7000 non-null int64
11 Kullandığı Paket Tutarı 7000 non-null float64
12 Taahhüt Başlangıç Tarihi 7000 non-null object
13 Müşteri Segmentasyonu 7000 non-null object
14 Son 3 Ay İçerisinde Müşteri Hizmetlerini Arama Adedi 7000 non-null int64
15 Müşteri Hizmetlerini Son Arama Nedeni 7000 non-null object
16 Inbound Churn Birimini Aramış Mı? 7000 non-null object
17 Inbound Churn İptal Talebi Nedeni 7000 non-null object
18 Inbound Churn Biriminde Teklif Edilen Offer 7000 non-null object
19 Inbound Churn Birimi İşlem Yapan Temsilci ID 7000 non-null object
20 Inbound Churn Birimi İşlem Yapan Temsilci Adı-Soyadı 7000 non-null object
21 Inbound Churn'de İkna Edildi Mi? 7000 non-null object
22 Outbound Churn Task ID 7000 non-null object
23 Outbound Churn Task Açılma Tarihi 7000 non-null object
24 Outbound Churn Taskının İlk Aranma Tarihi 7000 non-null object
25 Outbound Churn Biriminde Müşteriye Teklif Edilen Offer 7000 non-null object
26 Outbound Churn Biriminde Müşteri İkna Edildi Mi? 7000 non-null object
27 Outbound Churn İptal Talebi Nedeni 7000 non-null object
28 Outbound Churn Birimi İşlem Yapan Temsilci ID 7000 non-null object
29 Outbound Churn Birimi İşlem Yapan Temsilci Adı-Soyadı 7000 non-null object
30 Son 3 Ay İçerisinde Yapılan Anket Sonucu 7000 non-null object
dtypes: float64(1), int64(3), object(27)
memory usage: 1.7+ MB
Kullandığı paket isimlerini beğenmedim. Kendi oluşturduğum paket isimlerini burada kullanmak istiyorum.
ch["Kullandığı Paket Adı"].unique()
array(['Paket C', 'Paket B', 'Paket D', 'Paket A'], dtype=object)
pak = pd.read_excel(r"C:\Users\Hp\Desktop\churn_paket_içerikleri.xlsx")
pak
pak.drop(["Unnamed: 0", "Unnamed: 1", "Unnamed: 2" ,"Unnamed: 3","Unnamed: 4", "Unnamed: 5","Unnamed: 6","Unnamed: 7", "Unnamed: 8"], axis = 1)
pak_adi = pak["Paket Adı"]
pak_adi
0 Müthiş Avantaj 14 GB Paketi
1 Mutlu Fırsat 18 GB Paketi
2 Mutlu Fırsat 19 GB
3 Çekici Fırsat 13 GB Paketi
4 Net Fırsat 11 GB Paketi\t
5 Firsat 20GB Tarifesi
6 Platinum Sınırsız İletişim 20GB Paketi
7 Platinum Sınırsız Bağlan 40 GB Paketi
8 Ultra Bağlan 5 GB Paketi
9 Harika Bağlan 20 GB Paketi
10 Maxi Fırsat 20 GB Paketi
11 Harika Fırsat 20 GB Paketi
12 Giga Fırsat 15 GB Paketi
13 Maxi Fırsat 50 GB Paketi
14 Maxi Bağlan 20 GB Paketi
15 İdeal Tarifesi 50 GB Paketi
16 Ekstra İletişim 10 GB Paketi
17 İdeal İletişim 5 GB Paketi
Name: Paket Adı, dtype: object
ch["Kullandığı Paket Adı"] = np.random.choice(pak_adi, size = len(ch))
ch
Oluşan datada şöyle bir hata var. Bir müşteri IB Churn biriminde ikna edildi ise OB Churn birimine gitmez. Ancak chatgpt göndermiş. Şimdi ben “Inbound Churn’de İkna Edildi Mi?” evet ise devamındaki sütunların içeriğini temizleyeceğim.
columns_to_empty = ch.columns[ch.columns.get_loc("Inbound Churn'de İkna Edildi Mi?")+1:]
ch.loc[ch["Inbound Churn'de İkna Edildi Mi?"] == "Evet", columns_to_empty] = ""
ch
Temizleme işleminden sonra datayı daha da zenginleştirmek için “Inbound Churn’de İkna Edildi Mi?” = Evet olanların 30%’unu dataya tekrar tekrarlanan müşteri olarak sokmak istiyorum.
#Burada nan olanları buldum.
NaN_rows = ch[ch["Inbound Churn'de İkna Edildi Mi?"] == "Evet"]
#Sonra bu nan olanların 30%'unu rastgele seçtim
sampled_NaN_rows = NaN_rows.sample(frac=0.3, random_state=1)
#şimdi de seçtiğim bu 30%'luk datayı ch datasına ekliyorum
ch = pd.concat([ch, sampled_NaN_rows], ignore_index=True)
ch
Son olarak elde ettiğim datayı export ediyorum.
ch.to_csv(r"C:\Users\Hp\Desktop\churn_edali", index=False)