SVM 分类器 n_samples、n_splits 问题 sklearn Python
SVM classifier n_samples, n_splits problem sklearn Python
我正在尝试使用基于 O'Reilly 书籍示例的 SVM 模型(使用 Python 进行金融风险管理的机器学习)预测波动率。当我完全复制示例(使用 S&P500 数据)时,它运行良好,但现在我在使用特定基金 returns 数据:
的这段代码时遇到了麻烦
# returns
r = np.array([ nan, 0.0013933 , 0.00118874, 0.00076462, 0.00168565,
-0.00018507, -0.00390753, 0.00307275, -0.00351472])
# horizon
t = 252
# mean of returns
mu = r.mean()
# critical value
z = norm.ppf(0.95)
# realized volatility
vol = r.rolling(5).std()
vol = pd.DataFrame(vol)
vol.reset_index(drop=True, inplace=True)
# SVM GARCH
r_svm = r ** 2
r_svm = r_svm.reset_index()
# inputs X (returns and realized volatility)
X = pd.concat([vol, r_svm], axis=1, ignore_index=True)
X = X.dropna().copy()
X = X.reset_index()
X.drop([1, 'index'], axis=1, inplace=True)
# labels y realized volatility shifted 1 period onward
vol = vol.dropna().reset_index()
vol.drop('index', axis=1, inplace=True)
# linear kernel
svr_lin = SVR(kernel='linear')
# hyperparameters grid
para_grid = {'gamma': sp_rand(),
'C': sp_rand(),
'epsilon': sp_rand()}
# svm classifier (regression?)
clf = RandomizedSearchCV(svr_lin, para_grid)
clf.fit(X[:-1].dropna().values,
vol[1:].values.reshape(-1,))
# prediction
n_vol = clf.predict(X.iloc[-1:])
引发的错误是:
ValueError: Cannot have number of splits n_splits=5 greater than the number of samples: n_samples=3.
该代码适用于更长的 returns 系列,因此我假设问题出在数组的长度上,但我不知道如何解决它。有人可以帮我吗?
出现此错误是因为您将 RandomizedSearchCV
与默认 cv
参数一起使用。
默认情况下 RandomizedSearchCV
是 运行 5 倍 cross-validation 以找到模型的最佳超参数。
5-folds cross-validation 意味着将你的训练数据分成 5 个子集,并根据这些分割训练 5 个不同的模型。
看起来您的训练集中的对象少于 5 个,因此无法将您的数据分成 5 份。
要解决此问题,您应该添加更多数据或通过添加 cv
参数来减少 RandomizedSearchCV
的折叠数:
clf = RandomizedSearchCV(svr_lin, para_grid, cv=2)
我建议收集更多数据,因为 4 个数据点很可能不足以使模型准确或具有预测性。
我正在尝试使用基于 O'Reilly 书籍示例的 SVM 模型(使用 Python 进行金融风险管理的机器学习)预测波动率。当我完全复制示例(使用 S&P500 数据)时,它运行良好,但现在我在使用特定基金 returns 数据:
的这段代码时遇到了麻烦# returns
r = np.array([ nan, 0.0013933 , 0.00118874, 0.00076462, 0.00168565,
-0.00018507, -0.00390753, 0.00307275, -0.00351472])
# horizon
t = 252
# mean of returns
mu = r.mean()
# critical value
z = norm.ppf(0.95)
# realized volatility
vol = r.rolling(5).std()
vol = pd.DataFrame(vol)
vol.reset_index(drop=True, inplace=True)
# SVM GARCH
r_svm = r ** 2
r_svm = r_svm.reset_index()
# inputs X (returns and realized volatility)
X = pd.concat([vol, r_svm], axis=1, ignore_index=True)
X = X.dropna().copy()
X = X.reset_index()
X.drop([1, 'index'], axis=1, inplace=True)
# labels y realized volatility shifted 1 period onward
vol = vol.dropna().reset_index()
vol.drop('index', axis=1, inplace=True)
# linear kernel
svr_lin = SVR(kernel='linear')
# hyperparameters grid
para_grid = {'gamma': sp_rand(),
'C': sp_rand(),
'epsilon': sp_rand()}
# svm classifier (regression?)
clf = RandomizedSearchCV(svr_lin, para_grid)
clf.fit(X[:-1].dropna().values,
vol[1:].values.reshape(-1,))
# prediction
n_vol = clf.predict(X.iloc[-1:])
引发的错误是:
ValueError: Cannot have number of splits n_splits=5 greater than the number of samples: n_samples=3.
该代码适用于更长的 returns 系列,因此我假设问题出在数组的长度上,但我不知道如何解决它。有人可以帮我吗?
出现此错误是因为您将 RandomizedSearchCV
与默认 cv
参数一起使用。
默认情况下 RandomizedSearchCV
是 运行 5 倍 cross-validation 以找到模型的最佳超参数。
5-folds cross-validation 意味着将你的训练数据分成 5 个子集,并根据这些分割训练 5 个不同的模型。
看起来您的训练集中的对象少于 5 个,因此无法将您的数据分成 5 份。
要解决此问题,您应该添加更多数据或通过添加 cv
参数来减少 RandomizedSearchCV
的折叠数:
clf = RandomizedSearchCV(svr_lin, para_grid, cv=2)
我建议收集更多数据,因为 4 个数据点很可能不足以使模型准确或具有预测性。