PyOD股票异常检测触发ValueError: multi_class must be in ('ovo', 'ovr')如何解决
报错原因
- 你误用了
evaluate_print评估函数:该函数第二个入参要求传入提前标注好的二分类真实异常标签(0为正常、1为异常),你传入的是连续值的收盘价,scikit-learn的roc_auc_score将连续收盘价识别为多分类标签,因此抛出要求指定multi_class参数的报错。 - 特征选择逻辑错误:你用单调递增的日期作为KNN模型的输入特征,KNN基于距离判断异常的逻辑完全失效,股票价格异常检测应该直接把收盘价作为输入特征。
- PyOD自带的
visualize可视化函数仅支持2维特征场景,你的单特征场景无法直接调用。
修复方案
直接去掉无意义的评估逻辑和拆分训练集测试集的逻辑,自己实现异常点可视化即可,修正后的可运行代码如下:
import pandas as pd import matplotlib.pyplot as plt from pyod.models.knn import KNN # 读取数据,转换日期格式 AAPL = pd.read_csv('AAPL.csv', header=0) AAPL.iloc[:,1] = pd.to_datetime(AAPL.iloc[:,1]) # 取收盘价作为异常检测特征 X = AAPL.iloc[:, 2].values.reshape(-1,1) # 训练KNN异常检测器 clf_name = 'KNN' clf = KNN() clf.fit(X) # 得到所有样本的异常标签,1为异常 y_pred = clf.labels_ # 得到异常分数 y_scores = clf.decision_scores_ # 自定义可视化 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False plt.figure(figsize=(12,6)) # 绘制收盘价走势 plt.plot(AAPL.iloc[:,1], AAPL.iloc[:,2], label='收盘价', color='blue') # 标出异常点 anomaly = AAPL[y_pred == 1] plt.scatter(anomaly.iloc[:,1], anomaly.iloc[:,2], color='red', s=50, label='异常点') plt.title(f'AAPL股票价格异常检测 ({clf_name})') plt.xlabel('日期') plt.ylabel('收盘价') plt.legend() plt.xticks(rotation=45) plt.tight_layout() plt.show()
如果确实需要拆分训练集测试集验证,且你自己有提前标注的异常二分类标签,只需要给evaluate_print传入二分类的真实标签即可,不要再传入连续收盘价。
内容的提问来源于stack exchange,提问作者d12
相关产品推荐
相关产品推荐

