我也在为此苦苦挣扎,并且不想使用,因为它可能会产生误导,所以我写了一个小函数(从this.clip()
大量借用)来表明上部和下部 bin 包含异常值:
def outlier_aware_hist(data, lower=None, upper=None):
if not lower or lower < data.min():
lower = data.min()
lower_outliers = False
else:
lower_outliers = True
if not upper or upper > data.max():
upper = data.max()
upper_outliers = False
else:
upper_outliers = True
n, bins, patches = plt.hist(data, range=(lower, upper), bins='auto')
if lower_outliers:
n_lower_outliers = (data < lower).sum()
patches[0].set_height(patches[0].get_height() + n_lower_outliers)
patches[0].set_facecolor('c')
patches[0].set_label('Lower outliers: ({:.2f}, {:.2f})'.format(data.min(), lower))
if upper_outliers:
n_upper_outliers = (data > upper).sum()
patches[-1].set_height(patches[-1].get_height() + n_upper_outliers)
patches[-1].set_facecolor('m')
patches[-1].set_label('Upper outliers: ({:.2f}, {:.2f})'.format(upper, data.max()))
if lower_outliers or upper_outliers:
plt.legend()
您还可以将其与自动异常值检测器(从此处借用)结合起来,如下所示:
def mad(data):
median = np.median(data)
diff = np.abs(data - median)
mad = np.median(diff)
return mad
def calculate_bounds(data, z_thresh=3.5):
MAD = mad(data)
median = np.median(data)
const = z_thresh * MAD / 0.6745
return (median - const, median + const)
outlier_aware_hist(data, *calculate_bounds(data))