Khi có một bộ dữ liệu trong tay, phần lớn những newbie (trong đó có cả mình) sẽ nghĩ tới việc bắt tay vào mô hình hoá, tính toán, phân tích, thậm chí bê nguyên các model machine learning vào để predict rất hoành tráng. Nhưng..., bùm, lỗi hiện lên khi dùng các thư viện, nếu may mắn không có lỗi, thì kết quả cũng hết sức tệ, không chính xác.
"Garbage in, garbage out."
Nguồn: Gil Press - Forbes
Ta có thể thấy, Data Scientists dành tới 60% thời gian của mình để Clean và tổ chức lại dữ liệu.
"Quality data beats fancy algorithms."
Quá trình Cleaning Data không chỉ diễn ra một lần, mà sẽ luôn được lặp lại qua việc mô hình hoá, trực quan hoá, khai phá dữ liệu. Nguồn: Datacamp
Import các thư viện và thiết lập một số thông số
import pandas as pd
import numpy as np import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = (12, 8) import seaborn as sns
sns.set(style='whitegrid') import warnings
warnings.filterwarnings('ignore')
Load dữ liệu.
Dữ liệu mình sẽ sử dụng sẽ là "Đánh giá các loại mì ăn liền".
https://www.kaggle.com/residentmario/ramen-ratings
df = pd.read_csv('/content/gdrive/My Drive/ramen-ratings.csv')
df.head()
Mình sẽ load dữ liệu vào biến "df". Và luôn in ra vài dòng của dữ liệu với head() để có cái nhìn đầu tiên về "đối tượng" nhé .
Chuẩn hoá định dạng của dữ liệu.
Từ đây ta có thể thấy có Review Id, Brand (thương hiệu), Variety (Sản phẩm), Style (Kiểu đóng gói), Country (Xuất xứ), Stars (Đánh giá), Top Ten !? (cái này mình không rõ là Top Ten cái gì).
df.info()
info() là một method khá hữu ích để xem thông tin về kiểu dữ liệu của các cột, số lượng hàng và cột, các giá trị bị thiếu, bộ nhớ sử dụng.
Brand, Variety, Style, Country có kiểu 'object' vì nó có chứa dữ liệu kiểu 'str'. Review id thì không có gì đáng quan tâm lắm. Chỉ còn 'Stars' và 'Top Ten'. 'Stars' là các đánh giá bằng số thực, nên để hợp lý, ta nên chuyển nó sang kiểu 'float'.
df['Stars'] = pd.to_numeric(df['Stars'])
Á, có dữ liệu không theo định dạng số.. Ta sẽ tự viết hàm để kiểm tra, nếu không thể đưa về float, thì sẽ in chúng ra.
def check(e): try: float(e) except: print(e) for _, row in df.iterrows(): check(row['Stars'])
Giờ thì dễ rồi, chúng đều là 'Unrated', ta chỉ cần replace chúng với một giá trị khác, mình tạm thời sẽ replace chúng với 'NaN'. Rồi dùng method to_numeric() để thực hiện nốt công việc bên trên.
df['Stars'].replace('Unrated', np.NaN, inplace=True)
df['Stars'] = pd.to_numeric(df['Stars'])
'Top Ten', có lẽ cần phải đào sâu hơn để biết được chính xác nó có những gì.
df['Top Ten'].unique()
Có thể hiểu rằng, nếu Sản phẩm đó nằm trong top 10 của năm nào đó, thì sẽ có số năm và hạng. Còn không có thì sẽ là nan. '\n' có thể là lỗi khi thu thập dữ liệu. Vậy ta sẽ replace nan và '\n' thành 'No'.
df['Top Ten'].replace([np.NaN, '\n'], ['No', 'No'], inplace=True)
Giờ ta sẽ xem tới các giá trị của chúng có gì bất thường không.
df.describe()
Stars có min là 0, max là 5, hoàn toàn hợp lý.
Loại bỏ các giá trị sai, trùng lặp.
Loại bỏ toàn bộ các giá trị trùng lặp trong bộ dữ liệu.
df.drop_duplicates(inplace=True)
Giờ ta sẽ thử vizualize cột 'Country' nhé.
sns.countplot(df.Country, order=df.Country.value_counts().index)
plt.xticks(rotation=75)
plt.title('Số lượng sản phẩm theo từng quốc gia')
plt.xlabel('Quốc gia')
plt.ylabel('Số lượng sản phẩm')
plt.show()
Ta có thể thấy có vài quốc gia là một, nhưng do cách viết khác nhau nên thành 2 giá trị khác nhau (USA và United States, Netherlands và Holland), một số không phải quốc gia như (Dubai, Sarawak), UK thì mình sẽ chuyển sang United Kingdom để lát nữa có thể dùng được thư viện 'awoc'.
df['Country'].replace(['USA', 'UK', 'Holland', 'Dubai', 'Sarawak'],
['United States', 'United Kingdom', 'Netherlands', 'United Arab Emirates', 'Malaysia'],
inplace=True)
Nếu để ý thấy ở biểu đồ có Việt Nam . Để đơn giản, mình sẽ tách ra thành DataFrame riêng và clean DataFrame này thôi nhé.
vietnam = df[df['Country'] == 'Vietnam']
len(vietnam.Variety)
>>> 108
Có tới 108 Sản phẩm Mì ở Việt Nam. Ta sẽ cùng xem mỗi Thương hiệu có bao nhiêu sản phẩm mì.
sns.countplot(vietnam.Brand, order=vietnam.Brand.value_counts().index)
plt.title('Số lượng sản phẩm theo thương hiệu')
plt.xlabel('Thương hiệu')
plt.ylabel('Số lượng sản phẩm')
plt.xticks(rotation=75)
plt.show()
Từ đây ta thấy có vài giá trị cần phải sửa, như Acecook chính là Vina Acecook. Saigon Ve Wong là Ve Wong và có Thương hiệu A-One, ta sẽ cho chúng thành A-One. Một số thương hiệu là nhập khẩu hoặc xách tay (vì người đánh giá có thể là ăn được chúng tại Việt Nam nên nghĩ rằng chúng là thương hiệu Việt Nam) như Noah Foods, Unif / Tung-I, Uni-President.
vietnam['Brand'].replace(['Saigon Ve Wong', 'Ve Wong', 'Acecook'], ['A-One', 'A-One', 'Vina Acecook'], inplace=True) vietnam = vietnam[~vietnam['Brand'].isin(['Noah Foods', 'Unif / Tung-I', 'Uni-President'])]
Vizualize lại các sản phẩm theo thương hiệu.
Thêm các tính năng mới.
Việc biết được các tính năng có gì, và cấu trúc ra sao, ràng buộc chúng về cùng một định dạng, mình hoàn toàn có thể tạo ra thêm các tính năng mới cho bộ dữ liệu.
Mình sẽ thêm cột 'Awared' để thể hiện sản phẩm đó đã nằm trong top 10 hay chưa. Rồi sẽ là True, chưa là False.
df['Awared'] = df['Top Ten'].apply(lambda x: True if x != 'No' else False)
Hay với tên quốc gia chuẩn, mình có thể kết hợp được với các thư viện khác một cách dễ dàng, mình dùng thư viện 'awoc' để thêm tính năng cho bộ dữ liệu. Mình sẽ thêm cột 'Continent' theo từng quốc gia.
!pip install awoc
import awoc
my_world = awoc.AWOC() df['Continent'] = df['Country'].apply(lambda x: my_world.get_country_continent_name(x))
Check thử xem đã ổn chưa.
df['Continent'].unique()
Và đây là bộ dữ liệu chúng ta có được sau cùng.
Kết.
Vậy là kết thúc buổi hẹn đầu tiên rồi. Càng dành nhiều thời gian chuẩn bị, ta càng có thể có được cái mình muốn từ "nàng". Khi đã đủ tốt, ta thích nhét cái gì vào cũng đều cho ra kết quả mong đợi, hoặc chí ít cũng không bị fail một cách thảm hại.
Đây chỉ là những bước rất cơ bản để có thể clean dữ liệu, để tiến hành các bước tiếp theo như phân tích, áp dụng model machine learning. Chúng ta cũng có thể dễ dàng thêm các tính năng mới, để thấy được các insight thú vị, cũng như cải thiện độ chính xác cho model. Tuy vậy, vẫn còn rất nhiều việc phải làm với bộ data này.
Nếu mọi người có câu hỏi gì, hay có ý kiến đóng góp xin hãy bình luận bên dưới ạ. Rất mong các anh chị nhận xét, góp ý, và đặc biệt chỉ ra các lỗi sai để em khắc phục. Cảm ơn mọi người đọc tới đây, em xin trân thành cảm ơn ??.
Tài liệu tham khảo
https://towardsdatascience.com/the-ultimate-guide-to-data-cleaning-3969843991d4 https://www.forbes.com/sites/gilpress/2016/03/23/data-preparation-most-time-consuming-least-enjoyable-data-science-task-survey-says/?sh=14918e66f637 https://www.kaggle.com/residentmario/ramen-ratings