Skip to content

Commit

Permalink
Fixed typos
Browse files Browse the repository at this point in the history
  • Loading branch information
nagyatka committed Apr 17, 2019
1 parent 6fc0a5b commit b2a8d22
Show file tree
Hide file tree
Showing 6 changed files with 356 additions and 33 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# MSAX: Multivariate Symbolic Aggregate Approximation

## Installation

## Usage

185 changes: 185 additions & 0 deletions examples/sax_example.ipynb

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions msax/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def alphabet_error(paa_x, sax_x, a):
return np.sum(np.abs(values - paa_x))


def sax_error(x, a, w, memory_limit, use_inf=False, l_1 = 1.0):
def sax_error(x, a, w, memory_limit, use_inf=False, l_1=1.0):
"""
Calculates the L_1 error with input parameters. If the w < 2, a < 3 or the generated sax does not fit in the memory
it will return with np.nan. If the use_inf is True, it returns with np.inf instead of np.nan.
Expand Down Expand Up @@ -133,7 +133,6 @@ def as_dataframe(self, without_nan=True):
df = df.dropna()
return df


def __str__(self):
return "ErrorSurface: min_w: {}, min_a: {}, min_value: {}".format(self.min_w, self.min_a, self.min)

Expand Down
10 changes: 5 additions & 5 deletions msax/msax.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def breakpoints(a):
"""
bps = break_point_cache.get(a, None)
if bps is None:
bps = [np.sqrt(2)* erfinv(2*(j / a) - 1) for j in range(1, a)]
bps = [np.sqrt(2) * erfinv(2*(j / a) - 1) for j in range(1, a)]
break_point_cache[a] = bps
return bps

Expand All @@ -35,7 +35,7 @@ def symbol_values(a):
bps = breakpoints(a)

vals = [bps[0]]
vals.extend([(bps[x] + bps[x - 1]) / 2 for x in range(1,a-1)])
vals.extend([(bps[x] + bps[x - 1]) / 2 for x in range(1, a-1)])
vals.append(bps[-1])
return np.array(vals)

Expand Down Expand Up @@ -84,7 +84,7 @@ def alphabetize(paa_x, a):
:return: Symbol indices' list. A symbol index can be interpreted as an alphabet index.
:rtype: np.ndarray
"""
return np.searchsorted(breakpoints(a), paa_x)
return np.searchsorted(breakpoints(a), paa_x)


def sax(x, w, a, normalized=False):
Expand All @@ -103,9 +103,9 @@ def sax(x, w, a, normalized=False):
:rtype: np.ndarray
"""
if not normalized:
return alphabetize(paa(normalize(x),w), a)
return alphabetize(paa(normalize(x), w), a)
else:
return alphabetize(paa(x,w), a)
return alphabetize(paa(x, w), a)


def independence_transform(x):
Expand Down
55 changes: 29 additions & 26 deletions msax/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@
import numpy as np
import seaborn as sns

from msax.msax import paa

from mpl_toolkits.mplot3d import Axes3D

def ts_with_hist(x, fig = None, gridsize=(1, 3), bins=50):

def ts_with_hist(x, fig=None, bins=50):
"""
Visualizes the input x time series with its histogram.
:param x:
:param fig:
:param gridsize:
:param bins:
:param x: Input array
:param fig: Optional, matplotlib figure
:param bins: Number of bins on histogram
:return:
"""
if fig is None:
fig = plt.figure(figsize=(18, 6))
gridsize = (1, 3)
ax1 = plt.subplot2grid(gridsize, (0, 0), colspan=2, rowspan=1, fig=fig)
ax2 = plt.subplot2grid(gridsize, (0, 2), fig=fig)
ax1.plot(x)
Expand All @@ -24,58 +28,57 @@ def ts_with_hist(x, fig = None, gridsize=(1, 3), bins=50):
return fig, ax1, ax2


def plot_paa(orig_x, paa_x, w, fig = None):
def plot_paa(x, w, fig=None):
"""
Visualizes the input x time series with its PAA transformed version.
:param orig_x:
:param paa_x:
:param w:
:param fig:
:param x: Input array
:param w: window size parameter for PAA transformation
:param fig: Optional, matplotlib figure
:return:
"""
if fig is None:
fig = plt.figure(figsize=(18, 6))
x_paa = paa(x, w)

ax = fig.subplots(nrows=1, ncols=1)
ax.plot(orig_x, c='blue', label='Original')
ax.plot(np.repeat(paa_x, w), c='orange', label='PAA')
ax.plot(x, c='blue', label='Original')
ax.plot(np.repeat(x_paa, w), c='orange', label='PAA')
ax.legend()

return fig, ax


def plot_2d_error_surface(err_surface, alphabets, windows, fig = None):
def plot_2d_error_surface(err_surface, fig=None):
"""
Visualizes the input ErrorSurface in 2D.
:param err_surface:
:param alphabets:
:param windows:
:param fig:
:param err_surface: Input error surface. Must be an instance of ErrorSurface (msax.error.ErrorSurface)
:type err_surface: msax.error.ErrorSurface
:param fig: Optional, matplotlib figure
:return:
"""
if fig is None:
fig = plt.figure(figsize=(18, 12))

from msax.error import ErrorSurface
if isinstance(err_surface, ErrorSurface):
err_surface = err_surface.values
err_surface_vals = err_surface.values

ax = fig.add_subplot(111)
ax.text()
sns.heatmap(err_surface, xticklabels=alphabets, yticklabels=windows, ax=ax)
sns.heatmap(err_surface_vals, xticklabels=err_surface.alphabets, yticklabels=err_surface.windows, ax=ax)
ax.set_ylabel('window size')
ax.set_xlabel('alphabet size')
ax.set_title('Cost of SAX')
sns.jointplot()
return fig, ax


def plot_3d_error_surface(err_surface, ax=None, title=None):
"""
Visualizes the input ErrorSurface in 3D.
:param title:
:param ax:
:param err_surface:
:param err_surface: Input error surface
:type err_surface: msax.error.ErrorSurface
:param title: Optional. The title of the figure
:param ax: Optional. matplotlib axes.
:return:
"""
if ax is None:
Expand Down
130 changes: 130 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import io
import os
import sys
from shutil import rmtree

from setuptools import find_packages, setup, Command

# Package meta-data.
NAME = 'msax'
DESCRIPTION = 'Implementation of Multivariate Symbolic Aggregate Approximation (MSAX)'
URL = 'https://github.com/nagyatka/msax'
EMAIL = '[email protected]'
AUTHOR = 'Attila M. Nagy'
REQUIRES_PYTHON = '>=3.6.0'
KEYWORDS = 'sax msax timeseries '

MAJOR = 0
MINOR = 1
MICRO = 0
VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)

# What packages are required for this module to be executed?
REQUIRED = [
'numpy', 'scipy', 'pandas'
]

# What packages are optional?
EXTRAS = {
# 'fancy feature': ['django'],
}

# The rest you shouldn't have to touch too much :)
# ------------------------------------------------
# Except, perhaps the License and Trove Classifiers!
# If you do change the License, remember to change the Trove Classifier for that!

here = os.path.abspath(os.path.dirname(__file__))

# Import the README and use it as the long-description.
# Note: this will only work if 'README.md' is present in your MANIFEST.in file!
try:
with io.open(os.path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = '\n' + f.read()
except FileNotFoundError:
long_description = DESCRIPTION


# Load the package's __version__.py module as a dictionary.
about = {}
if not VERSION:
project_slug = NAME.lower().replace("-", "_").replace(" ", "_")
with open(os.path.join(here, project_slug, '__version__.py')) as f:
exec(f.read(), about)
else:
about['__version__'] = VERSION

class UploadCommand(Command):
"""Support setup.py upload."""

description = 'Build and publish the package.'
user_options = []

@staticmethod
def status(s):
"""Prints things in bold."""
print('\033[1m{0}\033[0m'.format(s))

def initialize_options(self):
pass

def finalize_options(self):
pass

def run(self):
try:
self.status('Removing previous builds…')
rmtree(os.path.join(here, 'dist'))
except OSError:
pass

self.status('Building Source and Wheel (universal) distribution…')
os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable))

self.status('Uploading the package to PyPI via Twine…')
os.system('twine upload dist/*')

self.status('Pushing git tags…')
os.system('git tag v{0}'.format(about['__version__']))
os.system('git push --tags')

sys.exit()


# Where the magic happens:
setup(
name=NAME,
version=about['__version__'],
description=DESCRIPTION,
long_description=long_description,
long_description_content_type='text/markdown',
author=AUTHOR,
author_email=EMAIL,
python_requires=REQUIRES_PYTHON,
url=URL,
packages=find_packages(exclude=["tests", "*.tests", "*.tests.*", "tests.*"]),
# If your package is a single module, use this instead of 'packages':
# py_modules=['mypackage'],

# entry_points={
# 'console_scripts': ['mycli=mymodule:cli'],
# },
install_requires=REQUIRED,
extras_require=EXTRAS,
include_package_data=True,
license='MIT',
classifiers=[
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Scientific/Engineering :: Artificial Intelligence',
'Topic :: Scientific/Engineering :: Information Analysis'
],
# $ setup.py publish support.
cmdclass={
'upload': UploadCommand,
},
)

0 comments on commit b2a8d22

Please sign in to comment.