Data dunia nyata jarang datang seragam, karena satu DataFrame dapat memuat kolom numerik seperti jam belajar dan kolom kategorikal seperti grup latihan pada tabel yang sama. ColumnTransformer menjawab kebutuhan itu dengan menerapkan transformer berbeda ke kolom berbeda dalam satu panggilan fit_transform. Topik ini membahas kontrak penyusunannya, opsi remainder, dan make_column_transformer sebagai pintasan penulisannya.
Kontrak nama, transformer, dan kolom#
ColumnTransformer disusun dari daftar bertingkat yang setiap entrinya berupa tiga unsur, yaitu nama, transformer, dan kolom. Nama berupa string bebas yang muncul pada nama fitur hasil transformasi, transformer berupa objek yang memahami fit dan transform, sedangkan kolom dinyatakan sebagai daftar nama kolom DataFrame. Susunan ini menjelaskan siapa yang memproses apa, sehingga kolom numerik dan kategorikal tidak pernah tertukar.
Kolom yang tidak disebut pada daftar mana pun mendapat perlakuan dari parameter remainder. Nilai bawaannya adalah "drop", yang berarti kolom tersebut dibuang tanpa suara. Nilai "passthrough" melewatkan kolom itu apa adanya, dan nilai lain boleh berupa transformer yang diterapkan ke seluruh kolom tersisa. Perilaku bawaan ini perlu diketahui, karena kolom yang diam-diam dibuang berarti informasi yang hilang tanpa peringatan.
Kolom pada entri juga tidak terbatas pada daftar nama string. Mask boolean, yaitu deretan benar-salah yang panjangnya sama dengan jumlah kolom, dapat digunakan sebagai pilihan kolom, dan fungsi make_column_selector dari modul yang sama memilih kolom berdasarkan tipe datanya, misalnya make_column_selector(dtype_include=object) untuk mengumpulkan semua kolom kategorikal sekaligus. Pemilihan berbasis tipe berguna ketika daftar kolom berubah-ubah, karena pemilihannya menyesuaikan diri tanpa menyunting daftar transformer.
Contoh berikut menyusun ColumnTransformer dengan StandardScaler untuk dua kolom numerik dan OneHotEncoder untuk satu kolom kategorikal pada data nilai latihan.
import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
df = pd.DataFrame({
"jam_belajar": [2.0, 4.0, 6.0, 8.0, 3.0],
"nilai_latihan": [60, 70, 85, 90, 65],
"grup": ["A", "B", "A", "C", "B"],
})
ct = ColumnTransformer(
transformers=[
("num", StandardScaler(), ["jam_belajar", "nilai_latihan"]),
("kat", OneHotEncoder(handle_unknown="ignore"), ["grup"]),
],
remainder="drop",
)
hasil = ct.fit_transform(df)
print("Hasil transformasi:")
print(np.round(hasil, 3))
print("Nama fitur hasil:")
print(ct.get_feature_names_out())Hasil transformasi:
[[-1.207 -1.209 1. 0. 0. ]
[-0.279 -0.346 0. 1. 0. ]
[ 0.65 0.95 1. 0. 0. ]
[ 1.578 1.382 0. 0. 1. ]
[-0.743 -0.777 0. 1. 0. ]]
Nama fitur hasil:
['num__jam_belajar' 'num__nilai_latihan' 'kat__grup_A' 'kat__grup_B'
'kat__grup_C']Matriks hasil terdiri atas lima kolom, yaitu dua kolom numerik yang skalanya sudah disetarakan diikuti tiga kolom biner hasil one-hot encoding. Nama fitur memuat awalan sesuai nama transformer yang diberikan, yaitu num__ dan kat__, sehingga setiap kolom hasil dapat dilacak kembali ke asalnya. Urutan kolom hasil menuruti urutan entri pada daftar transformers, yaitu keluaran num terlebih dahulu, kemudian keluaran kat, sehingga pemetaan kembali ke kolom tertentu tetap dapat dihitung. Awalan ini menjadi penunjuk yang berharga ketika hasil transformasi diserahkan ke model atau diperiksa secara manual.
remainder: nasib kolom yang tidak disebut#
Perilaku remainder mudah terlewat karena tidak menimbulkan error. Apabila terdapat kolom lain seperti usia peserta yang lupa disebut, kolom itu dibuang secara bawaan dan model kehilangan informasinya tanpa peringatan apa pun. Karena itu kebiasaan yang baik adalah memeriksa get_feature_names_out() setelah fit, lalu memastikan daftar kolom hasil memuat semua kolom yang dimaksudkan.
Nilai "passthrough" menjawab kebutuhan kolom yang ingin dilewatkan tanpa diubah, misalnya kolom numerik yang skalanya sudah tepat. Kolom yang tidak disebut tetap ikut muncul pada hasil, berbeda dari perilaku bawaan yang membuangnya. Contoh berikut menggunakan DataFrame yang sama dengan hanya satu transformer bernama num, lalu membiarkan dua kolom lainnya lewat apa adanya.
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
df = pd.DataFrame({
"jam_belajar": [2.0, 4.0, 6.0, 8.0, 3.0],
"nilai_latihan": [60, 70, 85, 90, 65],
"grup": ["A", "B", "A", "C", "B"],
})
ct = ColumnTransformer(
transformers=[("num", StandardScaler(), ["jam_belajar"])],
remainder="passthrough",
)
ct.fit(df)
print("Nama fitur dengan remainder passthrough:")
print(ct.get_feature_names_out())
print("Kolom passthrough dilewatkan tanpa diubah:")
print(ct.transform(df)[:, 1:])Nama fitur dengan remainder passthrough:
['num__jam_belajar' 'remainder__nilai_latihan' 'remainder__grup']
Kolom passthrough dilewatkan tanpa diubah:
[[60 'A']
[70 'B']
[85 'A']
[90 'C']
[65 'B']]Kolom yang tidak disebut muncul dengan awalan remainder__ dan isinya persis seperti sebelum transformasi, termasuk nilai_latihan yang tetap 60 sampai 90 dan grup yang tetap bertipe teks. Urutan kolom hasil mengikuti urutan transformer, lalu diikuti kolom remainder, sehingga posisi setiap kolom dapat dihitung. Apabila kolom tersisa justru perlu ditransformasi, nilai remainder dapat diisi dengan objek transformer lain tanpa menambah entri pada daftar utama. Meski begitu, semakin banyak pekerjaan yang berpindah ke remainder, semakin sulit membaca nama fitur hasilnya karena semua kolom tersisa dibundel dalam satu awalan yang sama. Entri eksplisit pada daftar utama tetap lebih mudah diaudit.
make_column_transformer sebagai gula sintaks#
make_column_transformer menghasilkan ColumnTransformer yang sama dengan penulisan yang lebih ringkas. Pemanggilnya menerima pasangan transformer dan kolom secara langsung, tanpa daftar nama, lalu menurunkan nama setiap transformer dari nama kelasnya secara otomatis. Fungsi ini dikenal sebagai gula sintaks (syntactic sugar), yaitu pintasan penulisan yang tidak menambah kemampuan baru melainkan mempersingkat kode.
import pandas as pd
from sklearn.compose import make_column_transformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
df = pd.DataFrame({
"jam_belajar": [2.0, 4.0, 6.0, 8.0, 3.0],
"nilai_latihan": [60, 70, 85, 90, 65],
"grup": ["A", "B", "A", "C", "B"],
})
ct = make_column_transformer(
(StandardScaler(), ["jam_belajar", "nilai_latihan"]),
(OneHotEncoder(handle_unknown="ignore"), ["grup"]),
)
hasil = ct.fit_transform(df)
print("Bentuk hasil:", hasil.shape)
print("Nama fitur hasil:")
print(ct.get_feature_names_out())Bentuk hasil: (5, 5)
Nama fitur hasil:
['standardscaler__jam_belajar' 'standardscaler__nilai_latihan'
'onehotencoder__grup_A' 'onehotencoder__grup_B' 'onehotencoder__grup_C']Bentuk dan isinya sama dengan versi eksplisit, hanya nama awalannya yang berbeda karena diturunkan dari nama kelas, yaitu standardscaler__ dan onehotencoder__. Nama eksplisit seperti num dan kat lebih mudah dibaca pada laporan maupun pesan error, sehingga bentuk eksplisit lebih disukai untuk proyek yang dijaga jangka panjang, sedangkan pintasan ini cocok untuk percobaan cepat.
Pilihan antara keduanya dapat ditentukan dari kebutuhan pembacaan. Bentuk eksplisit menuntut tiga unsur per entri, tetapi memberi kendali penuh atas nama yang muncul pada laporan, pesan error, dan hasil get_feature_names_out(). Bentuk pintasan mengurangi baris kode, sedangkan nama yang diturunkan otomatis dapat memanjang ketika transformer yang sama digunakan pada lebih dari satu entri.
ColumnTransformer pada topik ini disarangkan ke dalam Pipeline untuk menangani data campuran secara menyeluruh.
Ringkasan#
- ColumnTransformer menerima daftar entri nama, transformer, dan kolom, sehingga kolom numerik dan kategorikal diproses oleh transformer yang berbeda dalam satu panggilan.
- Kolom yang tidak disebut mengikuti
remainder, yang secara bawaan bernilai"drop"dan dapat diisi"passthrough"untuk melewatkan kolom tanpa diubah. - Nama fitur hasil memuat awalan nama transformer, misalnya
num__dankat__, sehingga asal setiap kolom dapat dilacak. - make_column_transformer menghasilkan objek yang sama dengan penulisan yang lebih ringkas, dengan nama yang diturunkan dari nama kelasnya.
Referensi#
- 6.1.4. Column Transformer — scikit-learn documentation — Mengulas ColumnTransformer, remainder, dan pemilihan kolom untuk data campuran.
- ColumnTransformer — scikit-learn documentation — Rujukan parameter transformers, remainder, dan get_feature_names_out.
- make_column_transformer — scikit-learn documentation — Rujukan pintasan penyusunan ColumnTransformer tanpa nama eksplisit.