Binning (Diskritisasi) menggunakan K-Means Clustering#
Clusterisasi dengan K-Means#
Clusterisasi dengan K-Means digunakan untuk mengelompokkan data pada fitur Sepal Length menjadi 4 kelompok (klaster) yaitu 0, 1, 2, 3, 4 berdasarkan tingkat kemiripan nilai. Proses ini dilakukan dengan cara mengelompokkan data yang memiliki nilai panjang sepal yang saling berdekatan ke dalam satu klaster yang sama. Nantinya setiap klaster yang terbentuk akan mewakili satu interval nilai.
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import silhouette_score, accuracy_score
import pandas as pd
# Baca data fitur dan label
df_features = pd.read_excel("data_iris.xlsx")
df_class = pd.read_excel("class.xlsx")
# Gabungkan data fitur dan label
df = df_features.copy()
df['class'] = df_class['class']
# Ambil hanya kolom sepal_length
features = df[['sepal_length']]
# Normalisasi fitur
scaler = MinMaxScaler()
scaled_features = scaler.fit_transform(features)
# Clustering KMeans dengan 4 klaster
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
kmeans.fit(scaled_features)
# Simpan hasil cluster ke dataframe
df['cluster'] = kmeans.labels_
# Evaluasi
print(f"Jumlah iterasi sampai konvergen: {kmeans.n_iter_}")
print(f"Inertia (SSE): {kmeans.inertia_:.4f}")
sil_score = silhouette_score(scaled_features, kmeans.labels_)
print(f"Silhouette Score: {sil_score:.4f}")
# Pemetaan cluster ke class mayoritas
mapping = (
df.groupby('cluster')['class']
.agg(lambda x: x.mode()[0])
.to_dict()
)
df['predicted_class'] = df['cluster'].map(mapping)
# Hitung akurasi prediksi clustering terhadap label asli
y_true = df['class']
y_pred = df['predicted_class']
acc = accuracy_score(y_true, y_pred)
print(f"\nAkurasi keseluruhan clustering terhadap label asli: {acc:.4%}")
# Tampilkan distribusi cluster per kelas
dist = pd.crosstab(df['class'], df['cluster'], rownames=['Class'], colnames=['Cluster'])
print("\nDistribusi cluster per kelas:")
print(dist)
# Simpan hasil ke Excel
df.to_excel("clus_dis.xlsx", index=False)
# Jika ingin tampilkan semua hasil
pd.set_option('display.max_rows', None)
print(df[['class', 'cluster', 'predicted_class']])
Jumlah iterasi sampai konvergen: 2
Inertia (SSE): 0.6416
Silhouette Score: 0.5920
Akurasi keseluruhan clustering terhadap label asli: 72.0000%
Distribusi cluster per kelas:
Cluster 0 1 2 3
Class
Iris-setosa 10 0 40 0
Iris-versicolor 29 0 5 16
Iris-virginica 10 12 1 27
class cluster predicted_class
0 Iris-setosa 2 Iris-setosa
1 Iris-setosa 2 Iris-setosa
2 Iris-setosa 2 Iris-setosa
3 Iris-setosa 2 Iris-setosa
4 Iris-setosa 2 Iris-setosa
5 Iris-setosa 0 Iris-versicolor
6 Iris-setosa 2 Iris-setosa
7 Iris-setosa 2 Iris-setosa
8 Iris-setosa 2 Iris-setosa
9 Iris-setosa 2 Iris-setosa
10 Iris-setosa 0 Iris-versicolor
11 Iris-setosa 2 Iris-setosa
12 Iris-setosa 2 Iris-setosa
13 Iris-setosa 2 Iris-setosa
14 Iris-setosa 0 Iris-versicolor
15 Iris-setosa 0 Iris-versicolor
16 Iris-setosa 0 Iris-versicolor
17 Iris-setosa 2 Iris-setosa
18 Iris-setosa 0 Iris-versicolor
19 Iris-setosa 2 Iris-setosa
20 Iris-setosa 0 Iris-versicolor
21 Iris-setosa 2 Iris-setosa
22 Iris-setosa 2 Iris-setosa
23 Iris-setosa 2 Iris-setosa
24 Iris-setosa 2 Iris-setosa
25 Iris-setosa 2 Iris-setosa
26 Iris-setosa 2 Iris-setosa
27 Iris-setosa 2 Iris-setosa
28 Iris-setosa 2 Iris-setosa
29 Iris-setosa 2 Iris-setosa
30 Iris-setosa 2 Iris-setosa
31 Iris-setosa 0 Iris-versicolor
32 Iris-setosa 2 Iris-setosa
33 Iris-setosa 0 Iris-versicolor
34 Iris-setosa 2 Iris-setosa
35 Iris-setosa 2 Iris-setosa
36 Iris-setosa 0 Iris-versicolor
37 Iris-setosa 2 Iris-setosa
38 Iris-setosa 2 Iris-setosa
39 Iris-setosa 2 Iris-setosa
40 Iris-setosa 2 Iris-setosa
41 Iris-setosa 2 Iris-setosa
42 Iris-setosa 2 Iris-setosa
43 Iris-setosa 2 Iris-setosa
44 Iris-setosa 2 Iris-setosa
45 Iris-setosa 2 Iris-setosa
46 Iris-setosa 2 Iris-setosa
47 Iris-setosa 2 Iris-setosa
48 Iris-setosa 2 Iris-setosa
49 Iris-setosa 2 Iris-setosa
50 Iris-versicolor 3 Iris-virginica
51 Iris-versicolor 3 Iris-virginica
52 Iris-versicolor 3 Iris-virginica
53 Iris-versicolor 0 Iris-versicolor
54 Iris-versicolor 3 Iris-virginica
55 Iris-versicolor 0 Iris-versicolor
56 Iris-versicolor 3 Iris-virginica
57 Iris-versicolor 2 Iris-setosa
58 Iris-versicolor 3 Iris-virginica
59 Iris-versicolor 2 Iris-setosa
60 Iris-versicolor 2 Iris-setosa
61 Iris-versicolor 0 Iris-versicolor
62 Iris-versicolor 0 Iris-versicolor
63 Iris-versicolor 0 Iris-versicolor
64 Iris-versicolor 0 Iris-versicolor
65 Iris-versicolor 3 Iris-virginica
66 Iris-versicolor 0 Iris-versicolor
67 Iris-versicolor 0 Iris-versicolor
68 Iris-versicolor 3 Iris-virginica
69 Iris-versicolor 0 Iris-versicolor
70 Iris-versicolor 0 Iris-versicolor
71 Iris-versicolor 0 Iris-versicolor
72 Iris-versicolor 3 Iris-virginica
73 Iris-versicolor 0 Iris-versicolor
74 Iris-versicolor 3 Iris-virginica
75 Iris-versicolor 3 Iris-virginica
76 Iris-versicolor 3 Iris-virginica
77 Iris-versicolor 3 Iris-virginica
78 Iris-versicolor 0 Iris-versicolor
79 Iris-versicolor 0 Iris-versicolor
80 Iris-versicolor 0 Iris-versicolor
81 Iris-versicolor 0 Iris-versicolor
82 Iris-versicolor 0 Iris-versicolor
83 Iris-versicolor 0 Iris-versicolor
84 Iris-versicolor 0 Iris-versicolor
85 Iris-versicolor 0 Iris-versicolor
86 Iris-versicolor 3 Iris-virginica
87 Iris-versicolor 3 Iris-virginica
88 Iris-versicolor 0 Iris-versicolor
89 Iris-versicolor 0 Iris-versicolor
90 Iris-versicolor 0 Iris-versicolor
91 Iris-versicolor 0 Iris-versicolor
92 Iris-versicolor 0 Iris-versicolor
93 Iris-versicolor 2 Iris-setosa
94 Iris-versicolor 0 Iris-versicolor
95 Iris-versicolor 0 Iris-versicolor
96 Iris-versicolor 0 Iris-versicolor
97 Iris-versicolor 3 Iris-virginica
98 Iris-versicolor 2 Iris-setosa
99 Iris-versicolor 0 Iris-versicolor
100 Iris-virginica 3 Iris-virginica
101 Iris-virginica 0 Iris-versicolor
102 Iris-virginica 1 Iris-virginica
103 Iris-virginica 3 Iris-virginica
104 Iris-virginica 3 Iris-virginica
105 Iris-virginica 1 Iris-virginica
106 Iris-virginica 2 Iris-setosa
107 Iris-virginica 1 Iris-virginica
108 Iris-virginica 3 Iris-virginica
109 Iris-virginica 1 Iris-virginica
110 Iris-virginica 3 Iris-virginica
111 Iris-virginica 3 Iris-virginica
112 Iris-virginica 3 Iris-virginica
113 Iris-virginica 0 Iris-versicolor
114 Iris-virginica 0 Iris-versicolor
115 Iris-virginica 3 Iris-virginica
116 Iris-virginica 3 Iris-virginica
117 Iris-virginica 1 Iris-virginica
118 Iris-virginica 1 Iris-virginica
119 Iris-virginica 0 Iris-versicolor
120 Iris-virginica 3 Iris-virginica
121 Iris-virginica 0 Iris-versicolor
122 Iris-virginica 1 Iris-virginica
123 Iris-virginica 3 Iris-virginica
124 Iris-virginica 3 Iris-virginica
125 Iris-virginica 1 Iris-virginica
126 Iris-virginica 3 Iris-virginica
127 Iris-virginica 0 Iris-versicolor
128 Iris-virginica 3 Iris-virginica
129 Iris-virginica 1 Iris-virginica
130 Iris-virginica 1 Iris-virginica
131 Iris-virginica 1 Iris-virginica
132 Iris-virginica 3 Iris-virginica
133 Iris-virginica 3 Iris-virginica
134 Iris-virginica 0 Iris-versicolor
135 Iris-virginica 1 Iris-virginica
136 Iris-virginica 3 Iris-virginica
137 Iris-virginica 3 Iris-virginica
138 Iris-virginica 0 Iris-versicolor
139 Iris-virginica 3 Iris-virginica
140 Iris-virginica 3 Iris-virginica
141 Iris-virginica 3 Iris-virginica
142 Iris-virginica 0 Iris-versicolor
143 Iris-virginica 3 Iris-virginica
144 Iris-virginica 3 Iris-virginica
145 Iris-virginica 3 Iris-virginica
146 Iris-virginica 3 Iris-virginica
147 Iris-virginica 3 Iris-virginica
148 Iris-virginica 3 Iris-virginica
149 Iris-virginica 0 Iris-versicolor
Cari Min Max dan Centroid dari fitur sepal length#
Pada tahap ini diperoleh informasi statistik yang mencakup nilai minimum (min), maksimum (max), dan centroid (nilai rata-rata) dari masing-masing cluster yang terbentuk. Statistik min dan max yang diperoleh dari hasil clustering ini nantinya dapat digunakan sebagai batas interval dalam proses diskritisasi fitur Sepal Length, sedangkan centroid dapat dimanfaatkan sebagai representasi numerik atau label diskrit dari masing-masing interval. Setiap data Sepal Length yang berada dalam suatu rentang (min hingga max) akan diberi label sesuai klaster tempatnya berada, menjadikan fitur tersebut tidak lagi berbentuk kontinu, melainkan sudah dalam bentuk kategori.
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
# Contoh Data
df = pd.read_excel("clus_dis.xlsx")
features = df[['sepal_length']]
# Normalisasi
scaler = MinMaxScaler()
scaled_features = scaler.fit_transform(features)
# KMeans Clustering
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
kmeans.fit(scaled_features)
# Tambahkan hasil cluster ke data
df['cluster'] = kmeans.labels_
# Ambil centroid dari hasil clustering (dalam skala normalisasi)
centroids_scaled = kmeans.cluster_centers_
# Konversi centroid ke skala asli
centroids_original = scaler.inverse_transform(centroids_scaled)
# Hitung min, max, dan centroid per klaster
cluster_stats = df.groupby('cluster')['sepal_length'].agg(['min', 'max']).copy()
cluster_stats['centroid'] = centroids_original.flatten()
# Tampilkan hasil
print("\nStatistik Sepal Length per Cluster:")
print(cluster_stats)
Statistik Sepal Length per Cluster:
min max centroid
cluster
0 5.4 6.1 5.734694
1 7.1 7.9 7.475000
2 4.3 5.3 4.895652
3 6.2 7.0 6.525581
Output tersebut adalah statistik dari fitur Sepal Length yang telah dikelompokkan ke dalam 4 klaster menggunakan KMeans Clustering. Untuk masing-masing klaster ditampilkan:
min: Nilai terkecil dari Sepal Length dalam klaster tersebut. Bisa digunakan sebagai batas bawah interval.
max: Nilai terbesar dari Sepal Length dalam klaster tersebut. Bisa digunakan sebagai batas atas interval.
centroid: Nilai rata-rata (mean) dari Sepal Length dalam klaster tersebut, yang merupakan pusat dari klaster (hasil centroids_ dari KMeans).
Statistik min max dapat digunakan sebagai interval untuk diskritisasi pada fitur sepal_length
Hasil Diskritisasi fitur sepal length#
Pada tahap ini dilakukan proses diskritisasi terhadap fitur numerik sepal_length berdasarkan hasil klasterisasi sebelumnya. Setiap data telah dikelompokkan ke dalam klaster menggunakan algoritma K-Means, dan hasil klaster tersebut kemudian digunakan untuk memberi label diskrit pada nilai sepal_length. Contoh, pada baris pertama, nilai sepal_length_original adalah 5.1 dan termasuk dalam klaster 2 berdasarkan rentang min max, sehingga label diskritisasi menjadi ‘C’. Dengan pendekatan ini, fitur sepal_length yang semula berupa nilai kontinu kini telah dikonversi menjadi fitur kategori.
# Pemetaan cluster ke label huruf
cluster_to_label = {
0: 'A',
1: 'B',
2: 'C',
3: 'D'
}
# Salin kolom sepal_length asli ke kolom baru (agar data numerik tetap tersimpan)
df['sepal_length_original'] = df['sepal_length']
# Gantikan nilai sepal_length dengan huruf berdasarkan klaster
df['sepal_length'] = df['cluster'].map(cluster_to_label)
# Tampilkan hasil
print(df[['cluster', 'sepal_length', 'sepal_length_original']])
cluster sepal_length sepal_length_original
0 2 C 5.1
1 2 C 4.9
2 2 C 4.7
3 2 C 4.6
4 2 C 5.0
5 0 A 5.4
6 2 C 4.6
7 2 C 5.0
8 2 C 4.4
9 2 C 4.9
10 0 A 5.4
11 2 C 4.8
12 2 C 4.8
13 2 C 4.3
14 0 A 5.8
15 0 A 5.7
16 0 A 5.4
17 2 C 5.1
18 0 A 5.7
19 2 C 5.1
20 0 A 5.4
21 2 C 5.1
22 2 C 4.6
23 2 C 5.1
24 2 C 4.8
25 2 C 5.0
26 2 C 5.0
27 2 C 5.2
28 2 C 5.2
29 2 C 4.7
30 2 C 4.8
31 0 A 5.4
32 2 C 5.2
33 0 A 5.5
34 2 C 4.9
35 2 C 5.0
36 0 A 5.5
37 2 C 4.9
38 2 C 4.4
39 2 C 5.1
40 2 C 5.0
41 2 C 4.5
42 2 C 4.4
43 2 C 5.0
44 2 C 5.1
45 2 C 4.8
46 2 C 5.1
47 2 C 4.6
48 2 C 5.3
49 2 C 5.0
50 3 D 7.0
51 3 D 6.4
52 3 D 6.9
53 0 A 5.5
54 3 D 6.5
55 0 A 5.7
56 3 D 6.3
57 2 C 4.9
58 3 D 6.6
59 2 C 5.2
60 2 C 5.0
61 0 A 5.9
62 0 A 6.0
63 0 A 6.1
64 0 A 5.6
65 3 D 6.7
66 0 A 5.6
67 0 A 5.8
68 3 D 6.2
69 0 A 5.6
70 0 A 5.9
71 0 A 6.1
72 3 D 6.3
73 0 A 6.1
74 3 D 6.4
75 3 D 6.6
76 3 D 6.8
77 3 D 6.7
78 0 A 6.0
79 0 A 5.7
80 0 A 5.5
81 0 A 5.5
82 0 A 5.8
83 0 A 6.0
84 0 A 5.4
85 0 A 6.0
86 3 D 6.7
87 3 D 6.3
88 0 A 5.6
89 0 A 5.5
90 0 A 5.5
91 0 A 6.1
92 0 A 5.8
93 2 C 5.0
94 0 A 5.6
95 0 A 5.7
96 0 A 5.7
97 3 D 6.2
98 2 C 5.1
99 0 A 5.7
100 3 D 6.3
101 0 A 5.8
102 1 B 7.1
103 3 D 6.3
104 3 D 6.5
105 1 B 7.6
106 2 C 4.9
107 1 B 7.3
108 3 D 6.7
109 1 B 7.2
110 3 D 6.5
111 3 D 6.4
112 3 D 6.8
113 0 A 5.7
114 0 A 5.8
115 3 D 6.4
116 3 D 6.5
117 1 B 7.7
118 1 B 7.7
119 0 A 6.0
120 3 D 6.9
121 0 A 5.6
122 1 B 7.7
123 3 D 6.3
124 3 D 6.7
125 1 B 7.2
126 3 D 6.2
127 0 A 6.1
128 3 D 6.4
129 1 B 7.2
130 1 B 7.4
131 1 B 7.9
132 3 D 6.4
133 3 D 6.3
134 0 A 6.1
135 1 B 7.7
136 3 D 6.3
137 3 D 6.4
138 0 A 6.0
139 3 D 6.9
140 3 D 6.7
141 3 D 6.9
142 0 A 5.8
143 3 D 6.8
144 3 D 6.7
145 3 D 6.7
146 3 D 6.3
147 3 D 6.5
148 3 D 6.2
149 0 A 5.9
Mengganti fitur sepal_length(numeriks) ke sepal_length (kategorikal)#
Pada tahap ini, dilakukan proses transformasi fitur sepal_length dari tipe data numerik menjadi kategorikal. Proses ini diawali dengan membaca ulang data iris asli serta data kelas referensi. Data kemudian digabungkan agar fitur sepal_length dapat diproses bersama label kelasnya. Selanjutnya, nilai sepal_length dinormalisasi menggunakan Min-Max Scaler agar seluruh nilai berada dalam rentang 0 hingga 1. Proses normalisasi ini penting untuk meningkatkan performa algoritma K-Means, yang sensitif terhadap skala data.
Setelah dinormalisasi, dilakukan proses klasterisasi menggunakan algoritma K-Means dengan jumlah klaster sebanyak empat. Setiap data kemudian memperoleh label klaster tertentu berdasarkan nilai sepal_length yang dimilikinya. Hasil klasterisasi disimpan dalam kolom baru bernama cluster.Kemudian, nilai klaster tersebut dipetakan ke dalam label kategorikal berupa huruf (‘A’, ‘B’, ‘C’, ‘D’) untuk menggantikan nilai numerik pada fitur sepal_length. Dengan demikian, fitur sepal_length yang semula bertipe numerik kini telah diubah menjadi fitur kategorikal atau diskrit.
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler
df_features = pd.read_excel("clus_dis.xlsx")
df_class = pd.read_excel("class.xlsx")
# Gabungkan dengan class
df = df_features.copy()
df['class'] = df_class['class']
# Clustering ulang fitur sepal_length
features = df[['sepal_length']]
scaler = MinMaxScaler()
scaled_features = scaler.fit_transform(features)
kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)
kmeans.fit(scaled_features)
df['cluster'] = kmeans.labels_
# Map hasil cluster ke kategori
cluster_to_category = {
0: 'A',
2: 'B',
3: 'C',
1: 'D'
}
df['sepal_length'] = df['cluster'].map(cluster_to_category)
# Hapus kolom yang tidak perlu
df_result = df.drop(columns=[col for col in ['cluster', 'class', 'predicted_class'] if col in df.columns])
# Simpan
df_result.to_excel("data_iris_sepal_kategori.xlsx", index=False)
# Tampilkan sebagian hasil
pd.set_option('display.max_rows', None)
print(df_result)
id petal_length petal_width sepal_length sepal_width
0 1 1.4 0.2 B 3.5
1 2 1.4 0.2 B 3.0
2 3 1.3 0.2 B 3.2
3 4 1.5 0.2 B 3.1
4 5 1.4 0.2 B 3.6
5 6 1.7 0.4 A 3.9
6 7 1.4 0.3 B 3.4
7 8 1.5 0.2 B 3.4
8 9 1.4 0.2 B 2.9
9 10 1.5 0.1 B 3.1
10 11 1.5 0.2 A 3.7
11 12 1.6 0.2 B 3.4
12 13 1.4 0.1 B 3.0
13 14 1.1 0.1 B 3.0
14 15 1.2 0.2 A 4.0
15 16 1.5 0.4 A 4.4
16 17 1.3 0.4 A 3.9
17 18 1.4 0.3 B 3.5
18 19 1.7 0.3 A 3.8
19 20 1.5 0.3 B 3.8
20 21 1.7 0.2 A 3.4
21 22 1.5 0.4 B 3.7
22 23 1.0 0.2 B 3.6
23 24 1.7 0.5 B 3.3
24 25 1.9 0.2 B 3.4
25 26 1.6 0.2 B 3.0
26 27 1.6 0.4 B 3.4
27 28 1.5 0.2 B 3.5
28 29 1.4 0.2 B 3.4
29 30 1.6 0.2 B 3.2
30 31 1.6 0.2 B 3.1
31 32 1.5 0.4 A 3.4
32 33 1.5 0.1 B 4.1
33 34 1.4 0.2 A 4.2
34 35 1.5 0.1 B 3.1
35 36 1.2 0.2 B 3.2
36 37 1.3 0.2 A 3.5
37 38 1.5 0.1 B 3.1
38 39 1.3 0.2 B 3.0
39 40 1.5 0.2 B 3.4
40 41 1.3 0.3 B 3.5
41 42 1.3 0.3 B 2.3
42 43 1.3 0.2 B 3.2
43 44 1.6 0.6 B 3.5
44 45 1.9 0.4 B 3.8
45 46 1.4 0.3 B 3.0
46 47 1.6 0.2 B 3.8
47 48 1.4 0.2 B 3.2
48 49 1.5 0.2 B 3.7
49 50 1.4 0.2 B 3.3
50 51 4.7 1.4 C 3.2
51 52 4.5 1.5 C 3.2
52 53 4.9 1.5 C 3.1
53 54 4.0 1.3 A 2.3
54 55 4.6 1.5 C 2.8
55 56 4.5 1.3 A 2.8
56 57 4.7 1.6 C 3.3
57 58 3.3 1.0 B 2.4
58 59 4.6 1.3 C 2.9
59 60 3.9 1.4 B 2.7
60 61 3.5 1.0 B 2.0
61 62 4.2 1.5 A 3.0
62 63 4.0 1.0 A 2.2
63 64 4.7 1.4 A 2.9
64 65 3.6 1.3 A 2.9
65 66 4.4 1.4 C 3.1
66 67 4.5 1.5 A 3.0
67 68 4.1 1.0 A 2.7
68 69 4.5 1.5 C 2.2
69 70 3.9 1.1 A 2.5
70 71 4.8 1.8 A 3.2
71 72 4.0 1.3 A 2.8
72 73 4.9 1.5 C 2.5
73 74 4.7 1.2 A 2.8
74 75 4.3 1.3 C 2.9
75 76 4.4 1.4 C 3.0
76 77 4.8 1.4 C 2.8
77 78 5.0 1.7 C 3.0
78 79 4.5 1.5 A 2.9
79 80 3.5 1.0 A 2.6
80 81 3.8 1.1 A 2.4
81 82 3.7 1.0 A 2.4
82 83 3.9 1.2 A 2.7
83 84 5.1 1.6 A 2.7
84 85 4.5 1.5 A 3.0
85 86 4.5 1.6 A 3.4
86 87 4.7 1.5 C 3.1
87 88 4.4 1.3 C 2.3
88 89 4.1 1.3 A 3.0
89 90 4.0 1.3 A 2.5
90 91 4.4 1.2 A 2.6
91 92 4.6 1.4 A 3.0
92 93 4.0 1.2 A 2.6
93 94 3.3 1.0 B 2.3
94 95 4.2 1.3 A 2.7
95 96 4.2 1.2 A 3.0
96 97 4.2 1.3 A 2.9
97 98 4.3 1.3 C 2.9
98 99 3.0 1.1 B 2.5
99 100 4.1 1.3 A 2.8
100 101 6.0 2.5 C 3.3
101 102 5.1 1.9 A 2.7
102 103 5.9 2.1 D 3.0
103 104 5.6 1.8 C 2.9
104 105 5.8 2.2 C 3.0
105 106 6.6 2.1 D 3.0
106 107 4.5 1.7 B 2.5
107 108 6.3 1.8 D 2.9
108 109 5.8 1.8 C 2.5
109 110 6.1 2.5 D 3.6
110 111 5.1 2.0 C 3.2
111 112 5.3 1.9 C 2.7
112 113 5.5 2.1 C 3.0
113 114 5.0 2.0 A 2.5
114 115 5.1 2.4 A 2.8
115 116 5.3 2.3 C 3.2
116 117 5.5 1.8 C 3.0
117 118 6.7 2.2 D 3.8
118 119 6.9 2.3 D 2.6
119 120 5.0 1.5 A 2.2
120 121 5.7 2.3 C 3.2
121 122 4.9 2.0 A 2.8
122 123 6.7 2.0 D 2.8
123 124 4.9 1.8 C 2.7
124 125 5.7 2.1 C 3.3
125 126 6.0 1.8 D 3.2
126 127 4.8 1.8 C 2.8
127 128 4.9 1.8 A 3.0
128 129 5.6 2.1 C 2.8
129 130 5.8 1.6 D 3.0
130 131 6.1 1.9 D 2.8
131 132 6.4 2.0 D 3.8
132 133 5.6 2.2 C 2.8
133 134 5.1 1.5 C 2.8
134 135 5.6 1.4 A 2.6
135 136 6.1 2.3 D 3.0
136 137 5.6 2.4 C 3.4
137 138 5.5 1.8 C 3.1
138 139 4.8 1.8 A 3.0
139 140 5.4 2.1 C 3.1
140 141 5.6 2.4 C 3.1
141 142 5.1 2.3 C 3.1
142 143 5.1 1.9 A 2.7
143 144 5.9 2.3 C 3.2
144 145 5.7 2.5 C 3.3
145 146 5.2 2.3 C 3.0
146 147 5.0 1.9 C 2.5
147 148 5.2 2.0 C 3.0
148 149 5.4 2.3 C 3.4
149 150 5.1 1.8 A 3.0
Melakukan proses diskritisasi dengan K-means clustering pada fitur lainya#
Setelah sebelumnya dilakukan diskritisasi pada fitur sepal_length, tahap ini melanjutkan proses diskritisasi terhadap fitur numerik lainnya, yaitu sepal_width, petal_length, dan petal_width. Metode yang digunakan adalah K-Means Clustering, yang diterapkan secara terpisah pada masing-masing fitur. Pertama, data iris asli dan versi data yang sudah mengandung sepal_length kategorikal dibaca. Kemudian dibuat sebuah fungsi cluster_kategori_stat() yang bertugas melakukan normalisasi menggunakan Min-Max Scaler, proses clustering dengan KMeans, serta menghasilkan kategori huruf berdasarkan label cluster. Fungsi ini juga menghasilkan statistik nilai minimum, maksimum, dan centroid (rata-rata) untuk setiap cluster dari fitur yang didiskritisasi.
Fitur sepal_width dikelompokkan ke dalam 3 kategori (‘A’, ‘B’, ‘C’).
Fitur petal_length dikelompokkan ke dalam 4 kategori (‘A’, ‘B’, ‘C’, ‘D’).
Fitur petal_width juga dikelompokkan ke dalam 3 kategori (‘A’, ‘B’, ‘C’).
import pandas as pd
from sklearn.preprocessing import KBinsDiscretizer
import numpy as np # Untuk np.nan jika perlu
# --- 1. Baca data awal ---
# Menggunakan nama file yang telah Anda sediakan
try:
df_numerik = pd.read_excel("data_iris_sepal_kategori.xlsx")
# Untuk df_kategori, kita akan memulainya dari df_numerik dan menambahkan kolom kategori.
# Asumsi: sepal_length sudah ada di df_numerik.
df_kategori = df_numerik[['id', 'sepal_length']].copy()
except FileNotFoundError as e:
print(f"Error loading file: {e}. Pastikan file berada di direktori yang sama.")
exit()
# --- 2. Fungsi bantu diskritisasi + mapping + statistik ---
def discretize_kbins_stat(data_col, n_bins, label_map, strategy='kmeans'):
"""
Melakukan diskritisasi menggunakan KBinsDiscretizer dan menghitung statistik.
Args:
data_col (pd.Series): Kolom data numerik yang akan didiskritisasi.
n_bins (int): Jumlah bin/kategori yang diinginkan.
label_map (dict): Kamus untuk memetakan label numerik (0, 1, ...) ke label kategori (A, B, ...).
strategy (str): Strategi diskritisasi ('uniform', 'quantile', 'kmeans'). Default 'kmeans'.
Returns:
tuple: (pd.Series kategori, pd.DataFrame statistik)
"""
# Inisialisasi KBinsDiscretizer
# encode='ordinal' berarti outputnya adalah integer (0, 1, ...)
# strategy='kmeans' akan mencoba membuat bin berdasarkan klaster KMeans
discretizer = KBinsDiscretizer(n_bins=n_bins, encode='ordinal', strategy=strategy)
# Melakukan fitting dan transformasi
# Reshape data_col agar sesuai dengan input yang diharapkan oleh scikit-learn (2D array)
labels_numeric = discretizer.fit_transform(data_col.values.reshape(-1, 1)).flatten().astype(int)
# Membuat seri kategori huruf
kategori_series = pd.Series(labels_numeric).map(label_map)
# Menghitung statistik min, max, centroid per cluster/bin
df_temp = pd.DataFrame({
'nilai_asli': data_col,
'cluster_id': labels_numeric # Menggunakan ID cluster/bin numerik
})
# Hitung statistik
stat = df_temp.groupby('cluster_id')['nilai_asli'].agg(['min', 'max', 'mean'])
stat = stat.rename(columns={'mean': 'centroid'}) # Mengganti nama 'mean' menjadi 'centroid'
# Tambahkan kolom kategori ke statistik
stat['kategori'] = stat.index.map(label_map)
stat = stat.set_index('kategori')
return kategori_series, stat
# --- 3. Sepal Width (3 kategori) ---
map_sepal_width = {0: 'A', 1: 'B', 2: 'C'}
# Menggunakan 'kmeans' strategy untuk mendekati perilaku asli
df_kategori['sepal_width'], stat_sepal_width = discretize_kbins_stat(
df_numerik['sepal_width'], 3, map_sepal_width, strategy='kmeans'
)
# --- 4. Petal Length (4 kategori) ---
map_petal_length = {0: 'A', 1: 'B', 2: 'C', 3: 'D'}
df_kategori['petal_length'], stat_petal_length = discretize_kbins_stat(
df_numerik['petal_length'], 4, map_petal_length, strategy='kmeans'
)
# --- 5. Petal Width (3 kategori) ---
map_petal_width = {0: 'A', 1: 'B', 2: 'C'}
df_kategori['petal_width'], stat_petal_width = discretize_kbins_stat(
df_numerik['petal_width'], 3, map_petal_width, strategy='kmeans'
)
df_kategori.to_excel("data_iris_kategori_lengkap.xlsx", index=False)
print("Hasil kategori disimpan ke 'data_iris_kategori_lengkap.xlsx'")
# --- 7. Gabungkan semua statistik dan tampilkan ---
print("\n=== Statistik Sepal Width (3 kategori) ===")
print(stat_sepal_width[['min', 'max', 'centroid']])
print("\n=== Statistik Petal Length (4 kategori) ===")
print(stat_petal_length[['min', 'max', 'centroid']])
print("\n=== Statistik Petal Width (3 kategori) ===")
print(stat_petal_width[['min', 'max', 'centroid']])
Hasil kategori disimpan ke 'data_iris_kategori_lengkap.xlsx'
=== Statistik Sepal Width (3 kategori) ===
min max centroid
kategori
A 2.0 2.8 2.585106
B 2.9 3.4 3.118987
C 3.5 4.4 3.758333
=== Statistik Petal Length (4 kategori) ===
min max centroid
kategori
A 1.0 1.9 1.464000
B 3.0 4.3 3.884000
C 4.4 5.3 4.808889
D 5.4 6.9 5.903333
=== Statistik Petal Width (3 kategori) ===
min max centroid
kategori
A 0.1 0.6 0.244000
B 1.0 1.7 1.337037
C 1.8 2.5 2.073913
Menampilkan semua data hasil diskritisasi setiap fitur#
import pandas as pd
# Baca file Excel yang sudah berisi kategori
df_kategori = pd.read_excel("data_iris_kategori_lengkap.xlsx")
# Tampilkan semua baris
pd.set_option('display.max_rows', None)
print(df_kategori)
id sepal_length sepal_width petal_length petal_width
0 1 B C A A
1 2 B B A A
2 3 B B A A
3 4 B B A A
4 5 B C A A
5 6 A C A A
6 7 B B A A
7 8 B B A A
8 9 B B A A
9 10 B B A A
10 11 A C A A
11 12 B B A A
12 13 B B A A
13 14 B B A A
14 15 A C A A
15 16 A C A A
16 17 A C A A
17 18 B C A A
18 19 A C A A
19 20 B C A A
20 21 A B A A
21 22 B C A A
22 23 B C A A
23 24 B B A A
24 25 B B A A
25 26 B B A A
26 27 B B A A
27 28 B C A A
28 29 B B A A
29 30 B B A A
30 31 B B A A
31 32 A B A A
32 33 B C A A
33 34 A C A A
34 35 B B A A
35 36 B B A A
36 37 A C A A
37 38 B B A A
38 39 B B A A
39 40 B B A A
40 41 B C A A
41 42 B A A A
42 43 B B A A
43 44 B C A A
44 45 B C A A
45 46 B B A A
46 47 B C A A
47 48 B B A A
48 49 B C A A
49 50 B B A A
50 51 C B C B
51 52 C B C B
52 53 C B C B
53 54 A A B B
54 55 C A C B
55 56 A A C B
56 57 C B C B
57 58 B A B B
58 59 C B C B
59 60 B A B B
60 61 B A B B
61 62 A B B B
62 63 A A B B
63 64 A B C B
64 65 A B B B
65 66 C B C B
66 67 A B C B
67 68 A A B B
68 69 C A C B
69 70 A A B B
70 71 A B C C
71 72 A A B B
72 73 C A C B
73 74 A A C B
74 75 C B B B
75 76 C B C B
76 77 C A C B
77 78 C B C B
78 79 A B C B
79 80 A A B B
80 81 A A B B
81 82 A A B B
82 83 A A B B
83 84 A A C B
84 85 A B C B
85 86 A B C B
86 87 C B C B
87 88 C A C B
88 89 A B B B
89 90 A A B B
90 91 A A C B
91 92 A B C B
92 93 A A B B
93 94 B A B B
94 95 A A B B
95 96 A B B B
96 97 A B B B
97 98 C B B B
98 99 B A B B
99 100 A A B B
100 101 C B D C
101 102 A A C C
102 103 D B D C
103 104 C B D C
104 105 C B D C
105 106 D B D C
106 107 B A C B
107 108 D B D C
108 109 C A D C
109 110 D C D C
110 111 C B C C
111 112 C A C C
112 113 C B D C
113 114 A A C C
114 115 A A C C
115 116 C B C C
116 117 C B D C
117 118 D C D C
118 119 D A D C
119 120 A A C B
120 121 C B D C
121 122 A A C C
122 123 D A D C
123 124 C A C C
124 125 C B D C
125 126 D B D C
126 127 C A C C
127 128 A B C C
128 129 C A D C
129 130 D B D B
130 131 D A D C
131 132 D C D C
132 133 C A D C
133 134 C A C B
134 135 A A D B
135 136 D B D C
136 137 C B D C
137 138 C B D C
138 139 A B C C
139 140 C B D C
140 141 C B D C
141 142 C B C C
142 143 A A C C
143 144 C B D C
144 145 C B D C
145 146 C B C C
146 147 C A C C
147 148 C B C C
148 149 C B D C
149 150 A B C C
Klasifikasi Naive Bayes Data Diskrit#
from sklearn.preprocessing import LabelEncoder
from sklearn.naive_bayes import CategoricalNB
from sklearn.metrics import classification_report, accuracy_score
import pandas as pd
# Load both files
data_iris = pd.read_excel("data_iris_kategori_lengkap.xlsx")
class_asli = pd.read_excel("class.xlsx")
# Gabungkan data kategorikal dengan kelas asli berdasarkan 'id'
data_gabungan = pd.merge(data_iris, class_asli[['id', 'class']], on='id')
# Encode fitur kategorikal (A, B, dst.) ke numerik
fitur_kategori = ['petal_length', 'petal_width', 'sepal_length', 'sepal_width']
for kolom in fitur_kategori:
encoder = LabelEncoder()
data_gabungan[kolom] = encoder.fit_transform(data_gabungan[kolom])
# Encode label kelas
label_encoder = LabelEncoder()
y = label_encoder.fit_transform(data_gabungan['class'])
X = data_gabungan[fitur_kategori]
# Model Naive Bayes
model = CategoricalNB()
model.fit(X, y)
y_pred = model.predict(X)
# Buat DataFrame hasil prediksi vs kelas asli
hasil_prediksi = data_gabungan[['id']].copy()
hasil_prediksi['kelas_asli'] = label_encoder.inverse_transform(y)
hasil_prediksi['kelas_prediksi'] = label_encoder.inverse_transform(y_pred)
# Simpan ke Excel
output_path = "naive_bayes.xlsx"
hasil_prediksi.to_excel(output_path, index=False)
# Evaluasi hasil prediksi
akurasi = accuracy_score(y, y_pred)
laporan_klasifikasi = classification_report(y, y_pred, target_names=label_encoder.classes_)
# Tampilkan hasil
print("\n=== Hasil Prediksi Kelas ===")
print(hasil_prediksi)
print("\n=== Akurasi ===")
print(f"Akurasi: {akurasi:.2f}")
print("\n=== Laporan Klasifikasi ===")
print(laporan_klasifikasi)
=== Hasil Prediksi Kelas ===
id kelas_asli kelas_prediksi
0 1 Iris-setosa Iris-setosa
1 2 Iris-setosa Iris-setosa
2 3 Iris-setosa Iris-setosa
3 4 Iris-setosa Iris-setosa
4 5 Iris-setosa Iris-setosa
5 6 Iris-setosa Iris-setosa
6 7 Iris-setosa Iris-setosa
7 8 Iris-setosa Iris-setosa
8 9 Iris-setosa Iris-setosa
9 10 Iris-setosa Iris-setosa
10 11 Iris-setosa Iris-setosa
11 12 Iris-setosa Iris-setosa
12 13 Iris-setosa Iris-setosa
13 14 Iris-setosa Iris-setosa
14 15 Iris-setosa Iris-setosa
15 16 Iris-setosa Iris-setosa
16 17 Iris-setosa Iris-setosa
17 18 Iris-setosa Iris-setosa
18 19 Iris-setosa Iris-setosa
19 20 Iris-setosa Iris-setosa
20 21 Iris-setosa Iris-setosa
21 22 Iris-setosa Iris-setosa
22 23 Iris-setosa Iris-setosa
23 24 Iris-setosa Iris-setosa
24 25 Iris-setosa Iris-setosa
25 26 Iris-setosa Iris-setosa
26 27 Iris-setosa Iris-setosa
27 28 Iris-setosa Iris-setosa
28 29 Iris-setosa Iris-setosa
29 30 Iris-setosa Iris-setosa
30 31 Iris-setosa Iris-setosa
31 32 Iris-setosa Iris-setosa
32 33 Iris-setosa Iris-setosa
33 34 Iris-setosa Iris-setosa
34 35 Iris-setosa Iris-setosa
35 36 Iris-setosa Iris-setosa
36 37 Iris-setosa Iris-setosa
37 38 Iris-setosa Iris-setosa
38 39 Iris-setosa Iris-setosa
39 40 Iris-setosa Iris-setosa
40 41 Iris-setosa Iris-setosa
41 42 Iris-setosa Iris-setosa
42 43 Iris-setosa Iris-setosa
43 44 Iris-setosa Iris-setosa
44 45 Iris-setosa Iris-setosa
45 46 Iris-setosa Iris-setosa
46 47 Iris-setosa Iris-setosa
47 48 Iris-setosa Iris-setosa
48 49 Iris-setosa Iris-setosa
49 50 Iris-setosa Iris-setosa
50 51 Iris-versicolor Iris-versicolor
51 52 Iris-versicolor Iris-versicolor
52 53 Iris-versicolor Iris-versicolor
53 54 Iris-versicolor Iris-versicolor
54 55 Iris-versicolor Iris-versicolor
55 56 Iris-versicolor Iris-versicolor
56 57 Iris-versicolor Iris-versicolor
57 58 Iris-versicolor Iris-versicolor
58 59 Iris-versicolor Iris-versicolor
59 60 Iris-versicolor Iris-versicolor
60 61 Iris-versicolor Iris-versicolor
61 62 Iris-versicolor Iris-versicolor
62 63 Iris-versicolor Iris-versicolor
63 64 Iris-versicolor Iris-versicolor
64 65 Iris-versicolor Iris-versicolor
65 66 Iris-versicolor Iris-versicolor
66 67 Iris-versicolor Iris-versicolor
67 68 Iris-versicolor Iris-versicolor
68 69 Iris-versicolor Iris-versicolor
69 70 Iris-versicolor Iris-versicolor
70 71 Iris-versicolor Iris-virginica
71 72 Iris-versicolor Iris-versicolor
72 73 Iris-versicolor Iris-versicolor
73 74 Iris-versicolor Iris-versicolor
74 75 Iris-versicolor Iris-versicolor
75 76 Iris-versicolor Iris-versicolor
76 77 Iris-versicolor Iris-versicolor
77 78 Iris-versicolor Iris-versicolor
78 79 Iris-versicolor Iris-versicolor
79 80 Iris-versicolor Iris-versicolor
80 81 Iris-versicolor Iris-versicolor
81 82 Iris-versicolor Iris-versicolor
82 83 Iris-versicolor Iris-versicolor
83 84 Iris-versicolor Iris-versicolor
84 85 Iris-versicolor Iris-versicolor
85 86 Iris-versicolor Iris-versicolor
86 87 Iris-versicolor Iris-versicolor
87 88 Iris-versicolor Iris-versicolor
88 89 Iris-versicolor Iris-versicolor
89 90 Iris-versicolor Iris-versicolor
90 91 Iris-versicolor Iris-versicolor
91 92 Iris-versicolor Iris-versicolor
92 93 Iris-versicolor Iris-versicolor
93 94 Iris-versicolor Iris-versicolor
94 95 Iris-versicolor Iris-versicolor
95 96 Iris-versicolor Iris-versicolor
96 97 Iris-versicolor Iris-versicolor
97 98 Iris-versicolor Iris-versicolor
98 99 Iris-versicolor Iris-versicolor
99 100 Iris-versicolor Iris-versicolor
100 101 Iris-virginica Iris-virginica
101 102 Iris-virginica Iris-virginica
102 103 Iris-virginica Iris-virginica
103 104 Iris-virginica Iris-virginica
104 105 Iris-virginica Iris-virginica
105 106 Iris-virginica Iris-virginica
106 107 Iris-virginica Iris-versicolor
107 108 Iris-virginica Iris-virginica
108 109 Iris-virginica Iris-virginica
109 110 Iris-virginica Iris-virginica
110 111 Iris-virginica Iris-virginica
111 112 Iris-virginica Iris-virginica
112 113 Iris-virginica Iris-virginica
113 114 Iris-virginica Iris-virginica
114 115 Iris-virginica Iris-virginica
115 116 Iris-virginica Iris-virginica
116 117 Iris-virginica Iris-virginica
117 118 Iris-virginica Iris-virginica
118 119 Iris-virginica Iris-virginica
119 120 Iris-virginica Iris-versicolor
120 121 Iris-virginica Iris-virginica
121 122 Iris-virginica Iris-virginica
122 123 Iris-virginica Iris-virginica
123 124 Iris-virginica Iris-virginica
124 125 Iris-virginica Iris-virginica
125 126 Iris-virginica Iris-virginica
126 127 Iris-virginica Iris-virginica
127 128 Iris-virginica Iris-virginica
128 129 Iris-virginica Iris-virginica
129 130 Iris-virginica Iris-virginica
130 131 Iris-virginica Iris-virginica
131 132 Iris-virginica Iris-virginica
132 133 Iris-virginica Iris-virginica
133 134 Iris-virginica Iris-versicolor
134 135 Iris-virginica Iris-versicolor
135 136 Iris-virginica Iris-virginica
136 137 Iris-virginica Iris-virginica
137 138 Iris-virginica Iris-virginica
138 139 Iris-virginica Iris-virginica
139 140 Iris-virginica Iris-virginica
140 141 Iris-virginica Iris-virginica
141 142 Iris-virginica Iris-virginica
142 143 Iris-virginica Iris-virginica
143 144 Iris-virginica Iris-virginica
144 145 Iris-virginica Iris-virginica
145 146 Iris-virginica Iris-virginica
146 147 Iris-virginica Iris-virginica
147 148 Iris-virginica Iris-virginica
148 149 Iris-virginica Iris-virginica
149 150 Iris-virginica Iris-virginica
=== Akurasi ===
Akurasi: 0.97
=== Laporan Klasifikasi ===
precision recall f1-score support
Iris-setosa 1.00 1.00 1.00 50
Iris-versicolor 0.92 0.98 0.95 50
Iris-virginica 0.98 0.92 0.95 50
accuracy 0.97 150
macro avg 0.97 0.97 0.97 150
weighted avg 0.97 0.97 0.97 150
Klasifikasi Naive Bayes Data Tanpa Diskritisasi#
import pandas as pd
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# Memuat dataset
try:
df_iris = pd.read_excel('data_iris.xlsx')
df_class = pd.read_excel('class.xlsx')
except FileNotFoundError as e:
print(f"Error loading file: {e}. Pastikan file berada di direktori yang sama.")
exit()
# Menyiapkan data
# Fitur (X) diambil dari df_iris, mengecualikan kolom 'id'
X = df_iris.drop('id', axis=1)
# Label sebenarnya (y_true) diambil dari kolom 'class' di df_class
y_true = df_class['class']
# Memastikan jumlah baris di X dan y_true cocok
if X.shape[0] != y_true.shape[0]:
print("Error: Jumlah baris pada fitur dan variabel target sebenarnya tidak cocok.")
exit()
# Menginisialisasi model Gaussian Naive Bayes
model = GaussianNB()
# Melatih model menggunakan fitur dari df_iris dan label sebenarnya dari df_class
model.fit(X, y_true)
# Membuat prediksi pada fitur yang sama
y_pred = model.predict(X)
# Membandingkan prediksi dengan kelas aktual (y_true)
comparison_df = pd.DataFrame({'True Class': y_true, 'Predicted Class': y_pred})
print("\nPerbandingan Kelas Aktual dan Kelas Prediksi:")
print(comparison_df.head())
# Mengevaluasi model
accuracy = accuracy_score(y_true, y_pred)
conf_matrix = confusion_matrix(y_true, y_pred)
class_report = classification_report(y_true, y_pred)
print(f"\nAkurasi: {accuracy:.4f}")
print("\nMatriks Konfusi:")
print(conf_matrix)
print("\nLaporan Klasifikasi:")
print(class_report)
comparison_df.to_excel('naive_bayes_classification_results.xlsx', index=False)
Perbandingan Kelas Aktual dan Kelas Prediksi:
True Class Predicted Class
0 Iris-setosa Iris-setosa
1 Iris-setosa Iris-setosa
2 Iris-setosa Iris-setosa
3 Iris-setosa Iris-setosa
4 Iris-setosa Iris-setosa
Akurasi: 0.9600
Matriks Konfusi:
[[50 0 0]
[ 0 47 3]
[ 0 3 47]]
Laporan Klasifikasi:
precision recall f1-score support
Iris-setosa 1.00 1.00 1.00 50
Iris-versicolor 0.94 0.94 0.94 50
Iris-virginica 0.94 0.94 0.94 50
accuracy 0.96 150
macro avg 0.96 0.96 0.96 150
weighted avg 0.96 0.96 0.96 150
Klasifikasi Decision Tree Data Diskrit#
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split # Meskipun tidak digunakan untuk split di sini, ini adalah praktik baik
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.preprocessing import OneHotEncoder
# --- 1. Memuat data yang sudah didiskritisasi ---
try:
df_discretized = pd.read_excel('data_iris_kategori_lengkap.xlsx')
df_true_class = pd.read_excel('class.xlsx')
except FileNotFoundError as e:
print(f"Error loading file: {e}. Pastikan file berada di direktori yang sama.")
exit()
# --- 2. Menyiapkan data ---
categorical_features = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
X_categorical = df_discretized[categorical_features]
# Variabel target (y) dari file kelas aktual
y = df_true_class['class']
encoder = OneHotEncoder(handle_unknown='ignore', sparse_output=False)
X_encoded = encoder.fit_transform(X_categorical)
feature_names = encoder.get_feature_names_out(categorical_features)
X_df_encoded = pd.DataFrame(X_encoded, columns=feature_names)
if X_df_encoded.shape[0] != y.shape[0]:
print("Error: Jumlah baris pada fitur yang di-encode dan variabel target tidak cocok.")
exit()
# --- 3. Melatih pengklasifikasi Decision Tree ---
# random_state digunakan untuk reproduksibilitas hasil
model = DecisionTreeClassifier(random_state=42)
# Melatih model
model.fit(X_df_encoded, y)
# --- 4. Membuat prediksi ---
y_pred = model.predict(X_df_encoded)
# --- 5. Mengevaluasi model ---
accuracy = accuracy_score(y, y_pred)
conf_matrix = confusion_matrix(y, y_pred)
class_report = classification_report(y, y_pred)
print(f"\nAkurasi Model Decision Tree (Data Diskritisasi): {accuracy:.4f}")
print("\nMatriks Konfusi:")
print(conf_matrix)
print("\nLaporan Klasifikasi:")
print(class_report)
# Secara opsional, simpan perbandingan kelas aktual dan prediksi ke file CSV
comparison_df_dt = pd.DataFrame({'True Class': y, 'Predicted Class': y_pred})
comparison_df_dt.to_excel('decision_tree_discretized_classification_results.xlsx', index=False)
Akurasi Model Decision Tree (Data Diskritisasi): 0.9800
Matriks Konfusi:
[[50 0 0]
[ 0 49 1]
[ 0 2 48]]
Laporan Klasifikasi:
precision recall f1-score support
Iris-setosa 1.00 1.00 1.00 50
Iris-versicolor 0.96 0.98 0.97 50
Iris-virginica 0.98 0.96 0.97 50
accuracy 0.98 150
macro avg 0.98 0.98 0.98 150
weighted avg 0.98 0.98 0.98 150
import pandas as pd
df= pd.read_excel('decision_tree_discretized_classification_results.xlsx')
# Tampilkan semua baris
pd.set_option('display.max_rows', None)
print(df)
True Class Predicted Class
0 Iris-setosa Iris-setosa
1 Iris-setosa Iris-setosa
2 Iris-setosa Iris-setosa
3 Iris-setosa Iris-setosa
4 Iris-setosa Iris-setosa
5 Iris-setosa Iris-setosa
6 Iris-setosa Iris-setosa
7 Iris-setosa Iris-setosa
8 Iris-setosa Iris-setosa
9 Iris-setosa Iris-setosa
10 Iris-setosa Iris-setosa
11 Iris-setosa Iris-setosa
12 Iris-setosa Iris-setosa
13 Iris-setosa Iris-setosa
14 Iris-setosa Iris-setosa
15 Iris-setosa Iris-setosa
16 Iris-setosa Iris-setosa
17 Iris-setosa Iris-setosa
18 Iris-setosa Iris-setosa
19 Iris-setosa Iris-setosa
20 Iris-setosa Iris-setosa
21 Iris-setosa Iris-setosa
22 Iris-setosa Iris-setosa
23 Iris-setosa Iris-setosa
24 Iris-setosa Iris-setosa
25 Iris-setosa Iris-setosa
26 Iris-setosa Iris-setosa
27 Iris-setosa Iris-setosa
28 Iris-setosa Iris-setosa
29 Iris-setosa Iris-setosa
30 Iris-setosa Iris-setosa
31 Iris-setosa Iris-setosa
32 Iris-setosa Iris-setosa
33 Iris-setosa Iris-setosa
34 Iris-setosa Iris-setosa
35 Iris-setosa Iris-setosa
36 Iris-setosa Iris-setosa
37 Iris-setosa Iris-setosa
38 Iris-setosa Iris-setosa
39 Iris-setosa Iris-setosa
40 Iris-setosa Iris-setosa
41 Iris-setosa Iris-setosa
42 Iris-setosa Iris-setosa
43 Iris-setosa Iris-setosa
44 Iris-setosa Iris-setosa
45 Iris-setosa Iris-setosa
46 Iris-setosa Iris-setosa
47 Iris-setosa Iris-setosa
48 Iris-setosa Iris-setosa
49 Iris-setosa Iris-setosa
50 Iris-versicolor Iris-versicolor
51 Iris-versicolor Iris-versicolor
52 Iris-versicolor Iris-versicolor
53 Iris-versicolor Iris-versicolor
54 Iris-versicolor Iris-versicolor
55 Iris-versicolor Iris-versicolor
56 Iris-versicolor Iris-versicolor
57 Iris-versicolor Iris-versicolor
58 Iris-versicolor Iris-versicolor
59 Iris-versicolor Iris-versicolor
60 Iris-versicolor Iris-versicolor
61 Iris-versicolor Iris-versicolor
62 Iris-versicolor Iris-versicolor
63 Iris-versicolor Iris-versicolor
64 Iris-versicolor Iris-versicolor
65 Iris-versicolor Iris-versicolor
66 Iris-versicolor Iris-versicolor
67 Iris-versicolor Iris-versicolor
68 Iris-versicolor Iris-versicolor
69 Iris-versicolor Iris-versicolor
70 Iris-versicolor Iris-virginica
71 Iris-versicolor Iris-versicolor
72 Iris-versicolor Iris-versicolor
73 Iris-versicolor Iris-versicolor
74 Iris-versicolor Iris-versicolor
75 Iris-versicolor Iris-versicolor
76 Iris-versicolor Iris-versicolor
77 Iris-versicolor Iris-versicolor
78 Iris-versicolor Iris-versicolor
79 Iris-versicolor Iris-versicolor
80 Iris-versicolor Iris-versicolor
81 Iris-versicolor Iris-versicolor
82 Iris-versicolor Iris-versicolor
83 Iris-versicolor Iris-versicolor
84 Iris-versicolor Iris-versicolor
85 Iris-versicolor Iris-versicolor
86 Iris-versicolor Iris-versicolor
87 Iris-versicolor Iris-versicolor
88 Iris-versicolor Iris-versicolor
89 Iris-versicolor Iris-versicolor
90 Iris-versicolor Iris-versicolor
91 Iris-versicolor Iris-versicolor
92 Iris-versicolor Iris-versicolor
93 Iris-versicolor Iris-versicolor
94 Iris-versicolor Iris-versicolor
95 Iris-versicolor Iris-versicolor
96 Iris-versicolor Iris-versicolor
97 Iris-versicolor Iris-versicolor
98 Iris-versicolor Iris-versicolor
99 Iris-versicolor Iris-versicolor
100 Iris-virginica Iris-virginica
101 Iris-virginica Iris-virginica
102 Iris-virginica Iris-virginica
103 Iris-virginica Iris-virginica
104 Iris-virginica Iris-virginica
105 Iris-virginica Iris-virginica
106 Iris-virginica Iris-virginica
107 Iris-virginica Iris-virginica
108 Iris-virginica Iris-virginica
109 Iris-virginica Iris-virginica
110 Iris-virginica Iris-virginica
111 Iris-virginica Iris-virginica
112 Iris-virginica Iris-virginica
113 Iris-virginica Iris-virginica
114 Iris-virginica Iris-virginica
115 Iris-virginica Iris-virginica
116 Iris-virginica Iris-virginica
117 Iris-virginica Iris-virginica
118 Iris-virginica Iris-virginica
119 Iris-virginica Iris-versicolor
120 Iris-virginica Iris-virginica
121 Iris-virginica Iris-virginica
122 Iris-virginica Iris-virginica
123 Iris-virginica Iris-virginica
124 Iris-virginica Iris-virginica
125 Iris-virginica Iris-virginica
126 Iris-virginica Iris-virginica
127 Iris-virginica Iris-virginica
128 Iris-virginica Iris-virginica
129 Iris-virginica Iris-virginica
130 Iris-virginica Iris-virginica
131 Iris-virginica Iris-virginica
132 Iris-virginica Iris-virginica
133 Iris-virginica Iris-versicolor
134 Iris-virginica Iris-virginica
135 Iris-virginica Iris-virginica
136 Iris-virginica Iris-virginica
137 Iris-virginica Iris-virginica
138 Iris-virginica Iris-virginica
139 Iris-virginica Iris-virginica
140 Iris-virginica Iris-virginica
141 Iris-virginica Iris-virginica
142 Iris-virginica Iris-virginica
143 Iris-virginica Iris-virginica
144 Iris-virginica Iris-virginica
145 Iris-virginica Iris-virginica
146 Iris-virginica Iris-virginica
147 Iris-virginica Iris-virginica
148 Iris-virginica Iris-virginica
149 Iris-virginica Iris-virginica
Klasifikasi Decision Tree Data Tanpa Diskritisasi#
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split # Termasuk untuk praktik baik
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# --- 1. Memuat data Iris asli ---
try:
df_iris_original = pd.read_excel('data_iris.xlsx')
df_true_class = pd.read_excel('class.xlsx')
except FileNotFoundError as e:
print(f"Error loading file: {e}. Pastikan file berada di direktori yang sama.")
exit()
# --- 2. Menyiapkan data ---
# Fitur (X) dari data Iris asli, mengecualikan kolom 'id'
features = ['petal_length', 'petal_width', 'sepal_length', 'sepal_width']
X = df_iris_original[features]
# Variabel target (y) dari file kelas aktual
y = df_true_class['class']
# Memastikan jumlah sampel di X dan y cocok
if X.shape[0] != y.shape[0]:
print("Error: Jumlah baris pada fitur dan variabel target tidak cocok.")
exit()
# Untuk tujuan demonstrasi ini, kita akan melatih dan mengevaluasi pada seluruh dataset.
# Dalam skenario dunia nyata, sangat disarankan untuk menggunakan train_test_split
# untuk membagi data menjadi set pelatihan dan pengujian guna mendapatkan evaluasi model yang lebih realistis.
# Contoh penggunaan train_test_split:
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# --- 3. Melatih pengklasifikasi Decision Tree ---
# random_state digunakan untuk reproduksibilitas hasil
model = DecisionTreeClassifier(random_state=42)
# Melatih model
model.fit(X, y)
# --- 4. Membuat prediksi ---
y_pred = model.predict(X)
# --- 5. Mengevaluasi model ---
accuracy = accuracy_score(y, y_pred)
conf_matrix = confusion_matrix(y, y_pred)
class_report = classification_report(y, y_pred)
print(f"\nAkurasi Model Decision Tree (Data Iris Asli): {accuracy:.4f}")
print("\nMatriks Konfusi:")
print(conf_matrix)
print("\nLaporan Klasifikasi:")
print(class_report)
comparison_df_dt_original = pd.DataFrame({'True Class': y, 'Predicted Class': y_pred})
comparison_df_dt_original.to_excel('decision_tree_original_iris_classification_results.xlsx', index=False)
Akurasi Model Decision Tree (Data Iris Asli): 1.0000
Matriks Konfusi:
[[50 0 0]
[ 0 50 0]
[ 0 0 50]]
Laporan Klasifikasi:
precision recall f1-score support
Iris-setosa 1.00 1.00 1.00 50
Iris-versicolor 1.00 1.00 1.00 50
Iris-virginica 1.00 1.00 1.00 50
accuracy 1.00 150
macro avg 1.00 1.00 1.00 150
weighted avg 1.00 1.00 1.00 150
import pandas as pd
df= pd.read_excel('decision_tree_original_iris_classification_results.xlsx')
# Tampilkan semua baris
pd.set_option('display.max_rows', None)
print(df)
True Class Predicted Class
0 Iris-setosa Iris-setosa
1 Iris-setosa Iris-setosa
2 Iris-setosa Iris-setosa
3 Iris-setosa Iris-setosa
4 Iris-setosa Iris-setosa
5 Iris-setosa Iris-setosa
6 Iris-setosa Iris-setosa
7 Iris-setosa Iris-setosa
8 Iris-setosa Iris-setosa
9 Iris-setosa Iris-setosa
10 Iris-setosa Iris-setosa
11 Iris-setosa Iris-setosa
12 Iris-setosa Iris-setosa
13 Iris-setosa Iris-setosa
14 Iris-setosa Iris-setosa
15 Iris-setosa Iris-setosa
16 Iris-setosa Iris-setosa
17 Iris-setosa Iris-setosa
18 Iris-setosa Iris-setosa
19 Iris-setosa Iris-setosa
20 Iris-setosa Iris-setosa
21 Iris-setosa Iris-setosa
22 Iris-setosa Iris-setosa
23 Iris-setosa Iris-setosa
24 Iris-setosa Iris-setosa
25 Iris-setosa Iris-setosa
26 Iris-setosa Iris-setosa
27 Iris-setosa Iris-setosa
28 Iris-setosa Iris-setosa
29 Iris-setosa Iris-setosa
30 Iris-setosa Iris-setosa
31 Iris-setosa Iris-setosa
32 Iris-setosa Iris-setosa
33 Iris-setosa Iris-setosa
34 Iris-setosa Iris-setosa
35 Iris-setosa Iris-setosa
36 Iris-setosa Iris-setosa
37 Iris-setosa Iris-setosa
38 Iris-setosa Iris-setosa
39 Iris-setosa Iris-setosa
40 Iris-setosa Iris-setosa
41 Iris-setosa Iris-setosa
42 Iris-setosa Iris-setosa
43 Iris-setosa Iris-setosa
44 Iris-setosa Iris-setosa
45 Iris-setosa Iris-setosa
46 Iris-setosa Iris-setosa
47 Iris-setosa Iris-setosa
48 Iris-setosa Iris-setosa
49 Iris-setosa Iris-setosa
50 Iris-versicolor Iris-versicolor
51 Iris-versicolor Iris-versicolor
52 Iris-versicolor Iris-versicolor
53 Iris-versicolor Iris-versicolor
54 Iris-versicolor Iris-versicolor
55 Iris-versicolor Iris-versicolor
56 Iris-versicolor Iris-versicolor
57 Iris-versicolor Iris-versicolor
58 Iris-versicolor Iris-versicolor
59 Iris-versicolor Iris-versicolor
60 Iris-versicolor Iris-versicolor
61 Iris-versicolor Iris-versicolor
62 Iris-versicolor Iris-versicolor
63 Iris-versicolor Iris-versicolor
64 Iris-versicolor Iris-versicolor
65 Iris-versicolor Iris-versicolor
66 Iris-versicolor Iris-versicolor
67 Iris-versicolor Iris-versicolor
68 Iris-versicolor Iris-versicolor
69 Iris-versicolor Iris-versicolor
70 Iris-versicolor Iris-versicolor
71 Iris-versicolor Iris-versicolor
72 Iris-versicolor Iris-versicolor
73 Iris-versicolor Iris-versicolor
74 Iris-versicolor Iris-versicolor
75 Iris-versicolor Iris-versicolor
76 Iris-versicolor Iris-versicolor
77 Iris-versicolor Iris-versicolor
78 Iris-versicolor Iris-versicolor
79 Iris-versicolor Iris-versicolor
80 Iris-versicolor Iris-versicolor
81 Iris-versicolor Iris-versicolor
82 Iris-versicolor Iris-versicolor
83 Iris-versicolor Iris-versicolor
84 Iris-versicolor Iris-versicolor
85 Iris-versicolor Iris-versicolor
86 Iris-versicolor Iris-versicolor
87 Iris-versicolor Iris-versicolor
88 Iris-versicolor Iris-versicolor
89 Iris-versicolor Iris-versicolor
90 Iris-versicolor Iris-versicolor
91 Iris-versicolor Iris-versicolor
92 Iris-versicolor Iris-versicolor
93 Iris-versicolor Iris-versicolor
94 Iris-versicolor Iris-versicolor
95 Iris-versicolor Iris-versicolor
96 Iris-versicolor Iris-versicolor
97 Iris-versicolor Iris-versicolor
98 Iris-versicolor Iris-versicolor
99 Iris-versicolor Iris-versicolor
100 Iris-virginica Iris-virginica
101 Iris-virginica Iris-virginica
102 Iris-virginica Iris-virginica
103 Iris-virginica Iris-virginica
104 Iris-virginica Iris-virginica
105 Iris-virginica Iris-virginica
106 Iris-virginica Iris-virginica
107 Iris-virginica Iris-virginica
108 Iris-virginica Iris-virginica
109 Iris-virginica Iris-virginica
110 Iris-virginica Iris-virginica
111 Iris-virginica Iris-virginica
112 Iris-virginica Iris-virginica
113 Iris-virginica Iris-virginica
114 Iris-virginica Iris-virginica
115 Iris-virginica Iris-virginica
116 Iris-virginica Iris-virginica
117 Iris-virginica Iris-virginica
118 Iris-virginica Iris-virginica
119 Iris-virginica Iris-virginica
120 Iris-virginica Iris-virginica
121 Iris-virginica Iris-virginica
122 Iris-virginica Iris-virginica
123 Iris-virginica Iris-virginica
124 Iris-virginica Iris-virginica
125 Iris-virginica Iris-virginica
126 Iris-virginica Iris-virginica
127 Iris-virginica Iris-virginica
128 Iris-virginica Iris-virginica
129 Iris-virginica Iris-virginica
130 Iris-virginica Iris-virginica
131 Iris-virginica Iris-virginica
132 Iris-virginica Iris-virginica
133 Iris-virginica Iris-virginica
134 Iris-virginica Iris-virginica
135 Iris-virginica Iris-virginica
136 Iris-virginica Iris-virginica
137 Iris-virginica Iris-virginica
138 Iris-virginica Iris-virginica
139 Iris-virginica Iris-virginica
140 Iris-virginica Iris-virginica
141 Iris-virginica Iris-virginica
142 Iris-virginica Iris-virginica
143 Iris-virginica Iris-virginica
144 Iris-virginica Iris-virginica
145 Iris-virginica Iris-virginica
146 Iris-virginica Iris-virginica
147 Iris-virginica Iris-virginica
148 Iris-virginica Iris-virginica
149 Iris-virginica Iris-virginica
Kesimpulan#
\( \begin{array}{lcccc} \hline \textbf{Model} & \textbf{Akurasi} \\ \hline \text{Naive Bayes (diskritisasi)} & 0.97 \\ \text{Naive Bayes (iris-asli)} & 0.96 \\ \text{Decision Tree (diskritisasi)} & 0.98 \\ \text{Decision Tree (iris-asli)} & 1.00 \\ \hline \end{array} \)
Secara keseluruhan, Decision Tree menunjukkan kinerja yang lebih unggul dibandingkan Naive Bayes pada kedua jenis data.Pengolahan data (diskritisasi) memberikan dampak yang berbeda pada kedua model:
Pada Naive Bayes, proses diskritisasi justru meningkatkan kinerja model dari 0.96 menjadi 0.97. Ini menunjukkan bahwa model Naive Bayes dalam kasus ini bekerja lebih baik dengan fitur-fitur yang bersifat kategorikal (hasil diskritisasi).
Pada Decision Tree, proses diskritisasi sedikit menurunkan kinerja model dari 1.00 menjadi 0.98. Hal ini menandakan bahwa Decision Tree mampu memanfaatkan informasi dari data numerik kontinu pada set data Iris asli secara lebih efektif untuk mencapai hasil yang sempurna.