<jupyter_start><jupyter_text>Load Dataset<jupyter_code>use_cols = [
    'Pclass', 'Sex', 'Age', 'Fare', 'SibSp',
    'Survived'
]

data = pd.read_csv('./data/titanic.csv', usecols=use_cols)

data.head(3)
# Note that we include target variable in the X_train 
# because we need it to supervise our discretization
# this is not the standard way of using train-test-split
X_train, X_test, y_train, y_test = train_test_split(data, data.Survived, test_size=0.3,
                                                    random_state=0)
X_train.shape, X_test.shape<jupyter_output><empty_output><jupyter_text>Equal width binningdivides the scope of possible values into N bins of the same width<jupyter_code>from sklearn.preprocessing import KBinsDiscretizer
enc_equal_width = KBinsDiscretizer(n_bins=3,encode='ordinal',strategy='uniform').fit(X_train[['Fare']])
# equal width for every bins
enc_equal_width.bin_edges_
result = enc_equal_width.transform(X_train[['Fare']])
pd.DataFrame(result)[0].value_counts()
# add the new discretized variable
X_train_copy = X_train.copy(deep=True)
X_train_copy['Fare_equal_width'] = enc_equal_width.transform(X_train[['Fare']])
print(X_train_copy.head(10))<jupyter_output>Survived  Pclass     Sex   Age  SibSp      Fare  Fare_equal_width
857         1       1    male  51.0      0   26.5500               0.0
52          1       1  female  49.0      1   76.7292               0.0
386         0       3    male   1.0      5   46.9000               0.0
124         0       1    male  54.0      0   77.2875               0.0
578         0       3  female   NaN      1   14.4583               0.0
549         1       2    male   8.0      1   36.7500               0.0
118         0       1    male  24.0      0  247.5208               1.0
12          0       3    male  20.0      0    8.0500               0.0
157         0       3    male  30.0      0    8.0500               0.0
127         1       3    male  24.0      0    7.1417               0.0<jupyter_text>Equal frequency binningdivides the scope of possible values of the variable into N bins, where each bin carries the same amount of observations<jupyter_code>enc_equal_freq = KBinsDiscretizer(n_bins=3,encode='ordinal',strategy='quantile').fit(X_train[['Fare']])
# check the bin edges
enc_equal_freq.bin_edges_
# equal number of case for every bins
result = enc_equal_freq.transform(X_train[['Fare']])
pd.DataFrame(result)[0].value_counts()
# add the new discretized variable
X_train_copy = X_train.copy(deep=True)
X_train_copy['Fare_equal_freq'] = enc_equal_freq.transform(X_train[['Fare']])
print(X_train_copy.head(10))<jupyter_output>Survived  Pclass     Sex   Age  SibSp      Fare  Fare_equal_freq
857         1       1    male  51.0      0   26.5500              2.0
52          1       1  female  49.0      1   76.7292              2.0
386         0       3    male   1.0      5   46.9000              2.0
124         0       1    male  54.0      0   77.2875              2.0
578         0       3  female   NaN      1   14.4583              1.0
549         1       2    male   8.0      1   36.7500              2.0
118         0       1    male  24.0      0  247.5208              2.0
12          0       3    male  20.0      0    8.0500              0.0
157         0       3    male  30.0      0    8.0500              0.0
127         1       3    male  24.0      0    7.1417              0.0<jupyter_text>K-means binningusing k-means to partition values into clusters<jupyter_code>enc_kmeans = KBinsDiscretizer(n_bins=3,encode='ordinal',strategy='kmeans').fit(X_train[['Fare']])
# check the bin edges
enc_kmeans.bin_edges_
result = enc_kmeans.transform(X_train[['Fare']])
pd.DataFrame(result)[0].value_counts()
# add the new discretized variable
X_train_copy = X_train.copy(deep=True)
X_train_copy['Fare_kmeans'] = enc_kmeans.transform(X_train[['Fare']])
print(X_train_copy.head(10))<jupyter_output>Survived  Pclass     Sex   Age  SibSp      Fare  Fare_kmeans
857         1       1    male  51.0      0   26.5500          0.0
52          1       1  female  49.0      1   76.7292          0.0
386         0       3    male   1.0      5   46.9000          0.0
124         0       1    male  54.0      0   77.2875          0.0
578         0       3  female   NaN      1   14.4583          0.0
549         1       2    male   8.0      1   36.7500          0.0
118         0       1    male  24.0      0  247.5208          1.0
12          0       3    male  20.0      0    8.0500          0.0
157         0       3    male  30.0      0    8.0500          0.0
127         1       3    male  24.0      0    7.1417          0.0<jupyter_text>Discretisation with Decision Treeusing a decision tree to identify the optimal splitting points that would determine the bins<jupyter_code>enc1 = dc.DiscretizeByDecisionTree(col='Fare',max_depth=2).fit(X=X_train,y=y_train)
enc1.tree_model
data1 = enc1.transform(data)
# see how the new column Fare_tree_discret is distributed
# the values are corresponding to the proba of the prediction by the tree
print(data1.head(5))

# the unique value of the discretisized column
print(data1.Fare_tree_discret.unique())
# see how the bins are cut
# because we use a tree with max-depth of 2, we have at most 2*2=4 bins generated by the tree
col='Fare'
bins = pd.concat([data1.groupby([col+'_tree_discret'])[col].min(),
                  data1.groupby([col+'_tree_discret'])[col].max()], axis=1)
print(bins)

# all values between 0 to 7.5208 in the original variable 'Fare' 
# are given new value 0.107143 in the new column 'Fare_tree_discret'
# and so on<jupyter_output>Fare      Fare
Fare_tree_discret                   
0.107143            0.0000    7.5208
0.255319            7.5500   10.5167
0.442308           11.1333   73.5000
0.746269           75.2500  512.3292<jupyter_text>Discretisation with Decision Tree with optimal depth search<jupyter_code># search for the best depth from range 2-7
# we see when depth=2 we get the best roc-auc mean
enc2 = dc.DiscretizeByDecisionTree(col='Fare',max_depth=[2,3,4,5,6,7]).fit(X=X_train,y=y_train)
# using optimal depth=2 we train the model, same result as last one
enc2.tree_model
data2 = enc2.transform(data)
data2.head(5)<jupyter_output><empty_output><jupyter_text>Discretisation with ChiMergesupervised hierarchical bottom-up (merge) method that locally exploits the chi-square criterion to decide whether two adjacent intervals are similar enough to be merged<jupyter_code>enc3 = dc.ChiMerge(col='Fare',num_of_bins=5).fit(X=X_train,y='Survived')
# the bins boundary created by ChiMerge

enc3.bins
data3 = enc3.transform(data)
print(data3.head(5))
# all values are grouped into 5 intervals
data3.Fare_chimerge.unique()<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup