<jupyter_start><jupyter_text>Import Library dan Dataset<jupyter_code># Import Library
import pandas as pd
pd.options.display.max_columns = 50

# Import Dataset
df_load = pd.read_csv('../../Dataset/dqlab_telco.csv')
# Menampilkan jumlah baris dan kolom
df_load.shape
# Menampilkan 5 data teratas
df_load.head()
# Jumlah ID yang unik
df_load.customerID.nunique()<jupyter_output><empty_output><jupyter_text>Memfilter ID Number Pelanggan Format Tertentu Mencari format ID Number (Phone Number) Pelanggan customerID yang benar, dengan kriteria:1. Panjang karakter adalah 11-12.2. Terdiri dari angka Saja, tidak diperbolehkan ada karakter selain angka3. Diawali dengan angka 45 2 digit pertama.<jupyter_code>df_load['valid_id'] = df_load['customerID'].str.match(r'(45\d{9, 10})')
# df_load = (df_load[df_load['valid_id'] == True]).drop('valid_id', axis=1)  # data nya udah bener jadi di komen aja
print('Hasil jumlah ID Customer yang terfilter adalah', df_load['customerID'].count())<jupyter_output>Hasil jumlah ID Customer yang terfilter adalah 7113<jupyter_text>Memfilter Duplikasi ID Number Pelanggan Memastikan bahwa tidak ada Id Number pelanggan yang duplikat. Biasanya duplikasi ID number ini tipenya:1. Duplikasi dikarenakan inserting melebihi satu kali dengan nilai yang sama tiap kolomnya2. Duplikasi dikarenakan inserting beda periode pengambilan data<jupyter_code># Drop Duplicate Rows
df_load = df_load.drop_duplicates()

# Drop duplicate ID sorted by Periode
df_load = df_load.sort_values('UpdatedAt', ascending=False).drop_duplicates(['customerID'])
print('Hasil jumlah ID Customer yang sudah dihilangkan duplikasinya (distinct) adalah', df_load['customerID'].count())<jupyter_output>Hasil jumlah ID Customer yang sudah dihilangkan duplikasinya (distinct) adalah 7017<jupyter_text>Mengatasi Missing Values dengan Penghapusan Rows<jupyter_code>print('Total missing values data dari kolom Churn', df_load['Churn'].isnull().sum())
# Dropping all Rows with spesific column (churn)
df_load.dropna(subset=['Churn'], inplace=True)
print('Total Rows dan Kolom Data setelah dihapus data Missing Values adalah ', df_load.shape)<jupyter_output>Total Rows dan Kolom Data setelah dihapus data Missing Values adalah  (6974, 23)<jupyter_text>Mengatasi Missing Values dengan Pengisian Nilai tertentu<jupyter_code>print('Status Missing Values :', df_load.isnull().values.any())
print('Jumlah Missing Values masing-masing kolom, adalah:')
print(df_load.isnull().sum().sort_values(ascending=False))
#handling missing values Tenure fill with 11
df_load['tenure'].fillna(11, inplace=True)
#Loop
#Handling missing values num vars (except Tenure)
for col_name in list(['MonthlyCharges', 'TotalCharges']):
    median = df_load[col_name].median()
    df_load[col_name].fillna(median, inplace=True)

print('Jumlah missing values setelah di imputer datanya, adalah:') 
print(df_load.isnull().sum().sort_values(ascending=False))<jupyter_output>Jumlah missing values setelah di imputer datanya, adalah:
UpdatedAt           0
DeviceProtection    0
Churn               0
TotalCharges        0
MonthlyCharges      0
PaymentMethod       0
PaperlessBilling    0
Contract            0
StreamingMovies     0
StreamingTV         0
TechSupport         0
OnlineBackup        0
customerID          0
OnlineSecurity      0
InternetService     0
MultipleLines       0
PhoneService        0
tenure              0
Dependents          0
Partner             0
SeniorCitizen       0
gender              0
valid_id            0
dtype: int64<jupyter_text>Mendeteksi adanya Outlier (Boxplot) Mendeteksi pencilan dari suatu nilai (outlier) salah satunya bisa melihat plot dari data tersebut menggunakan boxplot. Boxplot merupakan ringkasan distribusi sampel yang disajikan secara grafis yang bisa menggambarkan bentuk distribusi data (skewness), ukuran tendensi sentral dan ukuran penyebaran (keragaman) data pengamatan.<jupyter_code>print('Persebaran data sebelum ditangani Outlier: ')
df_load[['tenure','MonthlyCharges','TotalCharges']].describe()
# Creating Box Plot
import matplotlib.pyplot as plt
import seaborn as sns

for col_name in list(['tenure', 'MonthlyCharges', 'TotalCharges']):
    plt.figure() # untuk membuat figure baru
    sns.boxplot(x=df_load[col_name])
    plt.show()<jupyter_output><empty_output><jupyter_text>Mengatasi Outlier Setelah kita mengetahui variable mana saja yang terdapat pencilan (outlier), selanjutnya kita akan atasi outlier dengan menggunakan metode interquartile range (IQR).<jupyter_code># Handling with IQR
Q1 = (df_load[['tenure', 'MonthlyCharges', 'TotalCharges']]).quantile(0.25)
Q3 = (df_load[['tenure', 'MonthlyCharges', 'TotalCharges']]).quantile(0.75)
IQR = Q3 - Q1
maximum = Q3 + (1.5*IQR)
print('Nilai Maximum dari masing-masing Variable adalah:')
print(maximum)
minimum = Q1 - (1.5 * IQR)
print('Nilai Minimum dari masing-masing Variable adalah:')
print(minimum)

more_than = (df_load > maximum)
lower_than = (df_load < minimum)
df_load = df_load.mask(more_than, maximum, axis=1)
df_load = df_load.mask(lower_than, minimum, axis=1)

print('Persebaran data setelah ditangani Outlier:')
print(df_load[['tenure', 'MonthlyCharges', 'TotalCharges']].describe())<jupyter_output>Nilai Maximum dari masing-masing Variable adalah:
tenure             124.00000
MonthlyCharges     169.95000
TotalCharges      8877.44375
dtype: float64
Nilai Minimum dari masing-masing Variable adalah:
tenure             -60.00000
MonthlyCharges     -43.65000
TotalCharges     -4679.00625
dtype: float64
Persebaran data setelah ditangani Outlier:
            tenure  MonthlyCharges  TotalCharges
count  6974.000000     6974.000000   6974.000000
mean     32.389016       64.998552   2284.393510
std      24.575185       30.037725   2265.154806
min       0.000000        0.000000     19.000000
25%       9.000000       36.450000    404.662500
50%      29.000000       70.450000   1400.550000
75%      55.000000       89.850000   3793.775000
max     124.000000      169.950000   8877.443750<jupyter_text>**Kesimpulan**Dari ketiga boxplot dengan variable 'tenure','MonthlyCharges' & 'TotalCharges' terlihat jelas bahwasannya ada outlier. Hal ini bisa di identifikasi dari adanya titik-titik yang berada jauh dari gambar boxplot-nya. Kemudian kalau kita liat persebaran datanya dari kolom max nya juga ada nilai yang sangat tinggi sekali.Kemudian nilai outlier tersebut ditangani dengan cara merubah nilainya ke nilai maximum & minimum dari interquartile range (IQR). Setelah di tangani outlier-nya, dan dilihat perseberan datanya, terlihat sudah tidak ada lagi nilai yang outlier.  Mendeteksi Nilai yang tidak Standar Mendeteksi apakah ada nilai-nilai dari variable kategorik yang tidak standard. Hal ini biasanya terjadi dikarenakan kesalahan input data. Perbedaan istilah menjadi salah satu faktor yang sering terjadi, untuk itu dibutuhkan standardisasi dari data yang sudah ter-input.<jupyter_code>df_load['SeniorCitizen'] = df_load['SeniorCitizen'].astype('object')
for col_name in list(df_load.select_dtypes(include='object').columns.drop('customerID')):
    print('\nUnique Values Count \033[1m' + 'Before Standardized \033[0m Variable', col_name)
    print(df_load[col_name].value_counts())<jupyter_output>Unique Values Count [1mBefore Standardized [0m Variable gender
Male         3581
Female       3512
Wanita         14
Laki-Laki       6
Name: gender, dtype: int64

Unique Values Count [1mBefore Standardized [0m Variable Partner
No     3676
Yes    3437
Name: Partner, dtype: int64

Unique Values Count [1mBefore Standardized [0m Variable Dependents
No     4978
Yes    2115
Iya      20
Name: Dependents, dtype: int64

Unique Values Count [1mBefore Standardized [0m Variable PhoneService
Yes    6423
No      690
Name: PhoneService, dtype: int64

Unique Values Count [1mBefore Standardized [0m Variable MultipleLines
No                  3428
Yes                 2995
No phone service     690
Name: MultipleLines, dtype: int64

Unique Values Count [1mBefore Standardized [0m Variable InternetService
Fiber optic    3125
DSL            2451
No             1537
Name: InternetService, dtype: int64

Unique Values Count [1mBefore Standardized [0m Variable OnlineSecurity
No                     [...]<jupyter_text>Menstandarisasi Variable Kategorik Setelah kita mengeteahui variable mana saja yang ada nilai tidak standard, maka kita standardkan dengan pola terbanyak nya, dengan syarat tanpa mengubah maknanya. Contoh : Iya -> Yes Kemudian liat kembali unique values dari masing-masing variable yang sudah di ubah.<jupyter_code>df_load = df_load.replace(['Wanita', 'Laki-Laki', 'Churn', 'Iya'], ['Female', 'Male', 'Yes', 'Yes'])

#Loop
for col_name in list(['gender', 'Dependents', 'Churn']):
    print('\nUnique Values Count \033[1m' + 'After Standardized\033[0m Variable', col_name)
    print(df_load[col_name].value_counts())<jupyter_output>Unique Values Count [1mAfter Standardized[0m Variable gender
Male      3587
Female    3526
Name: gender, dtype: int64

Unique Values Count [1mAfter Standardized[0m Variable Dependents
No     4978
Yes    2135
Name: Dependents, dtype: int64

Unique Values Count [1mAfter Standardized[0m Variable Churn
No     5195
Yes    1875
Name: Churn, dtype: int64
{'fraction_non_alphanumeric': 0.08384991843393148, 'fraction_numerical': 0.05274605764002175, 'mean_word_length': 4.621026894865525, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '161453', 'license': 'MIT', 'n_tokens_mistral': 3595, 'n_tokens_neox': 3152, 'n_words': 891, 'path': 'Learn/Applied Data Science/Data Science in Telco-Data Cleansing.ipynb', 'repo_name': 'chiefryra/DQLab', 'size': '9195'}