Skip to content

Eda with Python

İnsan Kaynakları ve Kifoz Hastalığı Datası

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
Churn Datası

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)