Khóa học
Tuần tự hóa là một kỹ năng rất hữu ích. Nó cho phép bạn lưu lại trạng thái của dữ liệu hoặc mô hình, tránh phải xử lý lại hoặc huấn luyện lại từ đầu.
Trong bài viết này, tôi sẽ giới thiệu mô-đun Python Pickle nổi tiếng. Kết thúc bài, bạn sẽ biết cách tuần tự hóa và giải tuần tự các cấu trúc dữ liệu phổ biến như list và dictionary, cũng như cách áp dụng các kỹ thuật tối ưu hiệu năng khác nhau.
Tôi cũng khuyến nghị khóa học Thiết kế quy trình làm việc Machine Learning trong Python như bước tiếp theo, nơi bạn có thể học cách tuần tự hóa và đóng gói mô hình ML để đưa vào sản xuất.
Giới thiệu về tuần tự hóa đối tượng
Bạn có mệt mỏi vì phải chạy lại mã Python mỗi khi cần truy cập một data frame, biến, hoặc mô hình machine learning đã tạo trước đó không?
Tuần tự hóa đối tượng có thể là giải pháp bạn đang tìm kiếm.
Đó là quá trình lưu trữ một cấu trúc dữ liệu trong bộ nhớ để bạn có thể tải hoặc truyền đi khi cần mà không làm mất trạng thái hiện tại của nó.
Dưới đây là sơ đồ đơn giản giải thích cách tuần tự hóa hoạt động:

Hình minh họa của Tác giả
Trong Python, chúng ta làm việc với các cấu trúc dữ liệu cấp cao như list, tuple và set. Tuy nhiên, khi muốn lưu các đối tượng này vào bộ nhớ, chúng cần được chuyển đổi thành một dãy byte mà máy tính có thể hiểu được. Quá trình này gọi là tuần tự hóa.
Lần tiếp theo khi muốn truy cập cùng cấu trúc dữ liệu đó, dãy byte này phải được chuyển ngược lại thành đối tượng cấp cao trong một quá trình gọi là giải tuần tự.
Chúng ta có thể dùng các định dạng như JSON, XML, HDF5 và Pickle để tuần tự hóa. Trong hướng dẫn này, chúng ta sẽ tìm hiểu thư viện Python Pickle cho tuần tự hóa. Chúng ta sẽ đề cập cách sử dụng và hiểu khi nào nên chọn Pickle thay vì các định dạng tuần tự khác.
Cuối cùng, chúng ta sẽ học cách dùng thư viện Pickle của Python để tuần tự hóa list, dictionary, data frame Pandas, mô hình machine learning, và nhiều hơn nữa.
Để tự mình chạy dễ dàng toàn bộ mã ví dụ trong hướng dẫn này, bạn có thể tạo một sổ tay DataLab miễn phí với Python cài sẵn và chứa mọi mẫu mã. Để thực hành thêm về cách tải tệp pickle của Python, hãy xem bài tập thực hành này trên DataCamp.
Tại sao chúng ta cần tuần tự hóa đối tượng?
Trước khi bắt đầu với Python Pickle, hãy cùng hiểu vì sao tuần tự hóa đối tượng lại quan trọng đến vậy.
Bạn có thể thắc mắc tại sao không đơn giản lưu các cấu trúc dữ liệu vào một tệp văn bản rồi truy cập lại khi cần, thay vì phải tuần tự hóa chúng.
Hãy đi qua một ví dụ đơn giản để hiểu lợi ích của tuần tự hóa.
Dưới đây là một dictionary lồng nhau chứa thông tin học sinh như tên, tuổi và giới tính:
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
}
}
Hãy kiểm tra kiểu dữ liệu của đối tượng “students”:
type(students)
dict
Bây giờ chúng ta đã xác nhận đối tượng student là kiểu dictionary, hãy thử ghi nó vào một tệp văn bản mà không tuần tự hóa:
with open('student_info.txt','w') as data:
data.write(str(students))
Lưu ý rằng vì chỉ có thể ghi đối tượng chuỗi vào tệp văn bản, chúng ta đã chuyển dictionary thành chuỗi bằng hàm str(). Điều này có nghĩa trạng thái gốc của dictionary đã bị mất.
Giờ hãy đọc lại dictionary, in ra và kiểm tra kiểu của nó một lần nữa:
with open("student_info.txt", 'r') as f:
for students in f:
print(students)
type(students)
str
Dictionary lồng nhau giờ được in ra như một chuỗi và sẽ báo lỗi khi chúng ta cố truy cập các khóa hoặc giá trị của nó.
Đây chính là lúc tuần tự hóa phát huy tác dụng.
Khi làm việc với các kiểu dữ liệu phức tạp hơn như dictionary, data frame và list lồng nhau, tuần tự hóa cho phép người dùng giữ nguyên trạng thái gốc của đối tượng mà không mất thông tin liên quan nào.
Ở phần sau của bài viết, chúng ta sẽ học cách lưu dictionary này vào tệp bằng Pickle và giải tuần tự nó bằng thư viện. Bạn có thể đọc thêm về hiểu list/dictionary trong Python ở một hướng dẫn riêng.
Giới thiệu về Pickle trong Python
Mô-đun Pickle của Python là một định dạng phổ biến dùng để tuần tự hóa và giải tuần tự các kiểu dữ liệu. Đây là định dạng đặc thù của Python, nghĩa là đối tượng Pickle không thể được tải bằng ngôn ngữ lập trình khác.
Pickle có những ưu và nhược điểm riêng so với các định dạng tuần tự khác.
Ưu điểm khi dùng Pickle để tuần tự hóa đối tượng
- Không giống như JSON, vốn không xử lý được tuple và đối tượng datetime, Pickle có thể tuần tự hóa hầu như mọi kiểu dữ liệu dựng sẵn thường dùng trong Python. Nó cũng giữ nguyên trạng thái chính xác của đối tượng mà JSON không làm được.
- Pickle cũng là lựa chọn tốt khi lưu trữ cấu trúc đệ quy vì nó chỉ ghi một đối tượng một lần.
- Pickle cho phép linh hoạt khi giải tuần tự đối tượng. Bạn có thể dễ dàng lưu nhiều biến vào một tệp Pickle và tải lại trong một phiên Python khác, khôi phục dữ liệu y hệt mà không cần chỉnh sửa mã.
Nhược điểm khi dùng Pickle
- Pickle không an toàn vì có thể thực thi các callable độc hại của Python để dựng đối tượng. Khi giải tuần tự một đối tượng, Pickle không phân biệt được callable độc hại và không độc hại. Do đó, người dùng có thể vô tình thực thi mã tùy ý trong quá trình giải tuần tự.
- Như đã đề cập, Pickle là mô-đun dành riêng cho Python, và bạn có thể gặp khó khăn khi giải tuần tự đối tượng đã pickle bằng ngôn ngữ khác.
- Theo nhiều phép đo, Pickle có vẻ chậm hơn và tạo ra giá trị tuần tự lớn hơn so với các định dạng như JSON và ApacheThrift.
Lưu và tải đối tượng với hàm Pickle Dump và Load
Pickle dùng các hàm sau để tuần tự hóa và giải tuần tự đối tượng 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)
Hai hàm dump() và dumps() của Pickle dùng để tuần tự hóa một đối tượng. Khác biệt duy nhất là dump() ghi dữ liệu ra tệp, còn dumps() biểu diễn nó dưới dạng đối tượng byte.
Tương tự, load() đọc đối tượng đã pickle từ tệp, còn loads() giải tuần tự chúng từ một đối tượng kiểu bytes.
Trong hướng dẫn này, chúng ta sẽ dùng các hàm dump() và load() để pickle đối tượng Python vào tệp và unpickle chúng.
Tuần tự hóa các cấu trúc dữ liệu Python với Pickle
List
Đầu tiên, hãy tạo một list Python đơn giản:
import pickle
student_names = ['Alice','Bob','Elena','Jane','Kyle']
Giờ hãy mở một tệp, ghi list vào bằng hàm dumps() và đóng tệp:
with open('student_file.pkl', 'wb') as f: # open a text file
pickle.dump(student_names, f) # serialize the list
Trước tiên, chúng ta đã tạo một tệp có tên “student_file.pkl.” Phần mở rộng không nhất thiết phải là .pkl. Bạn có thể đặt tên tùy ý và tệp vẫn sẽ được tạo. Tuy nhiên, nên dùng phần mở rộng .pkl để nhắc bạn rằng đây là tệp Pickle.
Cũng lưu ý rằng chúng ta mở tệp ở chế độ wb. Điều này có nghĩa bạn đang ghi tệp ở chế độ nhị phân để dữ liệu được trả về dưới dạng đối tượng bytes.
Sau đó, chúng ta dùng hàm dump() để lưu list student_names vào tệp.
Cuối cùng, bạn có thể đóng tệp bằng dòng mã sau:
f.close()
Giờ hãy giải tuần tự tệp và in list ra:
with open('student_file.pkl', 'rb') as f:
student_names_loaded = pickle.load(f) # deserialize using load()
print(student_names_loaded) # print student names
Kết quả của đoạn mã trên sẽ như sau:
['Alice', 'Bob', 'Elena', 'Jane', 'Kyle']
Lưu ý rằng để giải tuần tự tệp, chúng ta cần dùng chế độ rb, nghĩa là đọc ở dạng nhị phân. Sau đó, chúng ta unpickle đối tượng bằng hàm load(), rồi có thể lưu dữ liệu vào biến khác và sử dụng theo ý.
Giờ hãy kiểm tra kiểu dữ liệu của list vừa unpickle:
type(student_names_loaded)
list
Tuyệt vời! Chúng ta đã giữ nguyên trạng thái và kiểu dữ liệu gốc của list này.
Mảng Numpy
Giờ hãy thử tuần tự hóa và giải tuần tự một kiểu dữ liệu phức tạp hơn một chút - mảng Numpy.
Trước hết, tạo một mảng 10 x 10 toàn số 1:
import numpy as np
numpy_array = np.ones((10,10)) # 10x10 array
Tiếp theo, giống như trước đó, gọi hàm dump() để tuần tự hóa mảng này vào tệp:
with open('my_array.pkl','wb') as f:
pickle.dump(numpy_array, f)
Cuối cùng, hãy unpickle mảng này và kiểm tra shape và kiểu dữ liệu để đảm bảo nó giữ nguyên trạng thái ban đầu:
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)))
Bạn sẽ nhận được kết quả sau:
Array shape: (10, 10)
Data type: <class 'numpy.ndarray'>
Đối tượng unpickle là mảng Numpy 10x10, có cùng shape và kiểu dữ liệu như đối tượng chúng ta vừa tuần tự hóa.
pandas DataFrame
Data frame là một đối tượng mà các nhà khoa học dữ liệu làm việc với hằng ngày. Cách phổ biến nhất để tải và lưu một Pandas DataFrame là đọc/ghi nó dưới dạng tệp CSV. Tìm hiểu thêm về nhập dữ liệu trong hướng dẫn pandas read_csv().
Tuy nhiên, quy trình này chậm hơn so với tuần tự hóa và có thể trở nên rất tốn thời gian nếu data frame lớn.
Hãy so sánh hiệu quả của việc lưu và tải một pandas dataframe bằng Pickle so với CSV bằng cách đo thời gian tương ứng.
Đầu tiên, hãy tạo một pandas dataframe với 100.000 dòng dữ liệu giả:
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)
Giờ hãy tính thời gian lưu dataframe này thành tệp csv:
import time
start = time.time()
df.to_csv('pandas_dataframe.csv')
end = time.time()
print(end - start)
0.19349145889282227
Mất 0,19 giây để lưu một Pandas dataframe với ba cột và 100.000 dòng thành tệp csv.
Hãy xem việc dùng Pickle có giúp cải thiện hiệu năng hay không. Thư viện pandas có phương thức to_pickle() cho phép chúng ta tuần tự hóa dataframe sang tệp pickle chỉ với một dòng mã:
start = time.time()
df.to_pickle("my_pandas_dataframe.pkl")
end = time.time()
print(end - start)
0.0059659481048583984
Chỉ mất 5 mili giây để lưu cùng DataFrame đó vào tệp Pickle, một cải thiện hiệu năng đáng kể so với lưu dạng csv.
Giờ hãy đọc tệp trở lại Pandas và xem việc tải tệp Pickle có mang lại lợi ích hiệu năng so với chỉ đọc tệp csv hay không:
# 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))
Đoạn mã trên sẽ cho ra kết quả sau:
Time taken to read the csv file: 0.00677490234375
Time taken to read the Pickle file: 0.0009608268737792969
Mất 6 mili giây để đọc tệp CSV vào Pandas, và chỉ 0,9 mili giây để đọc tệp Pickle.
Dù chênh lệch có vẻ nhỏ, việc tuần tự hóa các dataframe Pandas lớn bằng Pickle có thể tiết kiệm thời gian đáng kể. Pickle cũng giúp chúng ta giữ nguyên kiểu dữ liệu của từng cột trong mọi trường hợp và chiếm ít dung lượng đĩa hơn tệp CSV.
Dictionary
Cuối cùng, hãy tuần tự hóa dictionary mà chúng ta đã ghi vào tệp văn bản ở phần đầu hướng dẫn:
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
}
}
Hãy nhớ rằng khi lưu dictionary này thành tệp văn bản, chúng ta phải chuyển nó thành chuỗi và đã mất trạng thái gốc.
Giờ hãy tuần tự hóa nó bằng Pickle và đọc lại để đảm bảo nó vẫn giữ mọi thuộc tính của một 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)
Bạn sẽ nhận được kết quả sau:
{'Student 1': {'Name': 'Alice', 'Age': 10, 'Grade': 4}, 'Student 2': {'Name': 'Bob', 'Age': 11, 'Grade': 5}, 'Student 3': {'Name': 'Elena', 'Age': 14, 'Grade': 8}}
Giờ hãy kiểm tra kiểu của biến này:
type(deserialized_dict)
dict
Hãy thử truy cập một số thông tin về học sinh đầu tiên trong dictionary này:
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.
Tuyệt vời! Dictionary đã giữ nguyên mọi thuộc tính gốc và có thể được truy cập như trước khi tuần tự hóa. Xem thêm hướng dẫn hiểu list/dictionary trong Python để tìm hiểu thêm.
Tuần tự hóa mô hình Machine Learning với Pickle
Huấn luyện một mô hình machine learning là quá trình tốn thời gian, có thể kéo dài hàng giờ, thậm chí nhiều ngày. Việc huấn luyện lại thuật toán từ đầu mỗi khi cần tái sử dụng hoặc chuyển sang môi trường khác là không khả thi.
Nếu bạn muốn học về các thực tiễn tốt nhất khi xây dựng thuật toán machine learning, bạn có thể học khóa Thiết kế quy trình làm việc Machine Learning trong Python của chúng tôi.
Pickle cho phép bạn tuần tự hóa các mô hình machine learning ở trạng thái hiện tại, giúp có thể sử dụng lại khi cần.
Trong phần này, chúng ta sẽ học cách tuần tự hóa một mô hình machine learning với Pickle.
Để làm điều này, trước tiên hãy tạo dữ liệu giả và xây dựng một mô hình hồi quy tuyến tính với thư viện 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)
Giờ hãy in ra một số tham số tóm tắt của mô hình:
# 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
Sau đó, chúng ta có thể tuần tự hóa mô hình này bằng hàm dump() của Pickle:
with open("linear_regression.pkl", "wb") as f:
pickle.dump(linear_model, f)
Mô hình giờ đã được lưu dưới dạng tệp Pickle. Hãy giải tuần tự nó bằng hàm load():
with open("linear_regression.pkl", "rb") as f:
unpickled_linear_model = pickle.load(f)
Mô hình đã tuần tự nay được tải và lưu vào biến unpickled_linear_model. Hãy kiểm tra các tham số của mô hình này để đảm bảo nó giống hệt mô hình ban đầu:
# 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))
Bạn sẽ nhận được kết quả sau:
Model intercept : -0.010109549594702116
Model coefficients : [44.18793068 98.97389468 58.17121618]
Model score : 0.9999993081899219
Tuyệt vời! Các tham số của mô hình vừa unpickle trùng khớp với mô hình ban đầu.
Giờ chúng ta có thể dùng mô hình này để dự đoán trên tập kiểm thử, huấn luyện tiếp, hoặc chuyển sang môi trường khác.
Tăng hiệu năng Python Pickle cho các đối tượng lớn
Pickle là một định dạng tuần tự hóa hiệu quả, thường cho thấy nhanh hơn JSON, XML và HDF5 trong nhiều bài đo.
Tuy nhiên, khi làm việc với các cấu trúc dữ liệu cực lớn hoặc mô hình machine learning khổng lồ, Pickle có thể chậm đi đáng kể và tuần tự hóa có thể trở thành nút thắt hiệu năng trong quy trình của bạn.
Dưới đây là vài cách bạn có thể giảm thời gian lưu và tải tệp Pickle:
Dùng tham số PROTOCOL
Giao thức mặc định khi lưu và tải tệp Pickle hiện là 4, đây là giao thức tương thích nhất với các phiên bản Python khác nhau.
Tuy nhiên, nếu muốn tăng tốc quy trình, bạn có thể dùng đối số HIGHEST_PROTOCOL, là giao thức nhanh nhất hiện có của Pickle.
Để so sánh khác biệt hiệu năng giữa giao thức tương thích nhất của Pickle và giao thức mặc định, trước hết hãy tuần tự hóa một Pandas DataFrame bằng giao thức mặc định. Lưu ý đây là phiên bản giao thức mà Pickle dùng nếu không chỉ định rõ:
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
Mất khoảng 6 mili giây để chúng ta tuần tự hóa DataFrame bằng giao thức mặc định của Pickle.
Giờ hãy pickle DataFrame bằng giao thức cao nhất:
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
Với giao thức cao nhất, chúng ta đã tuần tự hóa DataFrame trong một nửa thời gian.
Dùng cPickle thay cho Pickle
Mô-đun cPickle là phiên bản nhanh hơn của Pickle được viết bằng C. Nhờ đó nó nhanh hơn thư viện Pickle được triển khai hoàn toàn bằng Python.
Lưu ý rằng trong Python3, cPickle được đổi tên thành _pickle, đây là thư viện chúng ta sẽ import.
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
Tuần tự hóa với cPickle mất khoảng 4 mili giây, là mức cải thiện đáng kể so với mô-đun Pickle của Python.
Chỉ tuần tự hóa những gì bạn cần
Ngay cả với các cách làm để tăng tốc, quá trình tuần tự hóa vẫn có thể rất chậm với các đối tượng lớn.
Để cải thiện hiệu năng, bạn có thể tách nhỏ cấu trúc dữ liệu và chỉ tuần tự hóa các phần cần thiết.
Khi làm việc với dictionary, chẳng hạn, bạn có thể chỉ định các cặp khóa-giá trị muốn truy cập lại. Hãy giảm kích thước dictionary trước khi tuần tự hóa vì điều này sẽ giảm độ phức tạp của đối tượng và tăng tốc quá trình đáng kể.
Tuần tự hóa với Pickle trong Python: Bước tiếp theo
Chúc mừng bạn! Bạn đã học được nhiều chủ đề xoay quanh tuần tự hóa trong Python và cách sử dụng thư viện Pickle.
Bây giờ bạn đã hiểu vững tuần tự hóa là gì, cách dùng Pickle để tuần tự hóa các cấu trúc dữ liệu Python, và cách tối ưu hiệu năng của Pickle bằng các đối số và mô-đun khác nhau.
Dưới đây là vài bước bạn có thể thực hiện để nâng cao hiểu biết về tuần tự hóa và tận dụng nó để cải thiện quy trình khoa học dữ liệu:
- Tìm hiểu các định dạng tuần tự hóa mới. Dù trong hướng dẫn này chúng ta chỉ đề cập mô-đun Pickle, nó không nhất thiết là định dạng tốt nhất trong mọi tình huống. Đáng để học thêm về các định dạng khác như JSON, XML và HDF5 để biết nên chọn định dạng nào cho từng trường hợp sử dụng.
- Tự mình thử nghiệm. Áp dụng các khái niệm trong hướng dẫn này vào quy trình khoa học dữ liệu của bạn. Lần tới khi bạn tạo cấu trúc dữ liệu mới hoặc lưu kết quả tính toán vào một biến, hãy tuần tự hóa nó để dùng sau, thay vì chạy lại toàn bộ mã nhiều lần.
- Tham gia khóa học trực tuyến. Để tối ưu quy trình khoa học dữ liệu và thực hiện hiệu quả các tác vụ như tuần tự hóa, điều cốt yếu là phải hiểu rõ về cấu trúc dữ liệu và đối tượng trong Python. Để đạt được điều này, bạn có thể học khóa Kiểu dữ liệu cho Khoa học Dữ liệu trong Python của chúng tôi.
Natassha là một chuyên viên tư vấn dữ liệu làm việc tại giao điểm giữa khoa học dữ liệu và tiếp thị. Cô tin rằng dữ liệu, khi được sử dụng khôn ngoan, có thể truyền cảm hứng cho sự phát triển vượt bậc của cá nhân và tổ chức. Là một chuyên gia dữ liệu tự học, Natassha thích viết các bài báo giúp những người theo đuổi khoa học dữ liệu bước chân vào ngành. Các bài viết trên blog cá nhân cũng như trên các ấn phẩm bên ngoài của cô thu hút trung bình 200 nghìn lượt xem mỗi tháng.
