Python TsFresh特征的Java实现——change_quantiles

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

特征change_quantiles简介

命令格式:change_quantiles(x, ql, qh, isabs, f_agg)

对给定时间序列x,由分位数ql与qh确定的区间。计算区间内时间序列x的均值、连续变化的绝对值等。

参数

  • x:时间序列,数据类型:numpy.ndarray
  • ql:数据的下分位数,数据类型:float
  • qh:数据的上分位数,数据类型:float
  • isabs:是否取绝对值,数据类型:bool
  • f_agg:应用于数据的聚合函数名称,如mean, var, std, median等,数据类型:str

特征change_quantiles计算原理

     1. 计算时间序列x的一阶差分div

     2. 根据参数isabs的值确定是否对div取绝对值。True时为取绝对值,False时不取绝对值

     3. 计算时间序列x的上、下分位数,确定统计区间

  计算分位数的方法是采用基于N-1计算分位数

  • 将数据从小到大排序,计为数组a(1 to n),n代表数据的长度
  • 确定分位数的位置:b= 1+(n-1) × quanty,b的整数部分计为c b的小数部分计为d
  • 计算分位数:若c<n,则result=a(c)+[a(c+1)-a(c)]*d,若c=n,则result=a(c)

     4. 建立一个与x等长度的索引序列ind,将x中处于统计区间内的值所对应的索引在ind中赋值为1,而其它索引赋值为0.

     5. 将索引序列ind与其移位1位的ind逐位进行“与”操作,形成新的索引序列ind

     6. 将索引序列ind为1的索引所对就的div中的数据,根据f_agg给出的函数进行统计分析

f_agg = "mean":均值

mean = \frac{1}{N}\sum_{i=1}^Nx_i

f_agg = "var":方差

var = \frac{1}{N}\sum_{i=1}^N(x_i-\bar{x})^2

注:这里的var采用的是方差公式,而不是样本方差公式,因此分母为N,而不是N-1。

 

Java实现

实现change_quantiles特征的代码

	public static double change_quantiles(double[] x, double ql, double qh, boolean isabs, String f_agg) {
		double result = 0;
		double[] x_diff = new double[x.length - 1];
		for (int idx = 0; idx < (x.length-1); idx++) {
			x_diff[idx] = x[idx+1] - x[idx];
			if (isabs)
				x_diff[idx] = Math.abs(x_diff[idx]);
		}
		
		double quantyLow = Quantiles_INC(x, ql);
		double quantyHig = Quantiles_INC(x, qh);
		
		int[] flag4Used = new int[x.length];
		for (int idx = 0; idx < x.length; idx++) {
			if ((x[idx] >= quantyLow) & (x[idx] <= quantyHig)) {
				flag4Used[idx] = 1;
			} else {
				flag4Used[idx] = 0;
			}
		}
		int num = 0;
		int[] flag4Diff = new int[x.length - 1];
		for (int idx = 0; idx < flag4Diff.length; idx++) {
			flag4Diff[idx] = flag4Used[idx] * flag4Used[idx+1];
			if (flag4Diff[idx] > 0) {
				num++;
			}
		}
		double[] x_short = new double[num];
		int ind = 0;
		for (int idx = 0; idx < flag4Diff.length; idx++) {
			if (flag4Diff[idx] > 0) {
				x_short[ind] = x_diff[idx];
				ind++;
			}
		}
		
		switch (f_agg) {
		case "var":{
			result = Var(x_short);
			break;
		}
		}
		
		return result;
	}

求解分位数的代码

	public static double Quantiles_INC(double[] x, double quanty) {
		double result = 0;
		Arrays.sort(x);
		double b = (x.length - 1) * quanty;
		double c = Math.floor(b);
		double d = b-c;
		if (c < (x.length - 1)) {
			result = x[(int) c] + (x[(int) c+1] - x[(int) c])*d;
		} else {
			result = x[(int) c];
		}
		
		
		return result;
	}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

带着地球去浪一浪

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

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

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

打赏作者

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

抵扣说明:

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

余额充值