如何通过Kolmogorov-Smirnov检验(KS检验)使用适当的规范化来获得正确的p_values和ks_values?

时间:2018-08-13 08:32:20

标签: python pandas numpy finance kolmogorov-smirnov

我正在研究财务问题,我要实现一个功能,以便在每种股票的信号收益的正态分布之间使用Kolmogorov-Smirnov检验(KS检验)。我将针对每只股票的信号收益按正态分布运行KS测试,对于该测试,我将使用scipy.stats.kstest进行KS测试。

  • 建议我迭代groupby函数
  • 我只需要使用熊猫,numpy和scipy。

我的功能如下:

def calculate_kstest(long_short_signal_returns):
"""
Calculate the KS-Test against the signal returns with a long or short signal.

Parameters
----------
long_short_signal_returns : DataFrame
    The signal returns which have a signal.
    This DataFrame contains two columns, "ticker" and "signal_return"

Returns
-------
ks_values : Pandas Series
    KS static for all the tickers
p_values : Pandas Series
    P value for all the tickers
"""
#TODO: Implement function
ks_v = []
p_v = []
#print(long_short_signal_returns)
column = []
df = long_short_signal_returns.copy()
print(df)

#df['signal_return'] = (df['signal_return'] - df['signal_return'].mean()) / (df['signal_return'].max() - df['signal_return'].min())

for name, group in df.groupby('ticker'):
    sub_group = group['signal_return'].values
    ks,p = kstest(sub_group,'norm')

    ks_v.append(ks)
    p_v.append(p)
    column.append(name)
ks_values = pd.Series(ks_v,column)
p_values = pd.Series(p_v, column)


return ks_values, p_values

但是,我的答案与预期的输出不匹配。

输入为:

INPUT long_short_signal_returns:
    signal_return ticker
0      0.12000000   DNTM
1     -0.83000000    EHX
2      0.37000000   VWER
3      0.83000000   DNTM
4     -0.34000000    EHX
5      0.27000000   VWER
6     -0.68000000   DNTM
7      0.29000000    EHX
8      0.69000000   VWER
9      0.57000000   DNTM
10     0.39000000    EHX
11     0.56000000   VWER
12    -0.97000000   DNTM
13    -0.72000000    EHX
14     0.26000000   VWER

我的输出是:

OUTPUT ks_values:
DNTM   0.20326939
EHX    0.34826827
VWER   0.60256811
dtype: float64

OUTPUT p_values:
DNTM   0.98593727
EHX    0.48009144
VWER   0.02898631
dtype: float64

预期输出为:

EXPECTED OUTPUT FOR ks_values:
DNTM   0.28999582
EHX    0.34484969
VWER   0.63466098
dtype: float64

EXPECTED OUTPUT FOR p_values:
DNTM   0.73186935
EHX    0.49345487
VWER   0.01775987
dtype: float64

有人告诉我必须先使用适当的规范化,然后才能使用正确的p_values和ks_values,但我不理解这种适当的规范化的含义以及如何解决此问题。谁能帮忙?

4 个答案:

答案 0 :(得分:1)

不带任何附加参数的KS测试将根据标准正态分布(均值为0和标准偏差为1的正态分布)测试您的数据。如果您的数据正态分布具有不同的均值和标准差,则KS测试会告诉您数据的分布显着不同(您将获得较小的p值)。

您要测试的是分布的“形状”,而不是均值和标准差。两种选择:在将数据放入kstest之前对其进行标准化(减去均值然后除以标准差),或者在调用KS test的调用中添加参数(scipy.stats.kstest(data, 'norm', args=(mean, standard deviation))

答案 1 :(得分:1)

我找到了解决问题的方法。不知何故,我不得不在整个数据集中采用该列的均值和标准差。在这种情况下,我必须要做

k, p = kstest(rvs=subgroup, 
              cdf='norm', 
              args=(np.mean(df['signal_return']), np.std(df['signal_return'])))

df = long_short_signal_returns

答案 2 :(得分:1)

我遇到了同样的问题,并尝试将分布标准化为均值= 0和std = 1

但是,测试中的期望值仍然(略)不同。测试中是否有错误,还是您获得了完全相同的值?您是如何通过考试的?

groups = long_short_signal_returns.groupby('ticker')

normal_args = (np.mean(long_short_signal_returns['signal_return']),np.std(long_short_signal_returns['signal_return']))

for name, group in groups:
    ks_value, p_value = kstest(group['signal_return'].values, 'norm', normal_args)

测试结果略有偏离(+-0.05):

OUTPUT ks_values:
AVYK   0.63919407
JUWZ   0.29787827
VXIK   0.35221525
dtype: float64

OUTPUT p_values:
AVYK   0.01650327
JUWZ   0.69536353
VXIK   0.46493498
dtype: float64

EXPECTED OUTPUT FOR ks_values:
JUWZ   0.28999582
VXIK   0.34484969
AVYK   0.63466098
dtype: float64

EXPECTED OUTPUT FOR p_values:
JUWZ   0.73186935
VXIK   0.49345487
AVYK   0.01775987
dtype: float64

答案 3 :(得分:1)

normal_args = (np.mean(long_short_signal_returns['signal_return']), np.std(long_short_signal_returns['signal_return'], ddof =1))

尝试添加ddof = 1。这是一个样本,而不是总体,因此在计算标准差时,需要使用(n-1)而不是'n'。