Xin chào mọi người hôm nay mình sẽ viết bài về cách lấy thêm tính năng từ bộ dữ liệu Time Series bằng code python. Nào chúng ta cùng bắt đầu thôi.
Trong khi làm việc với dữ liệu Time series, các giá trị của tập dữ liệu có thể bị ảnh hưởng bởi ngày nghỉ lễ, ngày nào trong tuần, số ngày trong tháng. Vậy thì làm sao để chúng ta có thể trích xuất các tính năng này từ Datetime bằng python để có thêm thông tin cho chúng ta đây?
Import và chuẩn bị dữ liệu
Chúng ta sẽ sử dụng tập dữ liệu daily female births dataset. Tập dữ liệu này mô tả số lượng trẻ em gái sinh hàng ngày ở California năm 1959.
Download dữ liệu:
!wget https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv
Sau khi download dữ liệu xong thì chúng ta bắt đầu thôi nào ^^
Việc đầu tiên chắc chắn là đọc và kiểm tra xem dữ liệu như thế nào nhỉ?
import pandas as pd
df = pd.read_csv('daily-total-female-births.csv')\
df.head()
Hình: data của chúng ta đây
Kiểm tra định dạng của dữ liệu:
df.info()
Hình: type của dữ liệu
Như bạn cũng thấy ở hình trên Date ở đây đang là object, vì vậy bây giờ mình sẽ convert hết sang datetime nhé: mình sử dụng pd.to_datetime
df.Date = pd.to_datetime(df.Date)
df.info()
Sau khi đã convert xong thì chúng ta thử kiểm tra xem đã đưa về datetime chưa nhé?
Hình: kiểm tra type df
Ở hình trên chúng ta cũng thấy rằng cột Date đã được convert từ object sang datetime rồi . Bây giờ visualize dữ liệu lên xem nào.
df.set_index('Date').plot()
Hình: visualize cột Date
Trích xuất ngày trong tuần
Thông tin về các ngày trong tuần cũng khá là quan trọng, biết đâu số lượng người sinh ra ở những ngày trong tuần nhiều hơn cuối tuần thì sao nhỉ?
df['weekday'] = df.Date.dt.weekday df.head(10)
Hình: trích xuất ngày trong tuần
Trích xuất Ngày, tháng, năm, quý từ cột Date
Trích xuất Ngày, tháng, năm, quý từ cột Date khá là đơn giản chúng ta chỉ cần dùng dữ liệu của cột Date là xong.
Ngày
Chúng ta có thể trích xuất dữ liệu ngày từ cột Date đơn giản như sau:
df['day'] = df['Date'].dt.day
df[['Date','day']].head()
Hình: day
Tháng
Tương tự với ngày:
df['month'] = df['Date'].dt.month
df[['Date','month']].head()
Hình: month
Năm
Tương tự với ngày và tháng ở trên
df['year'] = df['Date'].dt.year
df[['Date','year']].head()
Hình: year
Quý
Tương tự như trên:
df['quarter'] = df['Date'].dt.quarter
df[['Date','quarter']].head()
Hình: Quarter
Đơn giản phải không nào mọi người
Trích xuất Holidays
Những ngày lễ như năm mới, giáng sinh, ... thì mình nghĩ cũng ít người sinh hơn chăng? Tuy nhiên với một số dữ liệu như giao dịch ở ngân hàng, mua bán các thứ hoặc tiêu thụ điện năng, ... thì những ngày lễ lại ảnh hưởng rất nhiều nên mình cũng áp dụng để trích xuất dữ liệu ngày nghỉ lễ trong tập dữ liệu này.
Mình có sử dụng package holidays của python, thư viện này cung cấp các ngày lễ của nhiều quốc gia trên thế giới. CHúng ta có thể lựa chọn nơi mình muốn lấy dữ liệu này.
pip install holidays
Do dataset này mình sử dụng tập dữ liệu về số lượng trẻ em gái sinh hàng ngày ở California năm 1959. Nên ở đây mình chọn US nhé mọi người.
ca_holidays = holidays.UnitedStates(state='CA')
df['holidays'] = df.Date.apply(lambda x: ca_holidays.get(x))
Dưới đây là các ngày lễ ở California Hình: California holidays
Dữ liệu thu được:
Hình: holidays
Để so sánh số lần sinh giữa ngày lễ và ngày thường, chúng ta sẽ nhóm dữ liệu theo ngày lễ và lấy giá trị trung bình tất cả các lần sinh vào cùng một ngày.
df.holidays = df.holidays.fillna('No holiday') birth_df = df.groupby('holidays').median().reset_index()
birth_df
Hình: số lượng ca sinh trong holidays
Dựa vào hình trên, số trẻ sinh vào ngày Tết là thấp nhất, dường như là số lượng sinh vào các ngày lễ khác khá cao so với số lượng sinh vào các ngày bình thường. Tuy nhiên dữ liệu ngày chỉ có 1 năm nên cũng không đủ để đưa ra kết luận gì cả. Hình: bar chart
Trích xuất số ngày trong tháng
Một số ngày đặc biệt như 29/2 cũng hiếm khi xảy ra, vì vậy có thể số trẻ sinh vào ngày này cực ít. Hoặc nếu chúng ta muốn so sánh số lần sinh giữa các tháng khác nhau, vì vậy số lượng ngày trong 1 tháng cũng ảnh hưởng khá nhiều. Vì vậy chúng ta thử trích xuất dữ liệu này ra nhé. Chúng ta có thể sử dụng thư viện có sẵn của Python là calendar .
from calendar import monthrange first_day_of_month, days_in_a_month = monthrange(2021, 2) print('Weekday of first day of the month:', first_day_of_month)
print('Number of days in month:', days_in_a_month)
Weekday of first day of the month: 0
Number of days in month: 28
Chúng ta test thử với tháng 2 trong 2021 như ở trên.
def extract_month_range(year, month): '''Extract how many days in a month''' first_day_of_month, days_in_a_month = monthrange(int(year), int(month)) return days_in_a_month average_per_month = df.set_index('Date').resample('M').mean() average_per_month['month'] = average_per_month.index.month
average_per_month['year'] = average_per_month.index.year
average_per_month['days_in_a_month'] = average_per_month.apply(lambda row: extract_month_range(row.year, row.month), axis=1)
Hình: average_per_month
Chúng ta có thể vẽ biểu đồ cột Births và month ra để so sánh:
plt.plot(average_per_month.month, average_per_month.Births)
plt.ylabel('Birth')
plt.xlabel('month')
Hình: Birth and month
Ở hình trên chúng ta có thể thấy rằng ở tháng 9 số lượng trẻ em sinh ra là nhiều nhất, do tháng 9 có nhiều ngày hơn chăng? Chúng ta cùng thử vẽ biểu đồ để so sánh nhé
plt.bar(average_per_month.month, average_per_month.days_in_a_month)
plt.ylabel('days_in_a_month')
plt.xlabel('month')
Hình: số ngày trong tháng
Dựa vào hình trên và thực tế chúng ta biết rằng tháng 9 chỉ có 30 ngày thôi mà, trong khi đó tháng 1, 3, 5,... có 31 ngày cơ mà? Vậy là số ngày trong 1 tháng và số lượng trẻ em sinh ra không có mối tương quan trực tiếp rồi. Dù sao thì chúng ta cũng có thêm 1 feature để có thể kết hợp với các feature khác.
Kết luận
Cảm ơn mọi người đã đọc bài viết của mình, hi vọng sẽ hữu ích với mọi người. Nếu có gì sai sót mong nhận được góp ý ạ. Và đừng quên Upvoted cho bài viết của mình nhé ^^.
Reference
https://raw.githubusercontent.com/jbrownlee/Datasets/master/daily-total-female-births.csv
https://towardsdatascience.com/3-ways-to-extract-features-from-dates-927bd89cd5b9