Skip to content

Commit

Permalink
hello miuul
Browse files Browse the repository at this point in the history
  • Loading branch information
oguzerdo committed Jun 28, 2022
1 parent d4b7019 commit f2493a4
Showing 1 changed file with 380 additions and 0 deletions.
380 changes: 380 additions & 0 deletions 01_rule_based_segmentation.py
Original file line number Diff line number Diff line change
@@ -0,0 1,380 @@
# Portekizde bulunan bir otele ait bu veri setinde 2015-2018 boyunca konukların
# bazı demografik bilgileri ve rezervasyon ile ilgili bilgileri yer almakta.
# Otel, konuklarının bazı özelliklerini kullanarak seviye tabanlı (level based )
# yeni müşteri tanımları (persona) oluşturmak ve bu yeni müşteri tanımlarına göre segmentler oluşturup
# bu segmentlere göre yeni gelebilecek müşterilerin otele
# ortalama ne kadar kazandırabileceğini tahmin etmek istemektedir.


# Örneğin: Fransadan Ajans aracılığıyla rezervasyon yapmış 30 yaşındaki birisinin
# ortalama ne kadar kazandırabileceği ya da ne kadar zaman önce rezervasyon yapabileceği belirlenmek isteniyor.


################# Uygulama Öncesi #####################

# ID Nationality Age LeadTime LodgingRevenue OtherRevenue Channel
# 4 FRA 60.0 93 240.0 60.0 Agent
# 8 FRA 32.0 38 535.0 94.0 Agent
# 12 FRA 58.0 60 292.0 81.0 Agent
# 14 ESP 42.0 87 327.7 48.0 Direct
# 16 FRA 68.0 11 437.0 36.0 Agent


################# Uygulama Sonrası #####################

# customers_level_based Revenue LeadTime SEGMENT
# DEU_AGENT_18_25 560.716760 103.129221 A
# DEU_AGENT_26_40 449.799012 78.828552 B
# DEU_AGENT_41_50 492.285417 104.734114 B
# DEU_AGENT_51_60 500.283815 127.269332 B
# DEU_AGENT_60 360.369899 243.133928 C


# Değişken tanımları
# Nationality: Konuğun milliyeti
# Age: Konuğun yaşı
# LeadTime: Rezervasyon yapılan gün ile checkin arasındaki gün sayısı
# LodgingRevenue: Müşteri tarafından konaklama giderleri için harcanan toplam tutar (Euro). Bu değere oda, beşik ve diğer ilgili konaklama giderleri dahildir.
# OtherRevenue: Müşteri tarafından diğer harcamalar için harcanan toplam tutar (Euro). Bu değere yiyecek, içecek, spa ve diğer harcamalar dahildir.
# Channel: Müşteri tarafından otelde rezervasyon yapmak için kullanılan kanal.
# Agent Turizm ajansi ile rezervasyon,
# Direct: Direct booking.
# Corporate: Partnerler aracılığıyla yapılan rezervasyon.
# Electronic: Elektronik kanallar aracılığıyla yapılan rezervasyon.


# https://www.sciencedirect.com/science/article/pii/S2352340920314645?via=ihub
import pandas as pd
from matplotlib import pyplot as plt

pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option("display.width", 500)

# data.csv dosyasını okutunuz ve veri seti ile ilgili genel bilgileri gösteriniz.
import pandas as pd

data = pd.read_csv('datasets/data.csv', sep="|")

# Bu şekilde bir işlem yapmamalıyız.
yedek = data

yedek.head()
data.head()

yedek["Age"] = yedek["Age"].apply(lambda x: x * x)

yedek.head()
data.head()

data = pd.read_csv('datasets/data.csv', sep="|")

# Bu şekilde kullanmalıyız.
df = data.copy()
df["Age"] = df["Age"].apply(lambda x: x * x)

df.head()
data.head()

### Veriyi anlama


data = pd.read_csv('datasets/data.csv', sep="|")
df.head()

# ID Nationality Age LeadTime LodgingRevenue OtherRevenue Channel
# 0 4 FRA 60.0 93 240.0 60.0 Agent
# 1 8 FRA 32.0 38 535.0 94.0 Agent
# 2 12 FRA 58.0 60 292.0 81.0 Agent
# 3 14 ESP 42.0 87 327.7 48.0 Direct
# 4 16 FRA 68.0 11 437.0 36.0 Agent

df.info()

# Age ve Leadtime degiskeninde - degerler var
df.describe([0.1, 0.5, 0.75, 0.9, 0.95, 0.99]).T

# count mean std min 10% 50% 75% 90% 95% 99% max
# ID 35725.0 34973.034206 22583.237559 4.0 7132.8 31726.0 50506.0 71004.2 77593.8 82185.280 83585.0
# Age 35725.0 48.112414 14.474405 -11.0 29.0 48.0 58.0 68.0 73.0 81.000 114.0
# LeadTime 35725.0 90.635969 97.235745 -1.0 3.0 58.0 135.0 220.0 288.0 451.000 588.0
# LodgingRevenue 35725.0 357.515912 265.671866 0.0 117.0 292.0 444.0 670.0 881.8 1413.000 2055.0
# OtherRevenue 35725.0 85.870103 96.379774 0.0 12.0 56.0 110.0 187.5 260.5 461.904 1465.0

# Age ve Leadtime degiskeninde - degerler var bunları çıkaralım
df = df.loc[~((df["Age"] <= 0) | (df["LeadTime"] < 0))]

# Veri setindeki IDnin unique olma durumunu kontrol edelim
df.shape

# Toplam gözlem sayısı ID değişkeninideki toplam unique sayısına eşit. Çoklanmış bir veri yok.
df.ID.nunique()

# Bir başka yöntem
df[df.ID.duplicated()]

# Toplam kazancı ifade eden bir değişken yok bunu oluşturalım.

df["Revenue"] = df['LodgingRevenue'] df["OtherRevenue"]

# Revenue'de farklı bir durum var mı kontrol edelim.
df[df["Revenue"] <= 0]

# Revenue dagilimina bakalim
df["Revenue"].hist();
plt.show()

# Daha yakından incelemek istersek, genellikle harcamalar 200-400 Euro aralığında görülüyor.
df[df["Revenue"] < 750]["Revenue"].hist();
plt.show()

# Ilerleyen projelerde her bir değişkene tek tek grafik olarak bakmak bizi yoracak,
# Sayısal değişkenlerde describe ile veriyi grafiğe bakar gibi yorumlamak mümküm.
df.describe([0, 0.01, 0.1, 0.5, 0.75, 0.9, 0.95, 0.99]).T

# count mean std min 0% 1% 10% 50% 75% 90% 95% 99% max
# ID 35725.0 34973.034206 22583.237559 4.0 4.0 888.48 7132.8 31726.0 50506.0 71004.20 77593.80 82185.280 83585.00
# Age 35725.0 48.112414 14.474405 -11.0 -11.0 20.00 29.0 48.0 58.0 68.00 73.00 81.000 114.00
# LeadTime 35725.0 90.635969 97.235745 -1.0 -1.0 0.00 3.0 58.0 135.0 220.00 288.00 451.000 588.00
# LodgingRevenue 35725.0 357.515912 265.671866 0.0 0.0 66.60 117.0 292.0 444.0 670.00 881.80 1413.000 2055.00
# OtherRevenue 35725.0 85.870103 96.379774 0.0 0.0 2.00 12.0 56.0 110.0 187.50 260.50 461.904 1465.00
# Revenue 35725.0 443.386015 318.581430 65.0 65.0 78.50 141.0 364.5 552.3 827.62 1080.36 1707.000 2197.75

# Kaç unique Channel vardır?
df['Channel'].nunique()
df['Channel'].value_counts()

# Agent 29657
# Direct 4496
# Corporate 1245
# Electronic 327

# Hangi Milliyetten kaçar tane rezervasyon olmuş?
df["Nationality"].value_counts()
df.groupby("Nationality")["Revenue"].count()

# Nationality
# DEU 7702
# ESP 3814
# FRA 9103
# GBR 6409
# ITA 2503
# PRT 6194


# Milliyetlere göre satışlardan toplam ne kadar kazanılmış?
df.groupby("Nationality").agg({"Revenue": "sum"})

# Revenue
# Nationality
# DEU 3541379.31
# ESP 1635497.67
# FRA 4406410.68
# GBR 3039657.47
# ITA 1192924.21
# PRT 2024096.05

# Channel türlerine göre göre toplam, ortalama geliri ve rezervasyon sayılarını inceleyelim
df.groupby("Channel").agg({"Revenue": ["sum", 'mean', 'count']})

# Revenue
# sum mean count
# Channel
# Agent 13218264.05 445.704692 29657
# Corporate 390745.36 313.851695 1245
# Direct 2131530.41 474.094842 4496
# Electronic 99425.57 304.053731 327


# Ülkelere göre Rezervasyon geliri ortalamaları nedir?
df.groupby("Nationality").agg({"Revenue": "mean"})

# Revenue
# Nationality
# DEU 459.799962
# ESP 428.814282
# FRA 484.061373
# GBR 474.279524
# ITA 476.597767
# PRT 326.783347


# Ülke-Channel kırılımında Revenue ortalamaları nedir?

df.groupby(["Nationality", "Channel"]).agg({"Revenue": "mean"})[0:7]

# Revenue
# Nationality Channel
# DEU Agent 453.932861
# Corporate 405.155306
# Direct 547.891510
# Electronic 346.241071
# ESP Agent 432.095200
# Corporate 273.374132
# Direct 497.338772

# Segmentlere başlangıç
# Nationality, DistributionChannel, Age kırılımında ortalama lead time nedir ve ortalama kazançlar nedir?


df.groupby(["Nationality", "Channel", "Age"]).agg({"LeadTime": "mean",
"Revenue": "mean"})[0:20]

# Çıktıyı Revenue'a göre sıralayalım

agg_df = df.groupby(["Nationality", "Channel", "Age"]).agg({"LeadTime": "mean",
"Revenue": "mean"})
agg_df = agg_df.sort_values(by="Revenue", ascending=False)

agg_df.head()

# LeadTime Revenue
# Nationality Channel Age
# ESP Direct 20.0 31.0 2196.0
# DEU Corporate 41.0 5.0 1924.5
# ITA Corporate 62.0 24.0 1748.5
# DEU Corporate 60.0 68.0 1596.5
# GBR Electronic 27.0 9.0 1566.4

# Indekste yer alan isimleri değişken ismine çevirelim

agg_df.index
agg_df = agg_df.reset_index()
agg_df.head()

# Nationality Channel Age LeadTime Revenue
# 0 ESP Direct 20.0 31.0 2196.0
# 1 DEU Corporate 41.0 5.0 1924.5
# 2 ITA Corporate 62.0 24.0 1748.5
# 3 DEU Corporate 60.0 68.0 1596.5
# 4 GBR Electronic 27.0 9.0 1566.4

# İlk veri setindeki gözlem boyutuna bakalım (35709, 8)
df.shape

# Gruplamadan sonraki gözlem boyutu (1209, 5)
agg_df.shape

# Age değişkeninin dagilimlarini inceleyelim ve bunlari kategorik degiskene cevirelim
df['Age'].hist()
plt.show()

# AGE değişkeninin nerelerden bölüneceğini belirtelim:
# 18i dahil edebilmek icin 17 ile baslattik, verisetinde 17 yasinda konuk yok.
bins = [17, 25, 40, 50, 60, agg_df["Age"].max()]
labels = ['18_25', '26_40', '41_50', '51_60', '60 ']
agg_df["age_cat"] = pd.cut(agg_df["Age"], bins, labels=labels)

agg_df.head()

# Nationality Channel Age LeadTime Revenue age_cat
# 0 ESP Direct 20.0 31.0 2196.0 18_25
# 1 DEU Corporate 41.0 5.0 1924.5 41_50
# 2 ITA Corporate 62.0 24.0 1748.5 60
# 3 DEU Corporate 60.0 68.0 1596.5 51_60
# 4 GBR Electronic 27.0 9.0 1566.4 26_40

# 18-25 yas aralığındaki kişileirin harcamaları daha fazla görünüyor.
agg_df.groupby('age_cat')["Revenue"].mean()
agg_df.groupby('age_cat').agg({"Revenue": "mean"})

# Revenue
# age_cat
# 18_25 512.206998
# 26_40 407.179816
# 41_50 406.624691
# 51_60 430.374044
# 60 422.929742

agg_df.head()

# Yöntem 1
agg_df['customers_level_based'] = [row[0].upper() "_" row[1].upper() "_" row[5].upper() for row in
agg_df.values]

# Yöntem 2
cols = [col for col in agg_df.columns if col not in ["Age", "LeadTime", 'Revenue']]
agg_df['customers_level_based'] = agg_df.apply(lambda x: "_".join(x[col] for col in cols).upper(), axis=1)

# Yöntem 3
agg_df['customers_level_based'] = (agg_df[['Nationality', 'Channel', "age_cat"]].agg('_'.join, axis=1)).str.upper()

# Amacımıza bir adım daha yaklaştık.
# Burada ufak bir problem var. Birçok aynı segment olacak.
# örneğin DEU_AGENT_60 segmentinden birçok sayıda olabilir.
# kontrol edelim:
agg_df["customers_level_based"].value_counts()

# DEU_AGENT_60 31
# PRT_AGENT_60 30

# Bu sebeple segmentlere göre groupby yaptıktan sonra revenue ortalamalarını almalı ve segmentleri tekilleştirmeliyiz.
# Burada leadtimelari da bir hedef degisken gibi incelemek iyi olabilir

agg_df_final = agg_df.groupby("customers_level_based").agg({"Revenue": "mean",
'LeadTime': "mean"})

# customers_level_based index'te yer almaktadır. Bunu değişkene çevirelim.
agg_df_final = agg_df_final.reset_index()
agg_df_final.head()

# customers_level_based Revenue LeadTime
# 0 DEU_AGENT_18_25 560.716760 103.129221
# 1 DEU_AGENT_26_40 449.799012 78.828552
# 2 DEU_AGENT_41_50 492.285417 104.734114
# 3 DEU_AGENT_51_60 500.283815 127.269332
# 4 DEU_AGENT_60 360.369899 243.133928

#############################################
# GÖREV 7: Yeni müşterileri (DEU_AGENT_18_25) segmentlere ayırınız.
#############################################
# Revenu'a göre segmentlere ayıralım ve segmentleri betimleyelim

agg_df_final["SEGMENT"] = pd.qcut(agg_df_final["Revenue"], 4, labels=["D", "C", "B", "A"])

agg_df_final.groupby("SEGMENT").agg({"Revenue": ["count", "mean", "sum", "max", "min"]}).reset_index()

# SEGMENT Revenue
# count mean sum max min
# 0 D 29 216.516813 6278.987575 290.916667 116.000000
# 1 C 29 341.635048 9907.416379 413.803123 295.126296
# 2 B 29 470.204172 13635.920997 503.966599 419.286899
# 3 A 29 596.331327 17293.608481 818.187500 504.546095

agg_df_final.groupby("SEGMENT").agg({"Revenue": ["count", "mean"],
"LeadTime": ["count", "mean"]}).reset_index()

# SEGMENT Revenue LeadTime
# count mean count mean
# 0 D 29 216.516813 29 22.210802
# 1 C 29 341.635048 29 56.291879
# 2 B 29 470.204172 29 80.206429
# 3 A 29 596.331327 29 68.800687


#############################################
# Yeni gelen müşterileri sınıflandırınız ne kadar gelir getirebileceğini tahmin ediniz.
#############################################

# Nationality # Channel # Age
# --- --- ---
# PRT # _AGENT # _18_25
# GBR # _DIRECT # _26_40
# DEU # _CORPORATE # _41_50
# FRA # _ELECTRONIC # _51_60
# ESP # _60
# ITA

new_guest = "PRT_AGENT_18_25"

agg_df_final[agg_df_final["customers_level_based"] == new_guest]

# customers_level_based Revenue LeadTime SEGMENT
# 98 PRT_AGENT_18_25 402.508236 62.404329 C


new_guest = "ITA_ELECTRONIC_51_60"
agg_df_final[agg_df_final["customers_level_based"] == new_guest]

# customers_level_based Revenue LeadTime SEGMENT
# 96 ITA_ELECTRONIC_51_60 172.666667 12.0 D

0 comments on commit f2493a4

Please sign in to comment.