时间序列分类方法:BOSSVS学习

前言

BOSSVS(Bag-Of-SFA Symbols in Vector Space)是一种将自然语言处理方法中TF-IDF应用到基于符号化傅里叶逼近(SFA)的词袋中的方法,是一种时间序列分类的方法。简单来说与之前讲的SAX-VSM有异曲同工之妙,不过这里的字符是通过离散傅里叶系数得到的。

一、理论部分

SFA(Symbolic Fourier Approximation)

SFA是一种将时间序列转换为傅里叶系数后,将一定数量傅里叶系数离散化后、映射到字符的算法,这和之前讲到的SAX很相似,只不过转换到了频域。
离散傅里叶逼近在上一篇文章讲到了,有兴趣可以看一下,内容很少也很好理解,当然,如果存在错误烦请指正,不胜感激!
SFA简单流程
上图简单描述了SFA的过程,通过将时间序列( 蓝色 \textcolor{blue}{蓝色} 蓝色)进行离散傅里叶变换得到傅里叶系数( 红色 \textcolor{red}{红色} 红色),再将其中低频成分或特征、主要成分取出后进行分箱,最后映射到字符上。
SFA提供了几种分箱方法:①每个箱的宽度相同;②每个箱内的数据点数相同;③正态分布分位数(和SAX一样)。
不同的分箱策略得到的结果差距还是挺大的,我个人习惯了SAX的模式,所以后续都是按照正态分布分位数进行的。

不知道有没有朋友和我有一样的疑问,有了SAX为什么还要SFA?而且SFA只取了部分傅里叶系数进行逼近,会不会效果不好。虽然现在我可能也不能给出一个很好的解释,但从学习过程中的一些思考来讲,个人认为,首先SFA是在频域实现的,这可以实现一定的降噪效果,如果是选择前n个系数,那这些系数表示的就是数据的趋势,如果选择的是最具特点的,那就是最具特点的(咳咳)。

二、实战

1.自编代码

这次自编代码是在python实现的,还是贴出一些主要的代码交流交流~

    def sfa(self, x, strategy='reduce'):
        """
        生成符号表达
        :param strategy: 是否删除重复字符串
        :param x:离散傅里叶逼近的长度为coeff的傅里叶系数
        :return: 符号表达
        """
        sfa_list = []
        indexes = []
        temp = ''
        n = len(x)
        for i in range(n-self.win_size+1):
            sub = x[i:i+self.win_size]
            new_sub = self.dft_trans(sub)
            for j in range(len(new_sub)):
                temp += self.alpha[np.sum(self.beta <= new_sub[j]) - 1]
            if strategy == 'reduce':
                if len(sfa_list) == 0 or not temp == sfa_list[-1]:
                    sfa_list.append(temp)
                    indexes.append(i)
            else:
                sfa_list.append(temp)
                indexes.append(i)
            temp = ''
        return sfa_list, indexes

这里的reduce就是表明只保留连续相同字符串的第一个,和SAX一样。转换部分和离散傅里叶逼近和之前的文章一样,就不再重复了。

2.Pyts库函数

from pyts.classification import BOSSVS
from pyts.approximation import SymbolicFourierApproximation, MultipleCoefficientBinning
from pyts.datasets import load_gunpoint,load_pig_central_venous_pressure,load_coffee
X_train, X_test, y_train, y_test = load_coffee(return_X_y=True)
clf = BOSSVS(window_size=100,word_size=10,n_bins=5,strategy='normal')
clf.fit(X_train, y_train)
score = clf.score(X_test,y_test)
print('accuracy:',score)

注意一下,strategy这里强调了一下用normal,我记得当时测试自编的效果总是和库函数对不上,最后发现是由于默认的分箱策略不是正态分位数,可以注意一下~

3.测试

这次的测试用一些不一样的,数据集采用凯斯西储大学的故障轴承公开数据集里转速为1793的部分,对比了一下SAX-VSM和BOSSVS的效果,这里滑窗宽度为30,单词长度5,单词表长度:10。
SAX-VSM:
SAX-VSM分类结果
BOSSVS:
BOSSVS分类结果
可以说都挺惨不忍睹的,而且没想到BOSSVS和SAX-VSM差了这么多,不过毕竟轴承故障特征比较复杂,虽然会表现出一些周期性的冲击、调幅什么的,但是还是不能简单的从时域的形状进行区分。而且不得不说,调参是个玄学的事情,窗口宽度、单词长度、单词表长度有一丝丝变化最后的结果都天差地别。

结尾碎碎念

最近在做一些异常检测的任务,虽然能把一些异常的成分弄得更加明显了,但是阈值调参真的好烦啊!!!原来想用 μ + n σ \mu+n\sigma μ+这种方法,但是数据不遵循正态分布,效果很差,害。
学习了一下孤立森林,测试一下,用滑动均值将数据平滑、或者说得到趋势后再应用,效果还行,但是总会漏一些,还是需要多学习呀。

参考文献

Schäfer P. Bag-Of-SFA-symbols in vector space (BOSS VS)[J]. 2015.

  • 33
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值