刚好在做数据挖掘的时候对如何使用分位数处理outliers的问题有所研究,顺便也重新看了一下分位数的含义,所以来做一次比较通俗易懂的解释。(好久远的问题
分位数定义:
对一个有着连续分布函数的样本集X,分位数是将一个概率分布切分为有着相同概率的连续区间的切分点。
用数学公式表达的话:
在我们中学就有过中位数,其实中位数就是一个二分位数,取中位数左边区间的值的概率等于取其右边区间的值的概率。另外在大学的概率论课程中,另一个比较常见的是四分位数,也就是25%,50%,75%这三个切分点。
这里不谈如何求分位数,而是着重于理解其意义。
分位数意义:
表示了在这个样本集中从小至大排列之后小于某值的样本子集占总样本集的比例
那么这个对于我们平常有什么用呢? 就拿我最近在做的数据挖掘的例子来说:
我在分析一个变量时,我会先看看这个变量的分布是不是正常的?有没有outliers?它的总体分布是不是类似于一个正态分布?因为这些特性都需要我们在后面的数据清洗工程中进行对应的修改,比如将outliers的值变得尽量正常以方便模型拟合;如果数据分布类似于高斯分布(正态分布),那么就可以使用LR对其进行拟合。
在初次的处理中,我发现如下情况:
我们可以发现,在这个变量的分布中是有几个比较显眼的outliers的,那么为了使得我们可以更好地捕捉到它们,而不是使用简单粗暴的设置一个较大的值将大于该值的样本删去或者修改。我们可以将它们从小至大进行排列后再观察outliers在总体数据集中的分布位置。如下:
我们可以发现,偏离正常分布的outliers大致上处于数据的前0.5-1.0%与前99.5-100%里面。那么我们使用分位数来修改:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
train_df = pd.read_csv(r'C:\Users\msi\Desktop\Zillow\train_2016_v2.csv',parse_dates = ["transactiondate"])
#对于不规范的日期,在read_csv之后用to_datetime()来转换
plt.figure(figsize=(15,10))
plt.scatter(train_df.index,np.sort(train_df['logerror'].values))
plt.xlabel('index',fontsize=10)
plt.ylabel('logerror',fontsize = 10)
plt.title('Logerror_Distribution',fontsize = 20)
#上面有几个outliers,应该修改
ulimit = np.percentile(train_df.logerror.values,99)
llimit = np.percentile(train_df.logerror.values,1)
train_df.loc[train_df['logerror'] > ulimit,'logerror'] = ulimit
train_df.loc[train_df['logerror'] < llimit,'logerror'] = llimit
我采用了99与1这两个分位数来作为鉴定outliers分布的界限从而进行异常值的修正。这样子的修正可以以更好的准确率来得到我们理想的数据集。
因此我们可以得出分位数对我们最大的意义:可以利用概率分布来为我们确定当数据有序分布后处于某个特殊位置的数值,再利用其为我们达到选择,筛选,修正等目标。
因为我并不是专业的数学系的学生,所以在某些表述上可能有错误,希望大家可以指出,非常感谢。希望能帮助到题主。