19. Sử dụng Seaborn vẽ các biểu đồ thống kê (Phần 1 Numeric variable)

Khi phân tích một bộ dữ liệu, thường thì điều đầu tiên bạn sẽ muốn làm là nhận thức về phân phối của dữ liệu. Ý tưởng chính của Seaborn là nó cung cấp các high-level commands để tạo ra một loạt các loại hình vẽ hữu ích cho việc khai phá dữ liệu thống kê, và thậm chí một số mô hình thống kê phù hợp.

Chúng ta hãy cùng xem xét một số tập dữ liệu và các loại plot có sẵn trong Seaborn. Lưu ý rằng tất cả những điều dưới đây có thể được thực hiện bằng lệnh Matplotlib (thực tế, Seaborn được implement từ matplotlib) nhưng API Seaborn thì tiện lợi hơn nhiều.

Để thuận tiện cho bài, trước hết ta sẽ import đủ các gói sau:

import numpy as np
import pandas as pd
from scipy import stats, integrate
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(color_codes=True)
np.random.seed(sum(map(ord, "distributions")))

Histograms, KDE, and densities

Thông thường khi visualizing dữ liệu thống kê, tất cả những gì bạn muốn là vẽ histograms và join distributions của các biến. Chúng ta đã thấy rằng điều này tương đối đơn giản trong Matplotlib:

Tạo dữ liệu:

data = np.random.multivariate_normal([0, 0], [[10, 2], [2, 2]], size=2000)
data = pd.DataFrame(data, columns=['x', 'y'])

Vẽ qua matplotlib.

for col in 'xy':
    plt.hist(data
	
, normed=True, alpha=0.5) plt.show()

Cách thuận tiện nhất để xem nhanh một phân phối chuẩn một biến trong seaborn là dùng hàm distplot(). Chúng ta có thể có được một đường cong ước lượng (estimation) của phân phối bằng cách sử dụng một ước lượng mật độ hạt nhân (kernel density estimation- KDE)
for col in 'xy':
    sns.distplot(data
	
) plt.show()
 

Phương thức distplot() cũng cấp cho ta một số lựa chon như loại bỏ đường cong KDE, hoặc biểu diễn mật độ xác suất thống kê qua các ticks thẳng đứng. Cấu hình cho KDE ta dùng đối số “kde”, cấu hình cho các ticks ta dùng đối số “rug”. Cụ thể như sau:

Sử dụng KDE, RUG và chỉ dùng 5 bins.

sns.distplot(data['x'], bins = 5, kde=True, rug=True)
plt.show()

Loại bỏ KDE, chỉ dùng RUG và chỉ dùng 5 bins.

sns.distplot(data['x'], bins = 5, kde=False, rug=True)
plt.show()

Hay ta chỉ muốn hiển thị kde (kernel density estimate), và bỏ qua phần hist. Yêu cầu này là chức năng của kdeplot(), tuy nhiên ta có thể chỉ sử dụng distplot()

sns.distplot(data['x'], kde=True, hist = False)
plt.show()

Bạn cũng có thể sử dụng distplot() để fit một kiểu phân bố cho một tập dữ liệu và đánh giá trực quan nó tương ứng như thế nào với dữ liệu được quan sát:

Các bạn có thể thử lần lượt với các kiểu phân bố được liệt tại mục “Continuous distributions” ở link https://docs.scipy.org/doc/scipy/reference/stats.html#module-scipy.stats. Ví dụ:

sns.distplot(data['x'], kde=False, fit=stats.gamma)

plt.show()

Joint distributions

Nó cũng có thể hữu ích để hình dung một phân phối chuẩn hai biến. Cách đơn giản nhất để thực hiện việc này là chỉ sử dụng hàm jointplot(), tạo ra một biểu đồ đa bảng thể hiện đồng thời mối tương quan giữa hai biến cùng với sự phân phối chuẩn,  một biến ứng với mỗi Trục riêng. Ví dụ:

Tạo dữ liệu:

mean, cov = [0, 1], [(1, .5), (.5, 1)]
data = np.random.multivariate_normal(mean, cov, 200)
df = pd.DataFrame(data, columns=["x", "y"])

Phương thức joinplot()

Cách quen thuộc nhất để hình dung một phân phối hai biến (bivariate) là một scatterplot, nơi mỗi quan sát được thể hiện bởi mỗi điểm tại các giá trị x và y. Chúng ta có thể vẽ một scatterplot bằng hàm plt.scatter() trong matplotlib, tuy nhiên khi dùng joinplot(), nó đã là hàm thực thi mặc định của plot trong jointplot() rồi. Chúng ta có thể thay đổi plot qua việc lựa chọn plot qua đối số “kind”: nhận các  giá trị sau: { “scatter” | “reg” | “resid” | “kde” | “hex” }.

Scatter Plots: kind = ‘scatter’. Vì nó là mặc định nên ta không cần cài đặt tường minh.

sns.jointplot(x="x", y="y", data=df);

plt.show()

hexbin plots: là một lựa chọn rất tốt để biểu diễn mật độ dữ liệu thông qua các thùng lục giác vì nó cho thấy số lượng quan sát nằm trong thùng lục giác. Plot này hoạt động tốt nhất với số liệu tương đối lớn. Thư viện matplotlib cũng hố trợ hàm plt.hexbin(), tuy nhiên với seaborn thì thật là đơn giản.
x, y = np.random.multivariate_normal(mean, cov, 1000).T
with sns.axes_style("white"):
    sns.jointplot(x=x, y=y, kind="hex", color="r");

plt.show()

KDE plots: kind = “kde”

sns.jointplot(x="x", y="y", data=df, kind="kde");
plt.show()

Phương thức kdeplot()

Thay vì sử dụng jointplot() như phía trên, kdeplot() là một lựa chọn thứ hai để biểu diễn KDE plots.

Dưới đây là cách dùng kdeplot() và thêm rug để biểu diễn two-dimensional kernel density.

f, ax = plt.subplots(figsize=(6, 6))
sns.kdeplot(df.x, df.y, ax=ax)
sns.rugplot(df.x, color="g", ax=ax)
sns.rugplot(df.y, vertical=True, ax=ax,color='k');
plt.show()

Thay vì chỉ rõ level, hay tô màu theo các định mức như hình trước đây, chúng ta có thể biểu diễn dữ liệu có tính liên tục hơn. Ta dùng kdeplot() kết hợp với bảng màu trong seaborn. Ví dụ:
f, ax = plt.subplots(figsize=(6, 6))
cmap = sns.cubehelix_palette(as_cmap=True, dark=0, light=1, reverse=True)
sns.kdeplot(df.x, df.y, cmap=cmap, n_levels=60, shade=True);

 ​​​​​​​Phương thức plot_join() 
Plot_join() giúp ta đồng thời biểu diễn histogram và các điểm dữ liệu theo cách vẽ scatter trên cùng một đồ thị. Ngoài ra để tạo một joingrid cho toàn hình vẽ ta dùng ax_joint.collections[x].set_alpha(v), với x là chỉ số lớp bắt đầu từ 0 tính từ ngoài vào, các bạn nên thử với nhiều x để hiểu hơn. Ví dụ:
g = sns.jointplot(x="x", y="y", data=df, kind="kde", color="m")

g.plot_joint(plt.scatter, c="w", s=30, linewidth=1, marker="+")
g.ax_joint.collections[0].set_alpha(0)
g.set_axis_labels("$X$", "$Y$");
plt.show()


 ​​​​​​​Kết Luận

Bài học đã giúp các bạn có thể thấy được hiệu quả khi sử dụng Seaborn để vẽ các biểu đồ thống kê so với Matplotlib. Đồng thời bài học cũng giới thiệu đến bạn đọc một số phương thức vô cùng hữu ích như: distplot, joinplot, plot_join trong Seaborn.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *