Anotasi Outlier pada Seaborn Jointplot

Dengan membuat grafik kumpulan data "tips" sebagai plot gabungan, saya ingin memberi label pada 10 outlier teratas (atau n outlier teratas) pada grafik berdasarkan indeksnya dari kerangka data "tips". Saya menghitung sisa (jarak satu titik dari garis rata-rata) untuk menemukan outlier. Harap abaikan manfaat metode deteksi outlier ini. Saya hanya ingin memberi anotasi pada grafik sesuai spesifikasi.

import seaborn as sns
sns.set(style="darkgrid", color_codes=True)

tips = sns.load_dataset("tips")
model = pd.ols(y=tips.tip, x=tips.total_bill)
tips['resid'] = model.resid

#indices to annotate
tips.sort_values(by=['resid'], ascending=[False]).head(5)

masukkan deskripsi gambar di sini

tips.sort_values(by=['resid'], ascending=[False]).tail(5)

masukkan deskripsi gambar di sini

%matplotlib inline
g = sns.jointplot("total_bill", "tip", data=tips, kind="reg",
                  xlim=(0, 60), ylim=(0, 12), color="r", size=7)

Bagaimana cara memberi anotasi pada 10 outlier teratas (5 sisa terbesar dan 5 sisa terkecil) pada grafik dengan nilai indeks setiap titik (sisa terbesar) untuk mendapatkan ini:

masukkan deskripsi gambar di sini


person Thomas Matthew    schedule 24.03.2017    source sumber


Jawaban (1)


Anda dapat menggunakan matplotlib annotate untuk membuat anotasi pada suatu titik. Idenya adalah untuk mengulangi kerangka data dan menempatkan anotasi pada posisi masing-masing yang diberikan oleh kolom "tip" dan "total_bill".

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

sns.set(style="darkgrid", color_codes=True)

tips = sns.load_dataset("tips")
model = pd.ols(y=tips.tip, x=tips.total_bill)
tips['resid'] = model.resid

g = sns.jointplot("total_bill", "tip", data=tips, kind="reg",
                  xlim=(0, 60), ylim=(0, 12), color="r", size=7)

#indices to annotate
head = tips.sort_values(by=['resid'], ascending=[False]).head(5)

tail = tips.sort_values(by=['resid'], ascending=[False]).tail(5)

def ann(row):
    ind = row[0]
    r = row[1]
    plt.gca().annotate(ind, xy=(r["total_bill"], r["tip"]), 
            xytext=(2,2) , textcoords ="offset points", )

for row in head.iterrows():
    ann(row)
for row in tail.iterrows():
    ann(row)

plt.show()

masukkan deskripsi gambar di sini


Perhatikan bahwa pada pandas versi 0.20 pandas.ols telah dihapus. Untuk menggantinya, seseorang dapat menggunakan Model OLS dari statsmodels. Baris masing-masing kemudian akan berbunyi:

import statsmodels.api as sm
model = sm.OLS(tips.tip, tips.total_bill)
tips['resid'] = model.fit().resid

Perhatikan bahwa hasilnya sedikit berbeda (mungkin karena bobotnya berbeda).

person ImportanceOfBeingErnest    schedule 24.03.2017
comment
menyortir dan memotong iterable head dan tail adalah cara yang bagus untuk mengurangi jumlah iterasi, terutama untuk kerangka data besar seperti kumpulan data saya yang sebenarnya. terima kasih - person Thomas Matthew; 25.03.2017
comment
Saya memperbarui jawabannya dengan solusi untuk panda versi terbaru. - person ImportanceOfBeingErnest; 02.07.2017