Kursus
Serialisasi adalah hal yang bagus untuk diketahui. Ini memungkinkan Anda mempertahankan state data atau model Anda, sehingga tidak perlu memproses ulang atau melatih ulang dari awal.
Di sini, saya akan membahas modul Python Pickle yang terkenal. Pada akhirnya, Anda akan tahu cara men-serialisasi dan mendeserialisasi struktur data umum seperti list dan dictionary serta mengetahui cara memanfaatkan berbagai teknik optimasi kinerja.
Saya juga merekomendasikan kursus Designing Machine Learning Workflows in Python kami sebagai langkah berikutnya, di mana Anda dapat mempelajari cara menserealikan dan mengkontainerisasi model ML untuk produksi.
Pengenalan Serialisasi Objek
Apakah Anda lelah menjalankan ulang kode Python setiap kali perlu mengakses data frame, variabel, atau model machine learning yang sebelumnya dibuat?
Serialisasi objek mungkin solusi yang Anda cari.
Ini adalah proses menyimpan struktur data di memori sehingga Anda dapat memuat atau mentransmisikannya saat diperlukan tanpa kehilangan state saat ini.
Berikut diagram sederhana yang menjelaskan cara kerja serialisasi:

Gambar oleh Penulis
Di Python, kita bekerja dengan struktur data tingkat tinggi seperti list, tuple, dan set. Namun, saat ingin menyimpan objek-objek ini di memori, objek tersebut perlu diubah menjadi urutan byte yang dapat dipahami komputer. Proses ini disebut serialisasi.
Saat berikutnya kita ingin mengakses struktur data yang sama, urutan byte ini harus diubah kembali menjadi objek tingkat tinggi dalam proses yang dikenal sebagai deserialisasi.
Kita dapat menggunakan format seperti JSON, XML, HDF5, dan Pickle untuk serialisasi. Dalam tutorial ini, kita akan mempelajari pustaka Python Pickle untuk serialisasi. Kita akan membahas penggunaannya dan memahami kapan Anda sebaiknya memilih Pickle dibanding format serialisasi lainnya.
Terakhir, kita akan mempelajari cara menggunakan pustaka Pickle Python untuk men-serialisasi list, dictionary, data frame Pandas, model machine learning, dan lainnya.
Untuk dengan mudah menjalankan semua contoh kode dalam tutorial ini sendiri, Anda dapat membuat workbook DataLab secara gratis yang sudah terpasang Python dan berisi semua contoh kode. Untuk latihan lebih lanjut memuat file Python yang dipickle, lihat latihan praktis DataCamp ini.
Mengapa Kita Membutuhkan Serialisasi Objek?
Sebelum mulai dengan Python Pickle, mari pahami mengapa serialisasi objek begitu penting.
Anda mungkin bertanya-tanya mengapa kita tidak bisa menyimpan struktur data ke dalam file teks dan mengaksesnya lagi saat diperlukan alih-alih harus men-serialisasikannya.
Mari melalui contoh sederhana untuk memahami manfaat serialisasi.
Berikut dictionary bertingkat yang berisi informasi siswa seperti nama, usia, dan jenis kelamin:
students = {
'Student 1': {
'Name': "Alice", 'Age' :10, 'Grade':4,
},
'Student 2': {
'Name':'Bob', 'Age':11, 'Grade':5
},
'Student 3': {
'Name':'Elena', 'Age':14, 'Grade':8
}
}
Mari periksa tipe data objek “students”:
type(students)
dict
Sekarang setelah kita memastikan bahwa objek student adalah tipe dictionary, mari lanjut menuliskannya ke file teks tanpa serialisasi:
with open('student_info.txt','w') as data:
data.write(str(students))
Perhatikan bahwa karena kita hanya bisa menulis objek string ke file teks, kita telah mengonversi dictionary menjadi string menggunakan fungsi str(). Ini berarti state asli dictionary kita hilang.
Sekarang, mari baca dictionary itu, cetak, dan periksa lagi tipenya:
with open("student_info.txt", 'r') as f:
for students in f:
print(students)
type(students)
str
Dictionary bertingkat sekarang dicetak sebagai string, dan akan mengembalikan error saat kita mencoba mengakses key atau nilainya.
Di sinilah serialisasi berperan.
Saat menangani tipe data yang lebih kompleks seperti dictionary, data frame, dan list bertingkat, serialisasi memungkinkan pengguna mempertahankan state asli objek tanpa kehilangan informasi relevan.
Nanti dalam artikel ini, kita akan belajar menyimpan dictionary yang sama ke file menggunakan Pickle dan mendeserialisasikannya menggunakan pustaka tersebut. Anda dapat membaca lebih lanjut tentang dictionary comprehension di Python dalam tutorial terpisah.
Pengenalan Pickle di Python
Modul Pickle di Python adalah format populer yang digunakan untuk men-serialisasi dan mendeserialisasi tipe data. Format ini bersifat native untuk Python, artinya objek Pickle tidak dapat dimuat menggunakan bahasa pemrograman lain.
Pickle memiliki kelebihan dan kekurangan dibanding format serialisasi lainnya.
Kelebihan menggunakan Pickle untuk men-serialisasi objek
- Tidak seperti format serialisasi seperti JSON, yang tidak dapat menangani tuple dan objek datetime, Pickle dapat men-serialisasi hampir setiap tipe data built-in Python yang umum digunakan. Pickle juga mempertahankan state objek secara persis yang tidak dapat dilakukan JSON.
- Pickle juga pilihan yang baik saat menyimpan struktur rekursif karena hanya menulis objek satu kali.
- Pickle memungkinkan fleksibilitas saat mendeserialisasi objek. Anda dapat dengan mudah menyimpan variabel yang berbeda ke dalam file Pickle dan memuatnya kembali di sesi Python yang berbeda, memulihkan data Anda persis seperti semula tanpa perlu mengedit kode.
Kekurangan menggunakan Pickle
- Pickle tidak aman karena dapat mengeksekusi callable Python berbahaya untuk membangun objek. Saat mendeserialisasi objek, Pickle tidak bisa membedakan antara callable berbahaya dan tidak berbahaya. Karena itu, pengguna bisa saja mengeksekusi kode sewenang-wenang selama deserialisasi.
- Seperti disebutkan sebelumnya, Pickle adalah modul khusus Python, dan Anda mungkin kesulitan mendeserialisasi objek yang dipickle saat menggunakan bahasa lain.
- Menurut berbagai benchmark, Pickle tampak lebih lambat dan menghasilkan nilai hasil serialisasi yang lebih besar dibanding format seperti JSON dan ApacheThrift.
Menyimpan dan Memuat Objek dengan Fungsi Pickle Dump Python dan Fungsi Load
Pickle menggunakan fungsi-fungsi berikut untuk men-serialisasi dan mendeserialisasi objek Python:
pickle.dump(obj, file, protocol=None, *, fix_imports=True, buffer_callback=None)
pickle.dumps(obj, protocol=None, *, fix_imports=True, buffer_callback=None)
pickle.load(file, *, fix_imports=True, encoding='ASCII', errors='strict', buffers=None)
pickle.loads(data, /, *, fix_imports=True, encoding=”ASCII”, errors=”strict”, buffers=None)
Fungsi Pickle dump() dan dumps() digunakan untuk men-serialisasi sebuah objek. Satu-satunya perbedaan di antara keduanya adalah dump() menulis data ke file, sedangkan dumps() merepresentasikannya sebagai objek byte.
Demikian pula, load() membaca objek yang dipickle dari file, sedangkan loads() mendeserialisasinya dari objek mirip-bytes.
Dalam tutorial ini, kita akan menggunakan fungsi dump() dan load() untuk mempickle objek Python ke file dan meng-unpickle-nya.
Men-serialisasi Struktur Data Python dengan Pickle
List
Pertama, mari buat list Python sederhana:
import pickle
student_names = ['Alice','Bob','Elena','Jane','Kyle']
Sekarang, mari buka file teks, tulis list ke dalamnya menggunakan fungsi dumps(), lalu tutup filenya:
with open('student_file.pkl', 'wb') as f: # open a text file
pickle.dump(student_names, f) # serialize the list
Kita terlebih dahulu membuat file bernama “student_file.pkl.” Ekstensinya tidak harus .pkl. Anda dapat menamainya apa pun yang Anda suka, dan file tetap akan dibuat. Namun, praktik yang baik adalah menggunakan ekstensi .pkl agar Anda diingatkan bahwa ini adalah file Pickle.
Juga, perhatikan bahwa kita membuka file dalam mode wb. Ini berarti Anda menulis file dalam mode biner sehingga data dikembalikan sebagai objek bytes.
Kemudian, kita menggunakan fungsi dump() untuk menyimpan list student_names ke dalam file.
Terakhir, Anda dapat menutup file dengan baris kode berikut:
f.close()
Sekarang, mari deserialisasi file dan cetak list-nya:
with open('student_file.pkl', 'rb') as f:
student_names_loaded = pickle.load(f) # deserialize using load()
print(student_names_loaded) # print student names
Keluaran dari kode di atas seharusnya sebagai berikut:
['Alice', 'Bob', 'Elena', 'Jane', 'Kyle']
Perhatikan bahwa untuk mendeserialisasi file, kita perlu menggunakan mode rb, yang berarti read binary. Lalu, kita meng-unpickle objek menggunakan fungsi load(), setelah itu kita bisa menyimpan data ke variabel berbeda dan menggunakannya sesuai kebutuhan.
Sekarang mari periksa tipe data dari list yang baru saja kita unpickle:
type(student_names_loaded)
list
Bagus! Kita telah mempertahankan state dan tipe data asli dari list ini.
Array Numpy
Sekarang, mari coba men-serialisasi dan mendeserialisasi tipe data yang sedikit lebih kompleks - array Numpy.
Pertama-tama, mari buat array 10 kali 10 berisi angka satu:
import numpy as np
numpy_array = np.ones((10,10)) # 10x10 array
Lalu, seperti sebelumnya, mari panggil fungsi dump() untuk men-serialisasi array ini ke file:
with open('my_array.pkl','wb') as f:
pickle.dump(numpy_array, f)
Terakhir, mari unpickle array ini dan periksa shape serta tipe datanya untuk memastikan state aslinya tetap dipertahankan:
with open('my_array.pkl','rb') as f:
unpickled_array = pickle.load(f)
print('Array shape: '+str(unpickled_array.shape))
print('Data type: '+str(type(unpickled_array)))
Anda seharusnya mendapatkan keluaran berikut:
Array shape: (10, 10)
Data type: <class 'numpy.ndarray'>
Objek yang di-unpickle adalah array Numpy 10X10, dengan shape dan tipe data yang sama seperti objek yang baru kita serialisasi.
pandas DataFrame
Data frame adalah objek yang dikerjakan data scientist setiap hari. Cara paling populer untuk memuat dan menyimpan Pandas DataFrame adalah membacanya dan menuliskannya sebagai file CSV. Pelajari lebih lanjut tentang impor data dalam tutorial pandas read_csv().
Namun, proses ini lebih lambat daripada serialisasi dan bisa menjadi sangat memakan waktu jika data frame berukuran besar.
Mari bandingkan efisiensi menyimpan dan memuat pandas dataframe menggunakan Pickle versus CSV dengan membandingkan waktu yang dibutuhkan masing-masing.
Pertama, mari buat pandas dataframe dengan 100.000 baris data palsu:
import pandas as pd
import numpy as np
# Set random seed
np.random.seed(123)
data = {'Column1': np.random.randint(0, 10, size=100000),
'Column2': np.random.choice(['A', 'B', 'C'], size=100000),
'Column3': np.random.rand(100000)}
# Create Pandas dataframe
df = pd.DataFrame(data)
Sekarang, mari hitung waktu yang dibutuhkan untuk menyimpan dataframe ini sebagai file csv:
import time
start = time.time()
df.to_csv('pandas_dataframe.csv')
end = time.time()
print(end - start)
0.19349145889282227
Dibutuhkan 0,19 detik untuk menyimpan Pandas dataframe dengan tiga baris dan 100.000 kolom ke file csv.
Mari lihat apakah menggunakan Pickle dapat membantu meningkatkan performa. Pustaka pandas memiliki metode bernama to_pickle() yang memungkinkan kita men-serialisasi dataframe ke file pickle hanya dengan satu baris kode:
start = time.time()
df.to_pickle("my_pandas_dataframe.pkl")
end = time.time()
print(end - start)
0.0059659481048583984
Hanya dibutuhkan 5 milidetik untuk menyimpan Pandas DataFrame yang sama ke file Pickle, yang merupakan peningkatan performa signifikan dibanding menyimpannya sebagai csv.
Sekarang, mari baca kembali file tersebut ke Pandas dan lihat apakah memuat file Pickle menawarkan manfaat performa dibanding sekadar membaca file csv:
# Reading the csv file into Pandas:
start1 = time.time()
df_csv = pd.read_csv("my_pandas_dataframe.csv")
end1 = time.time()
print("Time taken to read the csv file: " + str(end1 - start1) + "\n")
# Reading the Pickle file into Pandas:
start2 = time.time()
df_pkl = pd.read_pickle("my_pandas_dataframe.pkl")
end2 = time.time()
print("Time taken to read the Pickle file: " + str(end2 - start2))
Kode di atas seharusnya menghasilkan keluaran berikut:
Time taken to read the csv file: 0.00677490234375
Time taken to read the Pickle file: 0.0009608268737792969
Dibutuhkan 6 milidetik untuk membaca file CSV ke Pandas, dan hanya 0,9 milidetik untuk membacanya dari Pickle.
Meskipun perbedaan ini tampak kecil, men-serialisasi Pandas dataframe berukuran besar dengan Pickle dapat menghasilkan penghematan waktu yang cukup besar. Pickle juga akan membantu kita mempertahankan tipe data setiap kolom dalam setiap kasus dan memakan lebih sedikit ruang disk daripada file CSV.
Dictionary
Terakhir, mari serialisasi dictionary yang kita tulis ke file teks pada bagian pertama tutorial:
students = {
'Student 1': {
'Name': "Alice", 'Age' :10, 'Grade':4,
},
'Student 2': {
'Name':'Bob', 'Age':11, 'Grade':5
},
'Student 3': {
'Name':'Elena', 'Age':14, 'Grade':8
}
}
Ingat bahwa saat kita menyimpan dictionary ini sebagai file teks, kita harus mengonversinya menjadi string, dan kita kehilangan state aslinya.
Sekarang mari serialisasi menggunakan Pickle dan baca kembali untuk memastikan bahwa dictionary tersebut masih berisi semua properti dictionary Python:
# serialize the dictionary to a pickle file
with open("student_dict.pkl", "wb") as f:
pickle.dump(students, f)
# deserialize the dictionary and print it out
with open("student_dict.pkl", "rb") as f:
deserialized_dict = pickle.load(f)
print(deserialized_dict)
Anda seharusnya mendapatkan keluaran berikut:
{'Student 1': {'Name': 'Alice', 'Age': 10, 'Grade': 4}, 'Student 2': {'Name': 'Bob', 'Age': 11, 'Grade': 5}, 'Student 3': {'Name': 'Elena', 'Age': 14, 'Grade': 8}}
Sekarang mari periksa tipe variabel ini:
type(deserialized_dict)
dict
Mari coba mengakses beberapa informasi tentang siswa pertama dalam dictionary ini:
print(
"The first student's name is "
+ deserialized_dict["Student 1"]["Name"]
+ " and she is "
+ (str(deserialized_dict["Student 1"]["Age"]))
+ " years old."
)
The first student's name is Alice and she is 10 years old.
Bagus! Dictionary mempertahankan semua properti aslinya dan dapat diakses seperti sebelum serialisasi. Lihat tutorial Python dictionary comprehension kami untuk mengetahui lebih lanjut.
Men-serialisasi Model Machine Learning dengan Pickle
Melatih model machine learning adalah proses yang memakan waktu berjam-jam, dan terkadang bahkan berhari-hari. Tidaklah praktis untuk melatih ulang algoritme dari awal saat Anda perlu menggunakannya kembali atau memindahkannya ke lingkungan berbeda.
Jika Anda ingin mempelajari praktik terbaik saat membangun algoritme machine learning, Anda dapat mengambil kursus Designing Machine Learning Workflows di Python.
Pickle memungkinkan Anda men-serialisasi model machine learning dalam state yang ada, sehingga memungkinkan untuk menggunakannya lagi sesuai kebutuhan.
Pada bagian ini, kita akan belajar men-serialisasi model machine learning dengan Pickle.
Untuk melakukannya, mari terlebih dahulu menghasilkan data palsu dan membangun model regresi linear dengan pustaka Scikit-Learn:
from sklearn.linear_model import LinearRegression
from sklearn.datasets import make_regression
# generate regression dataset
X, y = make_regression(n_samples=100, n_features=3, noise=0.1, random_state=1)
# train regression model
linear_model = LinearRegression()
linear_model.fit(X, y)
Sekarang, mari cetak beberapa parameter ringkasan model:
# summary of the model
print('Model intercept :', linear_model.intercept_)
print('Model coefficients : ', linear_model.coef_)
print('Model score : ', linear_model.score(X, y))
Model intercept : -0.010109549594702116
Model coefficients : [44.18793068 98.97389468 58.17121618]
Model score : 0.9999993081899219
Kita kemudian dapat men-serialisasi model ini menggunakan fungsi dump() dari Pickle:
with open("linear_regression.pkl", "wb") as f:
pickle.dump(linear_model, f)
Model sekarang disimpan sebagai file Pickle. Mari deserialisasi menggunakan fungsi load():
with open("linear_regression.pkl", "rb") as f:
unpickled_linear_model = pickle.load(f)
Model yang diserialisasi sekarang dimuat dan disimpan ke variabel unpickled_linear_model. Mari periksa parameter model ini untuk memastikan sama dengan yang awalnya kita buat:
# summary of the model
print('Model intercept :', unpickled_linear_model.intercept_)
print('Model coefficients : ', unpickled_linear_model.coef_)
print('Model score : ', unpickled_linear_model.score(X, y))
Anda seharusnya mendapatkan keluaran berikut:
Model intercept : -0.010109549594702116
Model coefficients : [44.18793068 98.97389468 58.17121618]
Model score : 0.9999993081899219
Bagus! Parameter model yang baru saja kita unpickle sama seperti yang awalnya kita buat.
Sekarang kita dapat menggunakan model ini untuk membuat prediksi pada dataset uji, melatih di atasnya, atau memindahkannya ke lingkungan lain.
Meningkatkan Performa Python Pickle untuk Objek Besar
Pickle adalah format serialisasi yang efisien dan sering terbukti lebih cepat daripada JSON, XML, dan HDF5 dalam berbagai benchmark.
Namun, saat menangani struktur data yang sangat besar atau model machine learning raksasa, Pickle dapat melambat secara signifikan, dan serialisasi bisa menjadi bottleneck dalam alur kerja Anda.
Berikut beberapa cara untuk mengurangi waktu yang dibutuhkan saat menyimpan dan memuat file Pickle:
Gunakan argumen PROTOCOL
Protocol default yang digunakan saat menyimpan dan memuat file Pickle saat ini adalah 4, yang paling kompatibel dengan berbagai versi Python.
Namun, jika Anda ingin mempercepat alur kerja, Anda dapat menggunakan argumen HIGHEST_PROTOCOL, yaitu protocol Pickle yang paling cepat tersedia.
Untuk membandingkan perbedaan performa antara protocol Pickle yang paling kompatibel dan protocol default, mari terlebih dahulu men-serialisasi sebuah Pandas DataFrame menggunakan protocol default. Perlu dicatat bahwa ini adalah versi protocol yang digunakan Pickle jika tidak ada protocol spesifik yang dinyatakan secara eksplisit:
import pickle
import time
import numpy as np
# Set random seed
np.random.seed(100)
data = {'Column1': np.random.randint(0, 10, size=100000),
'Column2': np.random.choice(['A', 'B', 'C'], size=100000),
'Column3': np.random.rand(100000)}
# serialize to a file
start = time.time()
with open("df1.pkl", "wb") as f:
pickle.dump(data, f)
end = time.time()
print(end - start)
0.006001710891723633
Dibutuhkan sekitar 6 milidetik untuk men-serialisasi DataFrame menggunakan protocol default Pickle.
Sekarang, mari pickle DataFrame menggunakan protocol tertinggi:
start = time.time()
with open("df2.pkl", "wb") as f:
pickle.dump(data, f, protocol=pickle.HIGHEST_PROTOCOL)
end = time.time()
print(end - start)
0.0030384063720703125
Dengan protocol tertinggi, kita berhasil men-serialisasi DataFrame dalam setengah waktu.
Gunakan cPickle alih-alih Pickle
Modul cPickle adalah versi Pickle yang lebih cepat dan ditulis dalam C. Hal ini membuatnya lebih cepat daripada pustaka Pickle, yang diimplementasikan murni dalam Python.
Perlu dicatat bahwa di Python3, cPickle telah diubah namanya menjadi _pickle, yang akan kita impor.
import _pickle as cPickle
start = time.time()
with open("df3.pkl", "wb") as f:
cPickle.dump(data, f)
end = time.time()
print(end-start)
0.004027366638183594
Serialisasi dengan cPickle memakan waktu sekitar 4 milidetik, yang merupakan peningkatan substansial dibanding modul Pickle Python.
Hanya men-serialisasi yang Anda butuhkan
Bahkan dengan solusi untuk mempercepat serialisasi, proses ini masih bisa sangat lambat untuk objek besar.
Untuk meningkatkan performa, Anda dapat memecah struktur data dan hanya men-serialisasi subset yang diperlukan.
Ketika bekerja dengan dictionary, misalnya, Anda dapat menentukan pasangan key-value yang ingin diakses lagi. Kurangi ukuran dictionary sebelum men-serialisasikannya karena ini akan mengurangi kompleksitas objek dan mempercepat proses secara signifikan.
Serialisasi dengan Pickle di Python: Langkah Berikutnya
Selamat! Anda telah mempelajari beragam topik terkait serialisasi di Python dan penggunaan pustaka Pickle.
Sekarang Anda seharusnya memiliki pemahaman yang kuat tentang apa itu serialisasi, cara menggunakan Pickle untuk men-serialisasi struktur data Python, dan cara mengoptimalkan performa Pickle menggunakan berbagai argumen dan modul.
Berikut beberapa langkah yang dapat Anda ambil untuk meningkatkan pemahaman tentang serialisasi dan memanfaatkannya untuk memperkuat alur kerja data science Anda:
- Pelajari Format Serialisasi Baru. Meskipun kita hanya membahas modul Pickle dalam tutorial ini, tidak selalu Pickle adalah format serialisasi terbaik untuk setiap skenario. Layak untuk mempelajari format lain, seperti JSON, XML, dan HDF5, sehingga Anda tahu mana yang dipilih untuk berbagai kasus penggunaan.
- Coba Sendiri. Terapkan konsep yang diajarkan dalam tutorial ini ke alur kerja data science Anda. Saat Anda membuat struktur data baru atau menyimpan keluaran perhitungan dalam variabel, serialisasikan untuk digunakan nanti alih-alih menjalankan seluruh kode Anda berulang kali.
- Ikuti Kursus Daring. Untuk mengoptimalkan alur kerja data science dan melakukan tugas seperti serialisasi secara efisien, penting untuk memiliki pemahaman yang kuat tentang struktur data dan objek Python. Untuk mencapainya, Anda dapat mengikuti kursus Data Types for Data Science in Python kami.
Natassha adalah seorang konsultan data yang bekerja di persimpangan ilmu data dan pemasaran. Ia meyakini bahwa data, ketika digunakan dengan bijak, dapat menginspirasi pertumbuhan luar biasa bagi individu dan organisasi. Sebagai profesional data autodidak, Natassha suka menulis artikel yang membantu para calon praktisi ilmu data menembus industri. Artikel-artikelnya di blog pribadi, serta publikasi eksternal, meraih rata-rata 200 ribu tayangan per bulan.

