找到数字列表的“形状”(直线/凹/凸,多少个驼峰)

时间:2014-09-06 19:09:07

标签: python statistics classification computer-science differentiation

这有点难以解释。我有一个整数列表。因此,例如,[1, 2, 4, 5, 8, 7, 6, 4, 1] - 当针对元素编号绘制时,它将类似于凸图。我如何从列表中以某种方式提取这种“形状”特征?它没有特别准确 - 只是一般的形状,凸起的一个驼峰,凹面w /两个,直线等 - 会很好。

我可以为每个可能的形状使用条件:例如,如果斜率在某个指数上为正,而在之后为负,则为斜率,偏差取决于index/list_size

有一些更聪明,更通用的方式吗?我想这可能是一个分类问题 - 但没有ML可能吗?

干杯。

2 个答案:

答案 0 :(得分:5)

numpy.diff 
  

第一阶差异由out [n] = a [n + 1] - a [n]

给出

https://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.diff.html

import numpy as np

data = [1, 2, 4, 5, 8, 7, 6, 4, 1]
data = np.array(data, dtype=float)
velocity = np.diff(data)
acceleration = np.diff(velocity)
jerk = np.diff(acceleration)
jounce = np.diff(jerk)

print data
print velocity
print acceleration
print jerk
print jounce

>>>
[ 1.  2.  4.  5.  8.  7.  6.  4.  1.]

# positive numbers = rising
[ 1.  2.  1.  3. -1. -1. -2. -3.]

# positive numbers = concave up
[ 1. -1.  2. -4.  0. -1. -1.]

# positive numbers = curling up
[-2.  3. -6.  4. -1.  0.]

# positive numbers = snapping up
[  5.  -9.  10.  -5.   1.]

https://en.wikipedia.org/wiki/Velocity

https://en.wikipedia.org/wiki/Acceleration

https://en.wikipedia.org/wiki/Jerk_(physics)

https://en.wikipedia.org/wiki/Jounce

我倾向于将一阶导数除以;移动平均速度乘以100,转换为%ROC;有时加速也很重要;凹陷...你得到的混蛋越多,数据越随机/嘈杂

你也可以计算每个人的平均值:

print np.mean(data)
print np.mean(velocity)
print np.mean(acceleration)

对该样本集进行关于形状的概括:

>>>
4.22222222222     # average value
0.0               # generally sideways; no trend
-0.571428571429   # concave mostly down

然后是平均相对标准偏差

import numpy as np
data = [1, 2, 4, 5, 8, 7, 6, 4, 1]
coef_variance = np.std(data) / np.mean(data)
print coef_variance

>>>0.566859453383

我打电话"相当不稳定&#34 ;;但不是极端的数量级;通常> 1被视为"高度变体"

https://en.wikipedia.org/wiki/Coefficient_of_variation

如果我们绘图:

import matplotlib.pyplot as plt
import numpy as np

data = [1, 2, 4, 5, 8, 7, 6, 4, 1]
x = range(9)

plt.plot(x,data,c='red',ms=2)

plt.show()

我们可以看到,这是对我们发现的内容的一般描述:

enter image description here

没有整体上升/下降趋势,相当不稳定,凹陷;意味着超过4

你也可以polyfit:

import matplotlib.pyplot as plt
import numpy as np

data = [1, 2, 4, 5, 8, 7, 6, 4, 1]
x = range(9)
plt.plot(x,data,c='red',ms=2)
poly = np.polyfit(x,data,2)
z = []
for x in range(9):
    z.append(poly[0]*x*x + poly[1]*x + poly[2])
x = range(9)
plt.plot(x,z,c='blue',ms=2)
print poly
plt.show()

返回:

[-0.37445887  3.195671   -0.07272727]
换句话说,

-0.374x^2 +  3.195x - 0.072

其中的情节:

enter image description here

从那里你可以计算平方和,看看你的模型有多准确

Sum of Square Differences (SSD) in numpy/scipy

你可以迭代polyfit过程每次增加度数

np.polyfit(x,data,degree)

直到您获得足够低的SSD满足您的需求;这会告诉你你的数据是否更多x ^ 2ish,x ^ 3ish,x ^ 4ish等。

while ssd > your_desire:               
   poly_array = polyfit()
   ssd = sum_squares(poly_array, data)
   degree +=1

答案 1 :(得分:0)

如果你反复区分数据(即x[i+1] - x[i]),直到所有结果都是相同的符号,怎么样?例如,如果你将它区分两次并且所有结果都是非负的,那么你就知道它是凸的。否则再次区别并检查标志。您可以设置一个限制,例如10左右,超出该限制,您会发现序列太复杂而无法表征。否则,你的形状的特点是你的差异次数和最终的标志。