2

我正在研究一个财务问题,我要实现一个函数,在每只股票的信号回报的正态分布之间使用 Kolmogorov-Smirnov 检验(KS 检验)。我要针对每只股票的信号回报在正态分布上运行 KS 测试,为了测试,我将使用scipy.stats.kstest来执行 KS 测试。

  • 建议我迭代groupby函数
  • 我只需要使用 pandas、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

4 回答 4

2

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

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

在哪里df = long_short_signal_returns

于 2018-08-15T04:33:21.947 回答
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
于 2018-08-17T13:11:41.690 回答
1

没有任何附加参数的 KS 检验将根据标准正态分布(均值为 0 和标准差为 1 的正态分布)测试您的数据。如果您的数据以不同的均值和标准差呈正态分布,则 KS 检验会告诉您数据的分布存在显着差异(您会得到一个小的 p 值)。

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

于 2018-08-13T11:27:34.763 回答
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'。

于 2018-08-20T03:28:56.853 回答