简介
拟合优度检验是一类对于数据是否为正态分布没有要求的检验方法,通过这种方法可以对非正态分布的数据进行检验,同样也能对正态分布的数据进行检验。检验原理如下:
1)将得到的数据进行按区间划分。
2)得到数据按区间划分的频数分布表,并将区间标准化。
3)计算各区间按标准正态分布对于的期望频率,通过这一期望频率得到期望频数fe。
4)计算chi-square。
5)对比显著度的临界值,如果大于则确定数据不符合正态分布,如果小于则确定数据在该显著度符合正态分布。
具体步骤可按下表进行:
通过python编写,代码如下:
#利用频率检验数据分布是否为正态分布def test_for_normility(data, c, sig):mean = data.mean()n = len(data)std = data.var()*(n/(n-1))data_g = data.groupby(pd.cut(data.iloc[:,0], c)).count()data_g.rename(columns = {0:'count'},inplace = True)data_g['left'] = (data_g.index.categories.left-float(mean))/float(std)data_g['right'] = (data_g.index.categories.right-float(mean))/float(std)data_g['fe'] = stats.norm.cdf(data_g['right'])- stats.norm.cdf(data_g['left'])under = 'under'+str(data_g.index.categories[0].left)up = 'up'+ str(data_g.index.categories[c-1].right)index = ['under'+str(data_g.index.categories[0].left)]+list(data_g.index)+['up'+ str(data_g.index.categories[c-1].right)]data_g2 = data_g.reindex(index)data_g2.loc[under, 'fe']= stats.norm.cdf(data_g.loc[data_g.index[0], 'left'])data_g2.loc[up, 'fe']= stats.norm.sf(data_g.loc[data_g.index[c-1], 'right'])data_g2.loc[under,'count'] = 0data_g2.loc[up,'count'] = 0data_t = data_g2.loc[:,['count', 'fe']]df = c+1data_t['chi_square'] = ((n*data_t['fe'] - data_t['count'])**2)/(n*data_t['fe'])chi_square = data_t['chi_square'].sum()p = stats.chi2.sf(chi_square,df)result = pd.DataFrame(index = [ 'df', 'chi_square', 'p_value'], columns = ['result'])result['result'] = [df,chi_square, p]if p<sig:print('在显著度为'+str(sig)+'下, 认为该组数据不服从正态分布')else:print('在显著度为'+str(sig)+'下,认为该组数据服从正态分布')return data_g2, result
其中c为分组的数量,sig为显著度。通过利用python生成一组随机正态分布数据测试结果如下:
通过利用python生成一组随机均匀分布数据测试结果如下:
通过上述结果可以确定代码的正确性。但是这种方法存在着一定的缺陷,当数据量很小时,测试的准确性会因为随机误差降低,结果变得不可靠。并且分组数也会影响结果,分组数一般按照2的k次方的准则进行分组,及2k<= n <2k+1 其中n为数据量。
测试如下检测20个数据的正态性时:
从图中可以看出我利用的是均匀分布进行检验,但结果依旧为符合正态分布,因为分组数不合理且数据量过小。
当分组数为变为5后又能正确的判断数据的的分布。