.. raw:: html
.. raw:: html
.. raw:: html
.. _sec_pandas:
Tiền xử lý dữ liệu
==================
.. raw:: html
Cho đến giờ chúng tôi đã đề cập tới rất nhiều kỹ thuật thao tác dữ liệu
được lưu trong dạng ``ndarray``. Nhưng để áp dụng học sâu vào giải quyết
các vấn đề thực tế, ta thường phải bắt đầu bằng việc xử lý dữ liệu thô,
chứ không có luôn dữ liệu ngăn nắp được chuẩn bị sẵn trong định dạng
``ndarray``. Trong số các công cụ phân tích dữ liệu phổ biến của Python,
gói ``pandas`` khá được ưa chuộng. Cũng như nhiều gói khác trong hệ sinh
thái rộng lớn của Python, ‘pandas’ có thể được sử dụng kết hợp với định
dạng ``ndarray``. Vì vậy, chúng ta sẽ đi nhanh qua các bước để tiền xử
lý dữ liệu thô bằng ``pandas`` rồi đổi chúng sang dạng ``ndarray``.
Nhiều kỹ thuật tiền xử lý dữ liệu khác sẽ được giới thiệu trong các
chương sau.
.. raw:: html
Đọc tập dữ liệu
---------------
.. raw:: html
Để lấy ví dụ, ta bắt đầu bằng việc tạo một tập dữ liệu nhân tạo lưu
trong file csv ``../data/house_tiny.csv`` (csv - *comma-separated values
- giá trị tách nhau bằng dấu phẩy*). Dữ liệu lưu ở các định dạng khác
cũng có thể được xử lý tương tự. Hàm ``mkdir_if_not_exist`` dưới đây để
đảm bảo rằng thư mục ``../data`` tồn tại. Chú thích
``# Saved in the d2l package for later use`` (*Lưu lại trong gói d2l để
dùng sau*) là kí hiệu đánh dấu các hàm, lớp hoặc các lệnh ``import``
được lưu trong gói ``d2l``, để sau này ta có thể trực tiếp gọi hàm
``d2l.mkdir_if_not_exist()``.
.. code:: python
import os
# Saved in the d2l package for later use
def mkdir_if_not_exist(path):
if not isinstance(path, str):
path = os.path.join(*path)
if not os.path.exists(path):
os.makedirs(path)
.. raw:: html
Sau đây ta ghi tệp dữ liệu vào file csv theo từng hàng một.
.. code:: python
data_file = '../data/house_tiny.csv'
mkdir_if_not_exist('../data')
with open(data_file, 'w') as f:
f.write('NumRooms,Alley,Price\n') # Column names
f.write('NA,Pave,127500\n') # Each row is a data point
f.write('2,NA,106000\n')
f.write('4,NA,178100\n')
f.write('NA,NA,140000\n')
.. raw:: html
.. raw:: html
.. raw:: html
Để nạp tập dữ liệu thô từ tệp csv vừa được tạo ra, ta dùng gói thư viện
``pandas`` và gọi hàm ``read_csv``. Bộ dữ liệu này có :math:`4` hàng và
:math:`3` cột, trong đó mỗi hàng biểu thị số phòng (“NumRooms”), kiểu
lối đi (“Alley”), và giá (“Price”) của căn nhà.
.. code:: python
# If pandas is not installed, just uncomment the following line:
# !pip install pandas
import pandas as pd
data = pd.read_csv(data_file)
print(data)
.. parsed-literal::
:class: output
NumRooms Alley Price
0 NaN Pave 127500
1 2.0 NaN 106000
2 4.0 NaN 178100
3 NaN NaN 140000
.. raw:: html
.. raw:: html
.. raw:: html
.. raw:: html
Xử lý dữ liệu thiếu
-------------------
.. raw:: html
Để ý rằng giá trị “NaN” là các giá trị bị thiếu. Để xử lý dữ liệu thiếu,
các cách thường được áp dụng là *quy buộc* (*imputation*) và *xoá bỏ*
(*deletion*), trong đó quy buộc thay thế giá trị bị thiếu bằng giá trị
khác, trong khi xoá bỏ sẽ bỏ qua các giá trị bị thiếu. Dưới đây chúng ta
xem xét phương pháp quy buộc.
.. raw:: html
Bằng phương pháp đánh chỉ số theo số nguyên (``iloc``), chúng ta tách
``data`` thành ``inputs`` (tương ứng với hai cột đầu) và ``outputs``
(tương ứng với cột cuối cùng). Với các giá trị số bị thiếu trong
``inputs``, ta thay thế phần tử “NaN” bằng giá trị trung bình cộng của
cùng cột đó.
.. code:: python
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())
print(inputs)
.. parsed-literal::
:class: output
NumRooms Alley
0 3.0 Pave
1 2.0 NaN
2 4.0 NaN
3 3.0 NaN
.. raw:: html
Với các giá trị dạng hạng mục hoặc số rời rạc trong ``inputs``, ta coi
“NaN” là một mục riêng. Vì cột “Alley” chỉ nhận 2 giá trị riêng lẻ là
“Pave” (được lát gạch) và “NaN”, ``pandas`` có thể tự động chuyển cột
này thành 2 cột “Alley_Pave” và “Alley_nan”. Những hàng có kiểu lối đi
là “Pave” sẽ có giá trị của cột “Alley_Pave” và cột “Alley_nan” tương
ứng là :math:`1` và :math:`0`. Hàng mà không có giá trị cho kiểu lối đi
sẽ có giá trị cột “Alley_Pave” và cột “Alley_nan” lần lượt là :math:`0`
và :math:`1`.
.. code:: python
inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)
.. parsed-literal::
:class: output
NumRooms Alley_Pave Alley_nan
0 3.0 1 0
1 2.0 0 1
2 4.0 0 1
3 3.0 0 1
.. raw:: html
.. raw:: html
.. raw:: html
Chuyển sang định dạng ``ndarray``
---------------------------------
.. raw:: html
Giờ thì toàn bộ các giá trị trong ``inputs`` và ``outputs`` đã ở dạng
số, chúng đã có thể được chuyển sang định dạng ``ndarray``. Khi đã ở
định dạng này, chúng có thể được biến đổi và xử lý với những chức năng
của ``ndarray`` đã được giới thiệu ở :numref:`sec_ndarray`.
.. code:: python
from mxnet import np
X, y = np.array(inputs.values), np.array(outputs.values)
X, y
.. parsed-literal::
:class: output
(array([[3., 1., 0.],
[2., 0., 1.],
[4., 0., 1.],
[3., 0., 1.]], dtype=float64),
array([127500, 106000, 178100, 140000], dtype=int64))
.. raw:: html
Tóm tắt
-------
.. raw:: html
- Cũng như nhiều gói mở rộng trong hệ sinh thái khổng lồ của Python,
``pandas`` có thể làm việc được với ``ndarray``.
- Phương pháp quy buộc hoặc xoá bỏ có thể dùng để xử lý dữ liệu bị
thiếu.
.. raw:: html
Bài tập
-------
.. raw:: html
Tạo một tập dữ liệu với nhiều hàng và cột hơn.
.. raw:: html
1. Xoá cột có nhiều giá trị bị thiếu nhất.
2. Chuyển bộ dữ liệu đã được xử lý sang định dạng ``ndarray``.
.. raw:: html
.. raw:: html
.. raw:: html
Thảo luận
---------
- `Tiếng Anh `__
- `Tiếng Việt `__
.. raw:: html
Những người thực hiện
---------------------
Bản dịch trong trang này được thực hiện bởi:
- Lê Khắc Hồng Phúc
- Nguyễn Cảnh Thướng
- Phạm Hồng Vinh
- Đoàn Võ Duy Thanh
- Vũ Hữu Tiệp
- Mai Sơn Hải