当前位置:   article > 正文

AI算法Python实现:Transfer entropy_pyinform

pyinform

一、原理

Transfer entropy(转移熵/传递熵)是一种非参数统计量,用于测量两个随机过程之间定向(时间不对称)的信息转移量。给定两个随机过程XY,在A时刻,Y的值为Y_{A},随着时间的推移,由于不确定性,到达B时刻后,Y的值只能在一定的范围内被确定。在变化过程中,如果过程X对过程Y(定向)施加一定的影响(信息转移量),那么到达B时刻后,Y的值的范围会发生变化,这个变化的量,就是Transfer entropy所代表的过程X到过程Y,导致Y变化的非确定性的减少量。用公式可以表示为:

T_{X\rightarrow Y}=H\left ( Y_{t}|Y_{t-1:t-L} \right )-H\left ( Y_{t}|Y_{t-1:t-L} ,X_{t-1:t-L}\right )

 其中,H(X)代表X的熵(香农熵)。

二、代码实现

  • transferEntropy.py
  • main.py

transferEntropy.py

  1. import numpy as np
  2. from ctypes import byref, c_int, c_ulong, c_double, POINTER
  3. from pyinform import _inform
  4. from pyinform.error import ErrorCode, error_guard
  5. def transfer_entropy(source, target, k, condition=None, local=False):
  6. """
  7. Compute the local or average transfer entropy from one time series to
  8. another with target history length *k*. Optionally, time series can be
  9. provided against which to *condition*.
  10. :param source: the source time series
  11. :type source: sequence or ``numpy.ndarray``
  12. :param target: the target time series
  13. :type target: sequence or ``numpy.ndarray``
  14. :param int k: the history length
  15. :param condition: time series of any conditions
  16. :type condition: sequence or ``numpy.ndarray``
  17. :param bool local: compute the local transfer entropy
  18. :returns: the average or local transfer entropy
  19. :rtype: float or ``numpy.ndarray``
  20. :raises ValueError: if the time series have different shapes
  21. :raises ValueError: if either time series has no initial conditions
  22. :raises ValueError: if either time series is greater than 2-D
  23. :raises InformError: if an error occurs within the ``inform`` C call
  24. """
  25. ys = np.ascontiguousarray(source, np.int32)
  26. xs = np.ascontiguousarray(target, np.int32)
  27. cs = np.ascontiguousarray(condition, np.int32) if condition is not None else None
  28. if xs.shape != ys.shape:
  29. raise ValueError("source and target timeseries are different shapes")
  30. elif xs.ndim > 2:
  31. raise ValueError("source and target have too great a dimension; must be 2 or less")
  32. if cs is None:
  33. pass
  34. elif cs.ndim == 1 and cs.shape != xs.shape:
  35. raise ValueError("condition has a shape that's inconsistent with the source and target")
  36. elif cs.ndim == 2 and xs.ndim == 1 and cs.shape[1:] != xs.shape:
  37. raise ValueError("condition has a shape that's inconsistent with the source and target")
  38. elif cs.ndim == 2 and xs.ndim == 2 and cs.shape != xs.shape:
  39. raise ValueError("condition has a shape that's inconsistent with the source and target")
  40. elif cs.ndim == 3 and cs.shape[1:] != xs.shape:
  41. raise ValueError("condition has a shape that's inconsistent with the source and target")
  42. elif cs.ndim > 3:
  43. raise ValueError("condition has too great a dimension; must be 3 or less")
  44. ydata = ys.ctypes.data_as(POINTER(c_int))
  45. xdata = xs.ctypes.data_as(POINTER(c_int))
  46. cdata = cs.ctypes.data_as(POINTER(c_int)) if cs is not None else None
  47. if cs is None:
  48. b = max(2, max(np.amax(xs), np.amax(ys)) + 1)
  49. else:
  50. b = max(2, max(np.amax(xs), np.amax(ys), np.amax(cs)) + 1)
  51. if cs is None:
  52. z = 0
  53. elif cs.ndim == 1 or (cs.ndim == 2 and xs.ndim == 2):
  54. z = 1
  55. elif cs.ndim == 3 or (cs.ndim == 2 and xs.ndim == 1):
  56. z = cs.shape[0]
  57. else:
  58. raise RuntimeError("unexpected state: condition and source are inconsistent shapes")
  59. if xs.ndim == 1:
  60. n, m = 1, xs.shape[0]
  61. else:
  62. n, m = xs.shape
  63. e = ErrorCode(0)
  64. if local is True:
  65. q = max(0, m - k)
  66. te = np.empty((n, q), dtype=np.float64)
  67. out = te.ctypes.data_as(POINTER(c_double))
  68. _local_transfer_entropy(ydata, xdata, cdata, c_ulong(z), c_ulong(n), c_ulong(m), c_int(b), c_ulong(k), out, byref(e))
  69. else:
  70. te = _transfer_entropy(ydata, xdata, cdata, c_ulong(z), c_ulong(n), c_ulong(m), c_int(b), c_ulong(k), byref(e))
  71. error_guard(e)
  72. return te
  73. _transfer_entropy = _inform.inform_transfer_entropy
  74. _transfer_entropy.argtypes = [POINTER(c_int), POINTER(c_int), POINTER(c_int), c_ulong, c_ulong, c_ulong, c_int, c_ulong, POINTER(c_int)]
  75. _transfer_entropy.restype = c_double
  76. _local_transfer_entropy = _inform.inform_local_transfer_entropy
  77. _local_transfer_entropy.argtypes = [POINTER(c_int), POINTER(c_int), POINTER(c_int), c_ulong, c_ulong, c_ulong, c_int, c_ulong, POINTER(c_double), POINTER(c_int)]
  78. _local_transfer_entropy.restype = POINTER(c_double)

main.py

  1. from transferEntropy import *
  2. xs = [0, 1, 1, 1, 1, 0, 0, 0, 0]
  3. ys = [0, 0, 1, 1, 1, 1, 0, 0, 0]
  4. a = transfer_entropy(xs, ys, k=2)
  5. print(a)

测试结果: 

三、参考资料

1. Transfer entropy - Wikipedia

2. Transfer Entropy - PyInform

3. 机器学习——建立因果连系(传递熵)

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号