Chuyển đến nội dung chính

Hướng dẫn Kaggle: EDA & Machine Learning

Trong hướng dẫn Kaggle này, bạn sẽ học cách tiếp cận và xây dựng các mô hình học có giám sát với sự hỗ trợ của phân tích dữ liệu thăm dò (EDA) trên dữ liệu Titanic.
· 10 phút đọc

Khám phá cùng AI

Đầu tháng này, tôi đã thực hiện một buổi Facebook Live Code Along, trong đó tôi (và mọi người cùng lập trình theo) xây dựng một số thuật toán với độ phức tạp tăng dần để dự đoán liệu một hành khách bất kỳ trên tàu Titanic có sống sót hay không, dựa trên dữ liệu như giá vé họ đã trả, nơi họ lên tàu và tuổi của họ.

Trong bài viết này, bạn sẽ xem lại một số nội dung chúng ta đã đề cập trong buổi đó. Nếu muốn xem lại hoặc theo dõi bài viết này cùng với video, bạn có thể xem tại đây:

Đặc biệt, bạn có thể vẫn nhớ rằng chúng ta đã xây dựng các mô hình học có giám sát.

Học có giám sát là nhánh của Machine Learning (ML) liên quan đến việc dự đoán nhãn, chẳng hạn như "Sống sót" hoặc "Không". Những mô hình này học từ dữ liệu đã gắn nhãn, tức là dữ liệu bao gồm việc hành khách có sống sót hay không (gọi là "huấn luyện mô hình"), rồi sau đó dự đoán trên dữ liệu chưa gắn nhãn.

Trên Kaggle, một nền tảng cho các cuộc thi mô hình dự đoán và phân tích, chúng được gọi là tập huấn luyện và tập kiểm tra vì

  • Bạn muốn xây dựng một mô hình học được các mẫu trong tập huấn luyện, và
  • Sau đó dùng mô hình để đưa ra dự đoán trên tập kiểm tra.

Sau đó Kaggle cho bạn biết tỷ lệ bạn dự đoán đúng: đây được gọi là độ chính xác (accuracy) của mô hình.

Bắt đầu với Học có Giám sát như thế nào

Như bạn có thể đã biết, một cách tiếp cận tốt cho học có giám sát là như sau:

  • Thực hiện Phân tích Dữ liệu Thăm dò (EDA) trên bộ dữ liệu của bạn;
  • Xây dựng một mô hình nhanh và đơn giản, hay mô hình chuẩn (baseline), để làm mốc so sánh với các mô hình sau này bạn sẽ xây dựng;
  • Lặp lại quy trình này. Bạn sẽ EDA thêm và xây dựng một mô hình khác;
  • Thiết kế đặc trưng (feature engineering): lấy các đặc trưng sẵn có và kết hợp chúng hoặc trích xuất thêm thông tin để cuối cùng đi đến điểm cuối cùng, đó là
  • Có được một mô hình hoạt động tốt hơn.

Trong buổi code along này, bạn đã hoặc sẽ làm tất cả các bước trên!

Lưu ý chúng tôi cũng có các khóa học giúp bạn bắt đầu với machine learning cho bộ dữ liệu Titanic bằng Python và R.

Nhập Dữ liệu và Khám phá Nhanh

Bước đầu tiên luôn là nhập dữ liệu để nhanh chóng xem qua dữ liệu bạn sẽ làm việc. Trong trường hợp này, bạn sẽ nhập gói pandas và dùng hàm read_csv() để đọc dữ liệu:

Lưu ý rằng trong các khối mã bên dưới, những gói và module khác như matplotlib, sklearn và seaborn đã được nhập sẵn. Bạn sẽ dùng chúng nhiều hơn sau này cho việc trực quan hóa dữ liệu (thống kê) và mục đích machine learning!

Bạn cũng sử dụng lệnh magic của IPython %matplotlib inline để các biểu đồ hiển thị ngay trong notebook. Bạn thêm sns.set() để đổi phong cách trực quan hóa về phong cách Seaborn cơ bản:

# Import modules
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import tree
from sklearn.metrics import accuracy_score

# Figures inline and set visualization style
%matplotlib inline
sns.set()

Không chần chừ nữa, hãy nhập dữ liệu và thực hiện bước đầu tiên trong việc kiểm tra dữ liệu:

# Import test and train datasets
df_train = pd.read_csv('../data/train.csv')
df_test = pd.read_csv('../data/test.csv')

# View first lines of training data
df_train.head(n=4)
 PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S

Nếu bạn muốn xem tất cả các đặc trưng này là gì, hãy tham khảo tài liệu dữ liệu Kaggle tại đây.

Trước khi tiếp tục, sẽ hữu ích nếu lưu ý một số thuật ngữ sau:

  • Biến mục tiêu là biến bạn cố gắng dự đoán;
  • Các biến khác được gọi là "đặc trưng" (hoặc "biến dự đoán", là những đặc trưng bạn dùng để dự đoán biến mục tiêu).

Với điều này trong đầu, bạn có thể tiếp tục khám phá dữ liệu với, chẳng hạn, hàm head(), dùng để lấy ra năm hàng đầu tiên của bộ dữ liệu:

# View first lines of test data
df_test.head()
 PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
08923Kelly, Mr. Jamesmale34.5003309117.8292NaNQ
18933Wilkes, Mrs. James (Ellen Needs)female47.0103632727.0000NaNS
28942Myles, Mr. Thomas Francismale62.0002402769.6875NaNQ
38953Wirz, Mr. Albertmale27.0003151548.6625NaNS
48963Hirvonen, Mrs. Alexander (Helga E Lindqvist)female22.011310129812.2875NaNS

Lưu ý rằng DataFrame df_test không có cột 'Survived' vì đây chính là thứ bạn sẽ cố gắng dự đoán!

  • Bạn cũng có thể dùng phương thức DataFrame .info() để xem kiểu dữ liệu, giá trị khuyết và hơn thế nữa (của df_train).
df_train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId    891 non-null int64
Survived       891 non-null int64
Pclass         891 non-null int64
Name           891 non-null object
Sex            891 non-null object
Age            714 non-null float64
SibSp          891 non-null int64
Parch          891 non-null int64
Ticket         891 non-null object
Fare           891 non-null float64
Cabin          204 non-null object
Embarked       889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB

Trong trường hợp này, bạn thấy chỉ có 714 giá trị không null cho cột 'Age' trong một DataFrame có 891 hàng. Điều này có nghĩa là có 177 giá trị null hoặc bị thiếu.

  • Ngoài ra, dùng phương thức DataFrame .describe() để xem thống kê tóm tắt của các cột số (của df_train).
df_train.describe()
 PassengerIdSurvivedPclassAgeSibSpParchFare
count891.000000891.000000891.000000714.000000891.000000891.000000891.000000
mean446.0000000.3838382.30864229.6991180.5230080.38159432.204208
std257.3538420.4865920.83607114.5264971.1027430.80605749.693429
min1.0000000.0000001.0000000.4200000.0000000.0000000.000000
25%223.5000000.0000002.00000020.1250000.0000000.0000007.910400
50%446.0000000.0000003.00000028.0000000.0000000.00000014.454200
75%668.5000001.0000003.00000038.0000001.0000000.00000031.000000
max891.0000001.0000003.00000080.0000008.0000006.000000512.329200

EDA trực quan và Mô hình đầu tiên của bạn

Bây giờ bạn đã có hình dung về dữ liệu và đã xem qua một số thống kê, đã đến lúc trực quan hóa dữ liệu với gói seaborn:

  • Ví dụ, dùng seaborn để vẽ biểu đồ cột về sống sót trên Titanic, đây là biến mục tiêu của bạn.
sns.countplot(x='Survived', data=df_train);

bar chart

Kết luận: trong tập huấn luyện, số người sống sót ít hơn số người không sống sót. Vậy hãy xây dựng mô hình đầu tiên dự đoán rằng không ai sống sót.

Đây là một mô hình tệ vì bạn biết là có người sống sót. Nhưng nó cho ta một mốc chuẩn: bất kỳ mô hình nào xây sau này cần làm tốt hơn mô hình này.

Bạn có thể làm như sau:

  • Tạo cột 'Survived' cho df_test mã hóa "không sống sót" cho tất cả các hàng;
  • Lưu các cột 'PassengerId' và 'Survived' của df_test ra .csv và nộp lên Kaggle.
df_test['Survived'] = 0
df_test[['PassengerId', 'Survived']].to_csv('data/predictions/no_survivors.csv', index=False)

Độ chính xác mô hình này cho bạn là bao nhiêu? Độ chính xác trên Kaggle là 62.7.

kaggle

Không quá tệ!

Lưu ý quan trọng! Bạn cũng sẽ muốn dùng các độ đo khác ngoài accuracy!

EDA trên các biến đặc trưng

Sau khi đã có một mô hình nhanh-gọn, đã đến lúc lặp lại: hãy làm EDA thêm và sớm xây dựng một mô hình khác!

  • Bạn có thể dùng seaborn để vẽ biểu đồ cột cho đặc trưng 'Sex' của bộ dữ liệu Titanic (của df_train).
sns.countplot(x='Sex', data=df_train);

bar plot

  • Đồng thời, dùng seaborn để vẽ các biểu đồ cột của đặc trưng 'Survived' được chia (facet) theo đặc trưng 'Sex'.
sns.factorplot(x='Survived', col='Sex', kind='count', data=df_train);

bar plot

Kết luận: Phụ nữ có khả năng sống sót cao hơn nam giới.

  • Với kết luận này, bạn có thể dùng pandas để xem có bao nhiêu phụ nữ và bao nhiêu đàn ông đã sống sót:
df_train.groupby(['Sex']).Survived.sum()
Sex
female    233
male      109
Name: Survived, dtype: int64
  • Dùng pandas để tính tỷ lệ phụ nữ sống sót và tỷ lệ đàn ông sống sót:
print(df_train[df_train.Sex == 'female'].Survived.sum()/df_train[df_train.Sex == 'female'].Survived.count())
print(df_train[df_train.Sex == 'male'].Survived.sum()/df_train[df_train.Sex == 'male'].Survived.count())
0.742038216561
0.188908145581

74% phụ nữ sống sót, trong khi 19% nam giới sống sót.

Giờ hãy xây dựng mô hình thứ hai và dự đoán rằng tất cả phụ nữ đều sống sót còn tất cả đàn ông thì không. Một lần nữa, đây là mô hình thiếu thực tế, nhưng nó sẽ cung cấp mốc chuẩn để so sánh với các mô hình sau.

  • Tạo cột 'Survived' cho df_test mã hóa dự đoán trên.
  • Lưu các cột 'PassengerId' và 'Survived' của df_test ra .csv và nộp lên Kaggle.
df_test['Survived'] = df_test.Sex == 'female'
df_test['Survived'] = df_test.Survived.apply(lambda x: int(x))
df_test.head()
 PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarkedSurvived
08923Kelly, Mr. Jamesmale34.5003309117.8292NaNQ0
18933Wilkes, Mrs. James (Ellen Needs)female47.0103632727.0000NaNS1
28942Myles, Mr. Thomas Francismale62.0002402769.6875NaNQ0
38953Wirz, Mr. Albertmale27.0003151548.6625NaNS0
48963Hirvonen, Mrs. Alexander (Helga E Lindqvist)female22.011310129812.2875NaNS1
df_test[['PassengerId', 'Survived']].to_csv('../data/predictions/women_survive.csv', index=False)

Vậy, khi bạn nộp mô hình này lên Kaggle thì độ chính xác là bao nhiêu?

Độ chính xác trên Kaggle là 76.6%:

kaggle

Với lần nộp này, bạn đã tăng khoảng 2.000 bậc trên bảng xếp hạng! Đồng thời, bạn đã cải thiện điểm số, vậy là làm rất tốt!

Khám phá Dữ liệu thêm nữa!

  • Dùng seaborn để vẽ các biểu đồ cột của đặc trưng 'Survived' được chia (facet) theo đặc trưng 'Pclass' của bộ dữ liệu Titanic.
sns.factorplot(x='Survived', col='Pclass', kind='count', data=df_train);

bar plot

Kết luận: Hành khách đi hạng nhất có khả năng sống sót cao hơn. Ngược lại, hành khách đi hạng ba ít có khả năng sống sót.

  • Dùng seaborn để vẽ các biểu đồ cột của đặc trưng 'Survived' được chia (facet) theo đặc trưng 'Embarked'.
sns.factorplot(x='Survived', col='Embarked', kind='count', data=df_train);

bar plot

Kết luận: Hành khách lên tàu tại Southampton ít có khả năng sống sót hơn.

EDA với các biến số

  • Dùng seaborn để vẽ biểu đồ tần suất cho cột 'Fare' của df_train.
sns.distplot(df_train.Fare, kde=False);

histogram

Kết luận: Phần lớn hành khách trả dưới 100 cho chuyến đi trên Titanic.

  • Dùng phương thức vẽ của pandas để vẽ cột 'Fare' cho từng giá trị của 'Survived' trên cùng một biểu đồ.
df_train.groupby('Survived').Fare.hist(alpha=0.6);

bar plot

Kết luận: Có vẻ như những người trả nhiều tiền hơn có cơ hội sống sót cao hơn.

  • Dùng seaborn để vẽ biểu đồ tần suất của cột 'Age' trong df_train. Bạn cần loại bỏ giá trị null trước khi vẽ.
df_train_drop = df_train.dropna()
sns.distplot(df_train_drop.Age, kde=False);

histogram

  • Vẽ strip plot và swarm plot của 'Fare' với 'Survived' trên trục x.
sns.stripplot(x='Survived', y='Fare', data=df_train, alpha=0.3, jitter=True);

strip plot

sns.swarmplot(x='Survived', y='Fare', data=df_train);

swarm plot

Kết luận: Giá vé rõ ràng có tương quan với khả năng sống sót trên Titanic.

  • Dùng phương thức DataFrame .describe() để xem thống kê tóm tắt của 'Fare' theo tình trạng sống sót.
df_train.groupby('Survived').Fare.describe()
 countmeanstdmin25%50%75%max
Survived        
0549.022.11788731.3882070.07.854210.526.0263.0000
1342.048.39540866.5969980.012.475026.057.0512.3292
  • Dùng seaborn để vẽ biểu đồ scatter giữa 'Age' và 'Fare', tô màu theo 'Survived'.
sns.lmplot(x='Age', y='Fare', hue='Survived', data=df_train, fit_reg=False, scatter_kws={'alpha':0.5});

scatter plot

Kết luận: Có vẻ những người sống sót hoặc là trả khá nhiều tiền cho vé hoặc là còn trẻ.

  • Dùng seaborn để tạo pairplot của df_train, tô màu theo 'Survived'. Pairplot là cách tuyệt vời để hiển thị hầu hết thông tin bạn đã phát hiện trong một lưới biểu đồ duy nhất.
sns.pairplot(df_train_drop, hue='Survived');

plots

Từ EDA đến Mô hình Machine Learning

Trong hướng dẫn này, bạn đã thành công:

  • tải dữ liệu và xem qua.
  • khám phá trực quan biến mục tiêu và đưa ra dự đoán đầu tiên.
  • khám phá trực quan một số biến đặc trưng và đưa ra nhiều dự đoán tốt hơn dựa trên EDA.
  • thực hiện EDA chuyên sâu với các biến đặc trưng, cả phân loại và số.

Trong bài tiếp theo, bạn sẽ dành thời gian xây dựng một số mô hình Machine Learning, dựa trên những gì bạn đã học từ EDA ở đây. Chúng ta sẽ làm điều này trong bài tiếp theo của dự án (ra mắt vào ngày 27 tháng 12).

Chủ đề

Liên quan