Vẽ ma trận tương quan bằng cách sử dụng gấu trúc


211

Tôi có một bộ dữ liệu với số lượng lớn các tính năng, vì vậy việc phân tích ma trận tương quan đã trở nên rất khó khăn. Tôi muốn vẽ một ma trận tương quan mà chúng ta có được bằng cách sử dụng dataframe.corr()hàm từ thư viện gấu trúc. Có bất kỳ chức năng tích hợp nào được cung cấp bởi thư viện gấu trúc để vẽ ma trận này không?


Các câu trả lời liên quan có thể được tìm thấy ở đây Tạo bản đồ nhiệt từ gấu trúc DataFrame
joelostblom

Câu trả lời:


291

Bạn có thể sử dụng pyplot.matshow() từ matplotlib:

import matplotlib.pyplot as plt

plt.matshow(dataframe.corr())
plt.show()

Biên tập:

Trong các ý kiến ​​là một yêu cầu về cách thay đổi nhãn đánh dấu trục. Đây là phiên bản cao cấp được vẽ trên kích thước hình lớn hơn, có nhãn trục để khớp với khung dữ liệu và chú thích thanh màu để diễn giải thang màu.

Tôi bao gồm cách điều chỉnh kích thước và độ xoay của nhãn và tôi đang sử dụng tỷ lệ hình làm cho thanh màu và hình chính có cùng chiều cao.

f = plt.figure(figsize=(19, 15))
plt.matshow(df.corr(), fignum=f.number)
plt.xticks(range(df.shape[1]), df.columns, fontsize=14, rotation=45)
plt.yticks(range(df.shape[1]), df.columns, fontsize=14)
cb = plt.colorbar()
cb.ax.tick_params(labelsize=14)
plt.title('Correlation Matrix', fontsize=16);

ví dụ cốt truyện tương quan


1
Tôi phải thiếu một cái gì đó:AttributeError: 'module' object has no attribute 'matshow'
Tom Russell

1
@TomRussell Bạn đã làm gì import matplotlib.pyplot as plt?
joelostblom

1
Tôi muốn nghĩ rằng tôi đã làm! :-)
Tom Russell

7
Bạn có biết làm thế nào để hiển thị tên cột thực tế trên cốt truyện?
WebQube

2
@Cecilia Tôi đã giải quyết vấn đề này bằng cách thay đổi tham số xoay thành 90
ikbel benabdessamad

182

Nếu mục tiêu chính của bạn là trực quan hóa ma trận tương quan, thay vì tạo ra một âm mưu, thì các pandas tùy chọn kiểu dáng thuận tiện là một giải pháp tích hợp khả thi:

import pandas as pd
import numpy as np

rs = np.random.RandomState(0)
df = pd.DataFrame(rs.rand(10, 10))
corr = df.corr()
corr.style.background_gradient(cmap='coolwarm')
# 'RdBu_r' & 'BrBG' are other good diverging colormaps

nhập mô tả hình ảnh ở đây

Lưu ý rằng điều này cần phải có trong phần phụ trợ hỗ trợ kết xuất HTML, chẳng hạn như Notebook JupyterLab. (Văn bản ánh sáng tự động trên nền tối là từ PR hiện có và không phải là phiên bản phát hành mới nhất, pandas0,23).


Tạo kiểu

Bạn có thể dễ dàng giới hạn độ chính xác của chữ số:

corr.style.background_gradient(cmap='coolwarm').set_precision(2)

nhập mô tả hình ảnh ở đây

Hoặc loại bỏ các chữ số hoàn toàn nếu bạn thích ma trận mà không có chú thích:

corr.style.background_gradient(cmap='coolwarm').set_properties(**{'font-size': '0pt'})

nhập mô tả hình ảnh ở đây

Tài liệu về kiểu dáng cũng bao gồm các hướng dẫn về các kiểu nâng cao hơn, chẳng hạn như cách thay đổi hiển thị của ô mà con trỏ chuột đang di chuột qua. Để lưu kết quả đầu ra, bạn có thể trả về HTML bằng cách nối thêm render()phương thức và sau đó ghi nó vào một tệp (hoặc chỉ chụp ảnh màn hình cho các mục đích ít chính thức hơn).


So sánh thời gian

Trong thử nghiệm của tôi, style.background_gradient()nhanh hơn gấp 4 lần plt.matshow()và nhanh hơn 120 lần so sns.heatmap()với ma trận 10x10. Thật không may, nó không mở rộng quy mô cũng như plt.matshow(): cả hai mất khoảng thời gian giống nhau cho ma trận 100x100 và plt.matshow()nhanh hơn gấp 10 lần đối với ma trận 1000x1000.


Tiết kiệm

Có một số cách có thể để lưu khung dữ liệu cách điệu:

  • Trả về HTML bằng cách nối thêm render()phương thức và sau đó ghi kết quả đầu ra vào một tệp.
  • Lưu dưới dạng .xslxtệp có định dạng có điều kiện bằng cách nối thêm to_excel()phương thức.
  • Kết hợp với imgkit để lưu một bitmap
  • Chụp ảnh màn hình (cho các mục đích ít chính thức hơn).

Cập nhật cho gấu trúc> = 0,24

Bằng cách cài đặt axis=None, giờ đây có thể tính toán các màu dựa trên toàn bộ ma trận thay vì trên mỗi cột hoặc mỗi hàng:

corr.style.background_gradient(cmap='coolwarm', axis=None)

nhập mô tả hình ảnh ở đây


2
Nếu có một cách để xuất khẩu như một hình ảnh, đó sẽ là tuyệt vời!
Kristada673

1
Cảm ơn! Bạn chắc chắn cần một bảng màu phân kỳimport seaborn as sns corr = df.corr() cm = sns.light_palette("green", as_cmap=True) cm = sns.diverging_palette(220, 20, sep=20, as_cmap=True) corr.style.background_gradient(cmap=cm).set_precision(2)
stallingOne

1
@stallingOne Điểm hay, tôi không nên đưa các giá trị âm vào ví dụ, tôi có thể thay đổi điều đó sau. Chỉ để tham khảo cho những người đọc nó, bạn không cần phải tạo một cmap phân kỳ tùy chỉnh với seaborn (mặc dù cái trong nhận xét ở trên trông khá lắt léo), bạn cũng có thể sử dụng các cmp phân kỳ tích hợp từ matplotlib, ví dụ corr.style.background_gradient(cmap='coolwarm'). Hiện tại không có cách nào để căn giữa cmap trên một giá trị cụ thể, đó có thể là một ý tưởng tốt với các cmaps khác nhau.
joelostblom

1
@rovyko Bạn có trên gấu trúc> = 0.24.0?
joelostblom

2
Các lô này rất trực quan, nhưng câu hỏi @ Kristada673 khá phù hợp, bạn sẽ xuất chúng như thế nào?
Erfan

89

Hãy thử chức năng này, cũng hiển thị tên biến cho ma trận tương quan:

def plot_corr(df,size=10):
    '''Function plots a graphical correlation matrix for each pair of columns in the dataframe.

    Input:
        df: pandas DataFrame
        size: vertical and horizontal size of the plot'''

    corr = df.corr()
    fig, ax = plt.subplots(figsize=(size, size))
    ax.matshow(corr)
    plt.xticks(range(len(corr.columns)), corr.columns);
    plt.yticks(range(len(corr.columns)), corr.columns);

6
plt.xticks(range(len(corr.columns)), corr.columns, rotation='vertical')nếu bạn muốn định hướng thẳng đứng của tên cột trên trục x
Nishant

Một điều đồ họa khác, nhưng thêm một plt.tight_layout()cũng có thể hữu ích cho các tên cột dài.
dùng4957048

86

Phiên bản bản đồ nhiệt của Seaborn:

import seaborn as sns
corr = dataframe.corr()
sns.heatmap(corr, 
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values)

9
Seamap Heatmap là lạ mắt nhưng nó thực hiện kém trên ma trận lớn. phương pháp matshow của matplotlib nhanh hơn nhiều.
anilbey

3
Seaborn có thể tự động suy ra các ticklabels từ tên cột.
Tulio Casagrande

80

Bạn có thể quan sát mối quan hệ giữa các tính năng bằng cách vẽ bản đồ nhiệt từ ma trận biển hoặc ma trận tán xạ từ gấu trúc.

Ma trận phân tán:

pd.scatter_matrix(dataframe, alpha = 0.3, figsize = (14,8), diagonal = 'kde');

Nếu bạn cũng muốn hình dung độ lệch của từng tính năng - hãy sử dụng các cặp đôi đi biển.

sns.pairplot(dataframe)

Sơ đồ nhiệt của Sns:

import seaborn as sns

f, ax = pl.subplots(figsize=(10, 8))
corr = dataframe.corr()
sns.heatmap(corr, mask=np.zeros_like(corr, dtype=np.bool), cmap=sns.diverging_palette(220, 10, as_cmap=True),
            square=True, ax=ax)

Đầu ra sẽ là một bản đồ tương quan của các tính năng. tức là xem ví dụ dưới đây.

nhập mô tả hình ảnh ở đây

Mối tương quan giữa tạp hóa và chất tẩy rửa là cao. Tương tự:

Pdoducts với tương quan cao:
  1. Tạp hóa và chất tẩy rửa.
Sản phẩm có tương quan trung bình:
  1. Sữa và tạp hóa
  2. Sữa và chất tẩy rửa
Sản phẩm có tương quan thấp:
  1. Sữa và thức ăn nhanh
  2. Đông lạnh và tươi.
  3. Đông lạnh và Deli.

Từ Pairplots: Bạn có thể quan sát cùng một tập hợp các mối quan hệ từ các cặp hoặc ma trận phân tán. Nhưng từ những điều này, chúng ta có thể nói rằng liệu dữ liệu có được phân phối bình thường hay không.

nhập mô tả hình ảnh ở đây

Lưu ý: Trên đây là cùng một biểu đồ được lấy từ dữ liệu, được sử dụng để vẽ sơ đồ nhiệt.


3
Tôi nghĩ rằng nó nên là .plt không .pl (nếu điều này đề cập đến matplotlib)
ghukill

2
@ghukill Không cần thiết. Anh ta có thể gọi nó làfrom matplotlib import pyplot as pl
Jeru Luke

làm cách nào để đặt ranh giới của mối tương quan giữa -1 đến +1 luôn, trong biểu đồ tương quan
debaonline4u

7

Bạn có thể sử dụng phương thức imshow () từ matplotlib

import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('ggplot')

plt.imshow(X.corr(), cmap=plt.cm.Reds, interpolation='nearest')
plt.colorbar()
tick_marks = [i for i in range(len(X.columns))]
plt.xticks(tick_marks, X.columns, rotation='vertical')
plt.yticks(tick_marks, X.columns)
plt.show()

5

Nếu dataframe là dfbạn chỉ cần sử dụng:

import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(15, 10))
sns.heatmap(df.corr(), annot=True)

3

đồ họa statmodels cũng cho một cái nhìn tốt đẹp về ma trận tương quan

import statsmodels.api as sm
import matplotlib.pyplot as plt

corr = dataframe.corr()
sm.graphics.plot_corr(corr, xnames=list(corr.columns))
plt.show()

2

Để hoàn thiện, giải pháp đơn giản nhất mà tôi biết với seaborn vào cuối năm 2019, nếu một người đang sử dụng Jupyter :

import seaborn as sns
sns.heatmap(dataframe.corr())

1

Cùng với các phương pháp khác, cũng tốt khi có cặp đôi sẽ đưa ra biểu đồ phân tán cho tất cả các trường hợp-

import pandas as pd
import numpy as np
import seaborn as sns
rs = np.random.RandomState(0)
df = pd.DataFrame(rs.rand(10, 10))
sns.pairplot(df)

0

Ma trận tương quan biểu mẫu, trong trường hợp của tôi zdf là khung dữ liệu mà tôi cần thực hiện ma trận tương quan.

corrMatrix =zdf.corr()
corrMatrix.to_csv('sm_zscaled_correlation_matrix.csv');
html = corrMatrix.style.background_gradient(cmap='RdBu').set_precision(2).render()

# Writing the output to a html file.
with open('test.html', 'w') as f:
   print('<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-widthinitial-scale=1.0"><title>Document</title></head><style>table{word-break: break-all;}</style><body>' + html+'</body></html>', file=f)

Sau đó chúng ta có thể chụp ảnh màn hình. hoặc chuyển đổi html thành một tập tin hình ảnh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.