@ 2018-02-08
抽样是一种选择数据对象子集进行分析的常用方法。在统计学中,抽样长期用于数据的实现调查和最终的数据分析;在数据挖掘中,抽样也非常有用。然而在统计学和数据挖掘中,抽样的动机并不相同:统计学使用抽样是因为得到感兴趣的整个数据集的费用太高、太费时间;而数据挖掘使用抽样是因为处理所有的数据的费用费用太高、太费时间。在某些情况下,使用抽样的算法可以压缩数据量,以便可以使用更好但开销较大的数据挖掘算法。
1. 有效抽样
有效抽样的主要原理如下:如果样本是有代表性的,则使用样本与使用整个数据集的效果几乎一样。而样本具有代表性的前提是它近似地具有与原数据集相同的(感兴趣的)性质。抽样本质上是一个统计过程,特定样本的代表性是变化的,因此所能做最好的抽样方案是选择一个确保以很高的概率得到有代表性的样本。
2. 抽样方法
2.1 简单随机抽样
简单随机抽样(Simple Random Sampling)是最简单的抽样方法,此情况下,选取任何特定项的概率相等。随机抽样又有两种变形(其他抽样方法也一样):
- 无放回抽样,每个选中项立即从构成总体的所有对象中删除
- 有放回抽样,对象被选中时不从总体中删除
在有放回抽样中,相同的对象可能被多次抽出,当样本与数据集相比相对较小时,两种方法产生的样本差别不大。但是,对于分析,有放回抽样较为简单,因为在抽样过程中,每个对象被选中的概率保持不变。
def __randomSampling(self,df_index,scale):
try:
len_df_index = len(df_index)
df_index_choice = np.random.choice(df_index, int( len_df_index* scale),p=[1/(len_df_index)]*len_df_index,replace=False)
# print (df_index_choice)
return df_index_choice
except Exception as e:
print (e)
return None
def RandomSampling(self,scale):
"""简单随机抽样"""
df_choice_index = self.__randomSampling(self.df.index,scale)
df_choice = self.df.iloc[df_choice_index,:]
df_not_choice = self.df.iloc[-(self.df.index.isin(df_choice.index))]
return (df_choice,df_not_choice)
2.3 系统抽样
系统抽样又被称机械抽样、等距抽样,先将总体的观察单位按某一顺序号分成 n n 个部分,再从第一部分随机抽取第 号观察单位,依次用相等间距,从每一部分各抽取一个观察单位组成样本。其优点是:易于理解、简便易行;缺点是:总体有周期或增减趋势时,易产生偏性。
def __systematicSampling(self,df_index,scale):
df_index_choice = []
try:
len_df_index = len(df_index)
len_choice = int(len_df_index * scale)
index = 0
k = 1/scale
while len(df_index_choice)<len_choice:
df_index_choice.append(df_index[int(0+index*k) % len_df_index])
index = index + 1
return df_index_choice
except Exception as e:
print (e)
return None
def SystematicSampling(self,scale):
"""系统抽样"""
df_choice_index = self.__systematicSampling(self.df.index,scale)
df_choice = self.df.iloc[df_choice_index,:]
df_not_choice = self.df.iloc[-(self.df.index.isin(df_choice.index))]
return (df_choice,df_not_choice)
2.2 分层抽样
当总体由不同类型的对象组成,每种类型的对象数量差别很大时,简单随机抽样不能充分地代表不太频繁出现的对象类型。当分析需要所有类型的代表时,这种抽样方法会有问题。分层抽样(Stratified Sampling)就是解决这种情况的抽样方法,从预先指定的组开始抽样,在最简单的情况下,尽管每组的大小不同,但是从每组抽取的对象个数相同;另一种变形是从每一组抽取的对象数量正比于该组的大小。
一旦选定抽样方法,就需要选择样本容量,较大的容量会增加样本就有代表性的概率,但同时也抵消了抽样带来的好处;反之,较小的容量会丢失模式或检测出错误的模式。所以如何确定适当的样本容量在抽样中是至关重要的。
先按对观察指标影响较大的某种特征,将总体分为若干个类别,再从每一层内按上述抽样方法抽取一定比例的观察单位,合起来组成样本。
def StratifiedSampling(self,sampling_type,scale):
"""分层抽取样本
Args:
sampling_type: 随机类型,仅支持 rs,rrs,ss,分别是随机抽样,重复随机抽样,系统抽样
scale:抽取样本比例,值域为 (0,1)
"""
df_choice = None
df_values = list(set(self.df_col[0].values))
for i in range(len(df_values)):
df_index = self.df_col[self.df_col[0]==df_values[i]].index
if sampling_type == 'rs':
df_choice_index = self.__randomSampling(df_index,scale)
elif sampling_type == 'rrs':
df_choice_index = self.__repetitionRandomSampling(df_index,scale)
elif sampling_type == 'ss':
df_choice_index = self.__systematicSampling(df_index,scale)
else :
raise Exception('不支持的随机类型。')
if df_choice is None:
df_choice = self.df.iloc[df_choice_index]
else:
df_temp = self.df.iloc[df_choice_index]
df_choice=df_choice.append(df_temp)
df_not_choice = self.df.iloc[-(self.df.index.isin(df_choice.index))]
return (df_choice,df_not_choice)
2.3 渐进抽样
合适的样本容量可能很难确定,因此有时需要使用自适应(Adaptive)或渐进抽样(Progressive Sampling)方法。这些方法从一个小样本开始,然后增加样本容量直到足够容量的样本。如此就不需要在开始就确定正确的样本容量,但需要评估样本的方法以确定它是否足够大。
【后续补上渐进抽样代码】
Reference
1. 《数据挖掘导论第2章》