Python TsFresh特征的Java实现——spkt_welch_density

 TsFresh(TimeSeries Fresh)是一个Python第三方工具包。它可以方便地对时间序列数据进行处理,获得大量的特征。这些特征可以用以训练分类器,以高效地实现对时间序列数据的分类、识别等。然而,在工程实现时,更多地是采用Java等语言,这需要利用Java实现对TsFresh的特征进行直接计算,故需要对TsFresh的某些特征进行深入地分析,并在Java语言下实现。

特征spkt_welch_density简介

命令格式:spkt_welch_density(x, param)

计算时间序列的功率谱密度在特征频率点上的值作为输出特征。

参数

  • x:时间序列,数据类型:numpy.ndarray
  • param:参数字典{"coeff": q},其中q为表示输出特征的功率谱密度数组的索引值

特征spkt_welch_density计算原理

  1. 根据Hanning窗的表达式,形成与时间序列点数相匹配的Hanning权矢量
  2. 去除时间序列x中的直流分量,形成新的序列x_detrend
  3. 用Hanning权矢量对序列x_detrend加权,形成加权后序列weighted_data
  4. 对加权后序列weighted_data做单边Fourier变换,得其单边频谱fx
  5. 利用单边频谱fx共轭相乘并进行归一化处理后,获得单边功率谱pxx
  6. 利用参数Coeff选择单边功率谱pxx相应索引处的值作为特征输出

Java实现

构造Hanning窗

w(n) = 0.5 + 0.5\cos\frac{2n\pi}{M}\qquad 0\leqslant n \leqslant M-1

public static double[] Window_Hann(int width_Window) {
	double dTheta = Math.PI*2.0/width_Window;
	double[] angle = new double[width_Window];
	for (int idx = 0; idx < width_Window; idx++) {
    	angle[idx] = -Math.PI + idx * dTheta;
	}
	System.out.println(Arrays.toString(angle));
	double[] weights = new double[width_Window];
	for (int idx = 0; idx < width_Window; idx++) {
		weights[idx] = 0.5 + 0.5 * Math.cos(angle[idx]);
	}
	return weights;
}

在进行Fourier变换之前需要对时间序列做去直流处理。

由于时间序列的长度不能够保证是2^N,所以无法使用Apache Commons Math 3.6.1 API中的FastFourierTransform,通常在网上能够找到的Fourier变换程序也是需要对数据长度要求为2^N,因此,需要对此进行独立编写。

Complex[] fx = new Complex[n_x/2 + 1];
int n_f = fx.length;
for (int idx_n = 0; idx_n < n_f; idx_n++) {
	fx[idx_n] = new Complex(0);
	for (int idx_k = 0; idx_k < n_x; idx_k++) {
		Complex cplx_exp = new Complex(Math.cos(angle[idx_k]*idx_n), 
            -Math.sin(angle[idx_k]*idx_n));
		fx[idx_n] = fx[idx_n].add(cplx_exp.multiply(new Complex(weighted_data[idx_k])));
	}
}
		

单边功率谱不是简单地等于单边频谱的平方,而应该是除零频之外的应是单边频谱平方的两倍

double[] pxx = new double[n_f]; 
for (int idx_n = 0; idx_n < n_f; idx_n++) {
	if (idx_n == 0) {
		pxx[idx_n] = fx[idx_n].conjugate().multiply(fx[idx_n]).getReal()/sum_wgt;
	} else {
		pxx[idx_n] = fx[idx_n].conjugate().multiply(fx[idx_n]).getReal()*2/sum_wgt;
	}
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

带着地球去浪一浪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值