练习1:寻找非线性关系的相关性#
a. 传统(皮尔逊)相关系数#
计算变量x与y之间的皮尔逊相关系数。
数据生成
code
n = 100
x = np.linspace(1, n, n)
y = x**5b. 斯皮尔曼等级相关系数#
使用stats.rankdata函数和公式计算x与y的斯皮尔曼相关系数:
其中为第i对值的等级差。
验证
使用scipy.stats.spearmanr验证计算结果。
练习2:斯皮尔曼相关系数的局限性#
a. 滞后关系#
构造与序列a完全相同但滞后一期的序列b(即b[i] = a[i-1]),计算a与b的斯皮尔曼相关系数。
数据生成
code
n = 100
a = np.random.normal(0, 1, n)b. 非单调关系#
通过关系式d=10c2−c+2d = 10c^2 - c + 2d=10c2−c+2生成序列d,计算c与d的斯皮尔曼相关系数。
数据生成
code
n = 100
c = np.random.normal(0, 2, n)练习3:实际应用案例#
a. 因子与远期收益#
使用yfinance获取2015年股票数据:
code
import yfinance as yf
asset_list = ['AAPL', 'MSFT', 'GOOG'] # 示例股票列表
prices_df = yf.download(asset_list, start='2015-01-01', end='2016-01-01')['Adj Close']定义动量因子(过去60日收益率):
code
my_factor = prices_df.pct_change(60)计算2015-01-02日的因子值与未来10日收益率的斯皮尔曼相关系数。
远期收益计算
code
forward_returns = prices_df.pct_change(10).shift(-10)b. 滚动窗口相关性#
对前60个交易日计算滚动斯皮尔曼相关系数,绘制时间序列并输出均值与标准差。
数据准备
code
rolling_corr = pd.Series(dtype=float)
for dt in prices_df.index[:60]:
valid_assets = my_factor.loc[dt].dropna().index
factor_values = my_factor.loc[dt, valid_assets]
fwd_returns = forward_returns.loc[dt, valid_assets]
# 计算相关系数并存储可视化与统计
code
plt.plot(rolling_corr.rolling(5).mean()) # 5日移动平均
print(f"均值: {rolling_corr.mean():.3f}")
print(f"标准差: {rolling_corr.std():.3f}")