├── .idea
├── misc.xml
├── modules.xml
├── pySTARMA.iml
└── vcs.xml
├── LICENSE
├── README.md
├── docs
├── installation.rst
├── manual.rst
└── pySTARMA_Logo.png
├── pySTARMA
├── __init__.py
├── stacf_stpacf.py
├── starma_model.py
└── utils.py
└── setup.py
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/pySTARMA.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pySTARMA
2 |
3 |
4 |

5 |
6 |
7 | Works on python 2.7 and 3.x
8 |
9 | pySTARMA is a Python library for modelling space-time-ARMA processes.
10 | It follows the [STARIMA](https://www.jstor.org/stable/621846) model proposed by Pfeifer und Deutsch (1980).
11 | It implements the estimation of the space-time autocorrelation function and the partial space-time autocorrelation function.
12 | It also implements the model estimation by kalman filtering, based on [Cipra and Motyková(1987)](https://dml.cz/bitstream/handle/10338.dmlcz/106567/CommentatMathUnivCarol_028-1987-3_16.pdf?sequence=1) and [Cheysson (2016)](https://cran.r-project.org/web/packages/starma/starma.pdf).
13 |
14 | All documentation can be found in the "docs" directory
15 |
--------------------------------------------------------------------------------
/docs/installation.rst:
--------------------------------------------------------------------------------
1 | Installation of pySTARMA
2 | ----
3 |
4 |
5 | The pySTARMA library is installed using pip.
6 |
7 | To do this:
8 |
9 | 1. download repository from `https://github.com/scrat-online/pySTARMA`
10 |
11 | 2. run:
12 |
13 | .. code-block:: python
14 |
15 | pip install //path to downloaded repository//pySTARMA
16 |
17 |
18 | :Authors: Andreas Wolf
19 | :Date: 2017/06/24
20 | :Version: 1.0
21 |
--------------------------------------------------------------------------------
/docs/manual.rst:
--------------------------------------------------------------------------------
1 | Manual pySTARMA
2 | ================
3 | This file contains the manual for using the pySTARMA library
4 |
5 | SPACE TIME ARMA (STARMA Object)
6 | -----------------
7 | Description
8 | ~~~~~~~~~~~~~~~~~~~~~~
9 | The **STARMA class** can be used to estimate **STARMA models**. The method ``STARMA.fit()`` performs the estimation of the model parameters. The method ``STARMA.predict()`` executes the forecast (still in the development stage). The method ``STARMA.get_model()`` returns the full model. The ``STARMA.get_item()`` method returns a selected property of the model (`see Return Values STARMA`_).
10 |
11 | Usage
12 | ~~~~~~~~~~~~~~~~~~~~~~
13 | .. code-block:: python
14 |
15 | model = sm.STARMA(p, q, ts_matrix, wa_matrices, iterations(optional))
16 | model.fit()
17 | model.get_model()
18 | model.get_item()
19 |
20 | Example
21 | ~~~~~~~~~~~~~~~~~~~~~~
22 | .. code-block:: python
23 |
24 | from pySTARMA import starma_model as sm
25 |
26 | #Create instance of STARMA
27 | model = sm.STARMA(5, 2, time_series, wa_matrices, 3)
28 |
29 | #Estimate parameters
30 | model.fit()
31 |
32 | #Print explicit item
33 | print(model.get_item('bic'))
34 |
35 | Attributes
36 | ~~~~~~~~~~~~~~~~~~~~~~
37 | +---------------------+---------------------------------------------+
38 | | Attribute | Value |
39 | +=====================+=============================================+
40 | |p | Number or list of autoregressive parameters |
41 | +---------------------+---------------------------------------------+
42 | |q | Number or list of moving average parameters |
43 | +---------------------+---------------------------------------------+
44 | |ts_matrix | Time series matrix |
45 | +---------------------+---------------------------------------------+
46 | |wa_matrices | List of adjacency matrices |
47 | +---------------------+---------------------------------------------+
48 | |iterations(optional) | Number of iteration of kalman filtering, |
49 | | | only for estimation of moving average |
50 | | | parameters |
51 | +---------------------+---------------------------------------------+
52 |
53 | Return Values
54 | ~~~~~~~~~~~~~~~~~~~~~~
55 |
56 | .. _`see Return Values STARMA`:
57 |
58 | A dictionary is returned as a 'model' with the following values:
59 |
60 | +---------------------+---------------------------------------------+
61 | | Value | Description |
62 | +=====================+=============================================+
63 | |residuals | Matrix with estimated residuals |
64 | +---------------------+---------------------------------------------+
65 | |phi | Matrix with estimated AR-parameters |
66 | +---------------------+---------------------------------------------+
67 | |phi_tvalue | Matrix with estimated AR-t-values |
68 | +---------------------+---------------------------------------------+
69 | |phi_pvalue | Matrix with estimated AR-p-values |
70 | +---------------------+---------------------------------------------+
71 | |theta | Matrix with estimated MA-parameters |
72 | +---------------------+---------------------------------------------+
73 | |theta_tvalue | Matrix with estimated MA-t-values |
74 | +---------------------+---------------------------------------------+
75 | |theta_pvalue | Matrix with estimated MA-p-values |
76 | +---------------------+---------------------------------------------+
77 | |sigma2 | Standard deviation |
78 | +---------------------+---------------------------------------------+
79 | |bic | Bayesian information criterion |
80 | +---------------------+---------------------------------------------+
81 |
82 | SPACE TIME ARIMA (STARIMA Object)
83 | -----------------
84 |
85 | Description
86 | ~~~~~~~~~~~
87 | The **STARIMA class** can be used to estimate **STARIMA models**. The method ``STARIMA.fit()`` performs the estimation of the parameters. The method ``STARIMA.predict()`` executes the forecast (still in the development stage). The method ``STARIMA.get_model()`` returns the full model. The ``STARIMA.get_item()`` method returns a selected property of the model (`see Return Values STARIMA`_).
88 |
89 | Usage
90 | ~~~~~~
91 | .. code-block:: python
92 |
93 | model = sm.STARIMA(p, q, d, ts_matrix, wa_matrices, iterations(optional))
94 | model.fit()
95 | model.get_model()
96 | model.get_item()
97 |
98 | Example
99 | ~~~~~~~~~~~~~~~~~~~~~~
100 | .. code-block:: python
101 |
102 | from pySTARMA import starma_model as sm
103 |
104 | #Create instance of STARIMA
105 | model = sm.STARMA(5, 2, (1,), time_series, wa_matrices, 3)
106 |
107 | #Estimate parameters
108 | model.fit()
109 |
110 | #Print explicit item
111 | print(model.get_item('bic'))
112 |
113 | Attributes
114 | ~~~~~~~~~~~~~~~~~~~~~~
115 | +---------------------+---------------------------------------------+
116 | | Attribute | Value |
117 | +=====================+=============================================+
118 | |p | Number or list of autoregressive parameters |
119 | +---------------------+---------------------------------------------+
120 | |q | Number or list of moving average parameters |
121 | +---------------------+---------------------------------------------+
122 | |d | List of numbers of differentiations |
123 | +---------------------+---------------------------------------------+
124 | |ts_matrix | Time series matrix |
125 | +---------------------+---------------------------------------------+
126 | |wa_matrices | List of adjacency matrices |
127 | +---------------------+---------------------------------------------+
128 | |iterations(optional) | Number of iteration of kalman filtering, |
129 | | | only for estimation of moving average |
130 | | | parameters |
131 | +---------------------+---------------------------------------------+
132 |
133 | Return Values
134 | ~~~~~~~~~~~~~~~~~~~~~~
135 |
136 | .. _`see Return Values STARIMA`:
137 |
138 | A dictionary is returned as a 'model' with the following values:
139 |
140 | +---------------------+---------------------------------------------+
141 | | Value | Description |
142 | +=====================+=============================================+
143 | |residuals | Matrix with estimated residuals |
144 | +---------------------+---------------------------------------------+
145 | |phi | Matrix with estimated AR-parameters |
146 | +---------------------+---------------------------------------------+
147 | |phi_tvalue | Matrix with estimated AR-t-values |
148 | +---------------------+---------------------------------------------+
149 | |phi_pvalue | Matrix with estimated AR-p-values |
150 | +---------------------+---------------------------------------------+
151 | |theta | Matrix with estimated MA-parameters |
152 | +---------------------+---------------------------------------------+
153 | |theta_tvalue | Matrix with estimated MA-t-values |
154 | +---------------------+---------------------------------------------+
155 | |theta_pvalue | Matrix with estimated MA-p-values |
156 | +---------------------+---------------------------------------------+
157 | |sigma2 | Standard deviation |
158 | +---------------------+---------------------------------------------+
159 | |bic | Bayesian information criterion |
160 | +---------------------+---------------------------------------------+
161 |
162 |
163 |
164 | Space Time Autocorrelation Function (STACF Object)
165 | -----------------
166 |
167 | Description
168 | ~~~~~~~~~~~~~~~~~~~~~~
169 | With the **STACF class**, the space-time-autocorrelation-function can be estimated.
170 |
171 | Usage
172 | ~~~~~~~~~~~~~~~~~~~~~~
173 | .. code-block:: python
174 |
175 | stacf = Stacf(ts_matrix, wa_matrices, t_lags)
176 | stacf.estimate()
177 | stacf.get()
178 |
179 | Example
180 | ~~~~~~~~~~~~~~~~~~~~~~
181 | .. code-block:: python
182 |
183 | from pySTARMA import stacf_stpacf as st
184 |
185 | #Create instance of STACF
186 | stacf = st.Stacf(time_series, weight_matrices, 25)
187 |
188 | #Estimate STACF
189 | stacf.estimate()
190 |
191 | #Print estimated STACF
192 | print(stacf.get())
193 |
194 | Attributes
195 | ~~~~~~~~~~~~~~~~~~~~~~
196 | +---------------------+---------------------------------------------+
197 | | Attribute | Value |
198 | +=====================+=============================================+
199 | |ts_matrix | Time series matrix |
200 | +---------------------+---------------------------------------------+
201 | |wa_matrices | List of adjecency matrices |
202 | +---------------------+---------------------------------------------+
203 | |t_lags | Number of time lags |
204 | +---------------------+---------------------------------------------+
205 |
206 | Return Values
207 | ~~~~~~~~~~~~~~~~~~~~~~
208 | List with lists for each spatial lag. Spatial lags lists contains the estimated spatial autocorrelation for the corresponding time lag.
209 |
210 | List index 0 --> time lag 0 etc..
211 |
212 | Space Time Partial Autocorrelation Function (STPACF-Object)
213 | -----------------
214 |
215 | Description
216 | ~~~~~~~~~~~~~~~~~~~~~~
217 | With the **STPACF class**, the space-time-partial-autocorrelation-function can be estimated.
218 |
219 | Usage
220 | ~~~~~~~~~~~~~~~~~~~~~~
221 | .. code-block:: python
222 |
223 | stpacf = Stpacf(ts_matrix, wa_matrices, t_lags)
224 | stpacf.estimate()
225 | stpacf.get()
226 |
227 | Example
228 | ~~~~~~~~~~~~~~~~~~~~~~
229 | .. code-block:: python
230 |
231 | from pySTARMA import stacf_stpacf as st
232 |
233 | #Create instance of STACF
234 | stpacf = st.Stpacf(time_series, weight_matrices, 25)
235 |
236 | #Estimate STACF
237 | stpacf.estimate()
238 |
239 | #Print estimated STACF
240 | print(stpacf.get())
241 |
242 | Attributes
243 | ~~~~~~~~~~~~~~~~~~~~~~
244 | +---------------------+---------------------------------------------+
245 | | Attribute | Value |
246 | +=====================+=============================================+
247 | |ts_matrix | Time series matrix |
248 | +---------------------+---------------------------------------------+
249 | |wa_matrices | List of adjecency matrices |
250 | +---------------------+---------------------------------------------+
251 | |t_lags | Number of time lags |
252 | +---------------------+---------------------------------------------+
253 |
254 | Return Values
255 | ~~~~~~~~~~~~~~~~~~~~~~
256 | List with lists for each spatial lag. Spatial lags lists contains the estimated spatial autocorrelation for the corresponding time lag.
257 |
258 | List index 0 --> time lag 0 etc..
259 |
260 |
261 | :Authors: Andreas Wolf
262 | :Date: 2017/06/24
263 | :Version: 1.0
264 |
--------------------------------------------------------------------------------
/docs/pySTARMA_Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/scrat-online/pySTARMA/707d9732582c6937410747867d4387b04d8e846a/docs/pySTARMA_Logo.png
--------------------------------------------------------------------------------
/pySTARMA/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | Project:
3 | File: __init__.py
4 |
5 | Created by Scrat on 04.04.2017
6 | """
7 |
--------------------------------------------------------------------------------
/pySTARMA/stacf_stpacf.py:
--------------------------------------------------------------------------------
1 | """
2 | Project:
3 | File: stacf_stpacf
4 |
5 | Created by Scrat on 04.04.2017
6 | """
7 |
8 |
9 | import math
10 | import numpy as np
11 |
12 |
13 | class Stacf:
14 | def __init__(self, ts_matrix, wa_matrices, t_lags):
15 | self._ts_matrix = ts_matrix
16 | self._wa_matrices = wa_matrices
17 | self._t_lags = t_lags
18 | self._s_lags = len(self._wa_matrices)
19 | self._stacf = None
20 |
21 | @staticmethod
22 | def _st_cov(ts_matrix, w1, w2, t_lag):
23 | """
24 |
25 | :param ts_matrix:
26 | :param w1:
27 | :param w2:
28 | :param t_lag:
29 | :return:
30 | """
31 | max_lags = ts_matrix.shape[0] - t_lag
32 | gamma = 0
33 | power_wn = w2.T.dot(w1)
34 |
35 | for t in range(0, max_lags):
36 | gamma += (power_wn.dot(ts_matrix[[t + t_lag]].T.dot(ts_matrix[[t]]))).trace()
37 |
38 | gamma = gamma / max_lags * ts_matrix.shape[1]
39 | return gamma
40 |
41 | def _st_acf(self, ts_matrix, wa_matrices, t_lags):
42 | """
43 |
44 | :param ts_matrix:
45 | :param wa_matrices:
46 | :param t_lags:
47 | :return:
48 | """
49 | st_acf = np.zeros((t_lags, len(wa_matrices)))
50 |
51 | cov000 = self._st_cov(ts_matrix, wa_matrices[0], wa_matrices[0], 0)
52 | for idx, w in enumerate(wa_matrices):
53 | covss0 = self._st_cov(ts_matrix, w, w, 0)
54 | for t in range(1, t_lags + 1):
55 | covs0t = self._st_cov(ts_matrix, w, wa_matrices[0], t)
56 | st_acf[t - 1, idx] = covs0t / math.sqrt(covss0 * cov000)
57 | return st_acf
58 |
59 | def estimate(self):
60 | self._stacf = self._st_acf(self._ts_matrix, self._wa_matrices, self._t_lags)
61 | return self._stacf
62 |
63 | def get(self):
64 | return self._stacf
65 |
66 |
67 | class Stpacf(Stacf):
68 | def __init__(self, ts_matrix, wa_matrices, t_lags):
69 | Stacf.__init__(self, ts_matrix, wa_matrices, t_lags)
70 |
71 | def _st__mat(self, t_lag):
72 | """
73 |
74 | :param t_lag:
75 | :return: Matrix
76 | """
77 | stmat = np.zeros((self._s_lags, self._s_lags))
78 |
79 | for idx, wm in enumerate(self._wa_matrices):
80 | for jdx, wn in enumerate(self._wa_matrices):
81 | stmat[idx, jdx] = self._st_cov(self._ts_matrix, wm, wn, t_lag)
82 | return stmat
83 |
84 | def _st_mat(self):
85 | """
86 |
87 | :param t_lags:
88 | :return: Matrix
89 | """
90 | s_lag = self._s_lags
91 | t_lag = self._t_lags
92 |
93 | slideye = np.eye(t_lag, 2 * t_lag - 1)
94 | stmat = np.zeros((s_lag * t_lag, s_lag * t_lag))
95 | for t in range(1, t_lag - 1):
96 | stmat = stmat + np.kron(slideye[0:t_lag, t:t + t_lag], self._st__mat(t))
97 |
98 | stmat = stmat + np.transpose(stmat)
99 | stmat += np.kron(np.eye(t_lag, t_lag), self._st__mat(0))
100 | return stmat
101 |
102 | def _st_vec(self):
103 | """
104 |
105 | :return: Vector
106 | """
107 | st_vec = np.zeros((self._s_lags * self._t_lags))
108 | for t in range(1, self._t_lags + 1):
109 | for s, wm in enumerate(self._wa_matrices):
110 | st_vec[(t - 1) * self._s_lags + s] = self._st_cov(self._ts_matrix, wm, self._wa_matrices[0], t)
111 | return st_vec
112 |
113 | def _st_pacf(self):
114 | """
115 |
116 | :return: Matrix
117 | """
118 | print('create yule-walker matrix')
119 | YWmat = self._st_mat()
120 | print('create yule-walker vector')
121 | YWvec = self._st_vec()
122 |
123 | s_lag = self._s_lags
124 | t_lag = self._t_lags
125 |
126 | st_pacf = np.zeros((t_lag, s_lag))
127 |
128 | print('solve yule-walker equitation')
129 | for t in range(0, t_lag):
130 | for s in range(0, s_lag):
131 | index = t * s_lag + s
132 | sol = np.linalg.solve(YWmat[:index + 1, :index + 1], YWvec[:index + 1])
133 | st_pacf[t, s] = sol[index]
134 | return st_pacf
135 |
136 | def estimate(self):
137 | self._stacf = self._st_pacf()
138 | return self._stacf
139 |
--------------------------------------------------------------------------------
/pySTARMA/starma_model.py:
--------------------------------------------------------------------------------
1 | """
2 | Project:
3 | File: STARIMA
4 |
5 | Created by Scrat on 02.03.2017
6 | """
7 |
8 | import numpy as np
9 | from prettytable import PrettyTable
10 |
11 | from pySTARMA import utils
12 | from pySTARMA.utils import set_stationary
13 |
14 |
15 | class STARMA:
16 | def __init__(self, p, q, ts_matrix, wa_matrices, iterations=2):
17 | """
18 | Initialising object/Instance of type STARMA
19 | :param p: Number or list of auto-regressive-parameters
20 | :param q: Number or list of moving-average-parameters
21 | :param ts_matrix: Time series matrix
22 | :param wa_matrices: List of adjacency matrices
23 | :param iterations: Number of iterations for kalman filter
24 | :param cls_name: Name of class or user specified model name
25 | """
26 | self._p = p
27 | self._q = q
28 | self._wa_matrices = wa_matrices
29 | self._ts_matrix = ts_matrix
30 | self._iter = iterations
31 | self._max_p_tlag = self._get_max_tlag(p)
32 | self._max_q_tlag = self._get_max_tlag(q)
33 | self._max_tlag = max(self._max_p_tlag, self._max_q_tlag)
34 | self._model = None
35 |
36 | def __str__(self):
37 | if self._model is not None:
38 | return 'No model fitted yet'
39 | else:
40 | return 'Object of class STARMA/STARIMA ' \
41 | '\n\t AR-Orders: %s ' \
42 | '\n\t MA-Orders: %s ' \
43 | % (self._p, self._q)
44 |
45 | @staticmethod
46 | def _get_max_tlag(x):
47 | """
48 | Get maximum time lag of ar- or ma-parameters
49 | :param x: Number or list of ar- or ma-parameters
50 | :return: maximum time lag
51 | """
52 | if type(x) is list:
53 | return max(x) + 1
54 | else:
55 | return x
56 |
57 | @staticmethod
58 | def _get_order_matrix(tlag, slag):
59 | """
60 | Generates an matrix containing the indices of the parameters to estimate
61 | :param tlag: time lag
62 | :param slag: spatial lag
63 | :return: matrix with time and spatial orders
64 | """
65 | iterate = 0
66 | if type(tlag) is list:
67 | order_matrix = np.empty([2, len(tlag) * slag], dtype=int)
68 | for i, t in enumerate(tlag):
69 | for s in range(0, slag):
70 | order_matrix[0, iterate] = t
71 | order_matrix[1, iterate] = s
72 | iterate += 1
73 | else:
74 | order_matrix = np.empty([2, tlag * slag], dtype=int)
75 | for t in range(tlag):
76 | for s in range(slag):
77 | order_matrix[0, iterate] = t
78 | order_matrix[1, iterate] = s
79 | iterate += 1
80 |
81 | return order_matrix
82 |
83 | def _get_ma_matrix(self):
84 | """
85 | Get matrix of ma-order with indices of time-lag and spatial lag
86 | :return: matrix of ma-order-indices
87 | """
88 | return self._get_order_matrix(self._q, len(self._wa_matrices))
89 |
90 | def _get_ar_matrix(self):
91 | """
92 | Get matrix of ar-order with indices of time-lag and spatial lag
93 | :return: matrix of ar-order-indices
94 | """
95 | return self._get_order_matrix(self._p, len(self._wa_matrices))
96 |
97 | def _get_total_parameter(self):
98 | """
99 | Get the total count of parameter to estimate
100 | :return: Number of total parameter
101 | """
102 | return len(self._get_ar_matrix()) + len(self._get_ma_matrix())
103 |
104 | def _fit_model(self, ts_matrix):
105 | """
106 | Implementation of the Kalman Filter by Cipra & Motykova - Study on Kalman filter in time series anlysis (1987) and Cheysson - starma: Modelling Space Time AutoRegressive Moving Average (STARMA) Processes
107 | """
108 | print('Model fitting in progress')
109 | print(self.__str__())
110 |
111 | # run kalman filter
112 | # first iteration
113 | eps = ts_matrix.copy()
114 | self._model = utils.kalmanfilter_estimation(ts_matrix,
115 | self._wa_matrices,
116 | eps,
117 | self._get_ar_matrix(),
118 | self._get_ma_matrix(),
119 | self._max_p_tlag,
120 | self._max_q_tlag,
121 | self._max_tlag)
122 |
123 | # if ma orders present, do further iteration
124 | if self._q > 0:
125 | count = 0
126 | while self._iter > count:
127 | eps[0: self._max_tlag] = utils.residuals_estimation(ts_matrix[0:self._max_tlag],
128 | self._wa_matrices,
129 | self._model['phi'],
130 | self._model['theta'])
131 |
132 | self._model = utils.kalmanfilter_estimation(ts_matrix,
133 | self._wa_matrices,
134 | eps,
135 | self._get_ar_matrix(),
136 | self._get_ma_matrix(),
137 | self._max_p_tlag,
138 | self._max_q_tlag,
139 | self._max_tlag)
140 |
141 | count += 1
142 |
143 | # write information to model
144 | self._model['timeseries'] = ts_matrix
145 | self._model['residuals'] = utils.residuals_estimation(ts_matrix, self._wa_matrices, self._model['phi'],
146 | self._model['theta'])
147 | self._model['sigma2'] = np.trace(self._model['sigma2VarianceMatrix']) / len(self._model['sigma2VarianceMatrix'])
148 | self._model['llh'] = utils.loglikelihood(self._model) + np.log(
149 | ts_matrix.size * ((self._get_total_parameter()) * len(self._wa_matrices)))
150 | self._model['bic'] = self._get_total_parameter() * np.log(ts_matrix.size) - 2 * self._model['llh']
151 | self._model['phi_tvalue'] = self._model['phi'] / self._model['phi_sd']
152 | self._model['theta_tvalue'] = self._model['theta'] / self._model['theta_sd']
153 | self._model['phi_pvalue'] = self._p_value(self._model['phi_tvalue'])
154 | self._model['theta_pvalue'] = self._p_value(self._model['theta_tvalue'])
155 |
156 | def _p_value(self, t_value):
157 | """
158 | TODO check if calculation is correct with tvalue = paramter / std and pavalue with df as totalparameter and not
159 | as total observations - totalparameter
160 | :param t_value:
161 | :return: p-value of parameter
162 | """
163 | from scipy.stats import t as t_dist
164 | df = (self._ts_matrix.size) - (self._get_total_parameter() * len(self._wa_matrices))
165 | # TODO check calculation of p-values with degrees of freedom
166 | # p_value = tdist.pdf(abs(tvalue), self._total_parameter())
167 | return t_dist.pdf(abs(t_value), df)
168 |
169 | def fit(self):
170 | """
171 | Estimate parameter for model
172 | """
173 | self._fit_model(self._ts_matrix)
174 |
175 | def predict(self, ts_matrix, t_lags):
176 | """
177 | Estimate forecasting for model
178 | :param ts_matrix: Time series matrix
179 | :param t_lags: Maximum time lags in future
180 | :return: Matrix with predictions
181 | """
182 | return utils.prediction(ts_matrix
183 | , self._wa_matrices
184 | , self._model['phi']
185 | , self._model['theta']
186 | , t_lags)
187 |
188 | def print_results(self):
189 | """
190 | Print model results to screen
191 | """
192 | if self._model != 0:
193 | #table = PrettyTable(['coefficients', 'parameter', 'std deviation', 't-value', 'p-value'])
194 | #for i in range(0, len(self._model['phi'])):
195 | # table.add_row(i)
196 | #for i in range(0, len(self._model['theta'])):
197 | # table.add_row(i)
198 | #print table
199 | print('sigma2 is estimated as:\t\t %s' % self._model['sigma2'])
200 | print('standard error is estimated as:\t\t %s' % np.sqrt(self._model['sigma2']))
201 | print('BIC is estimated as:\t\t %s' % self._model['bic'])
202 | print('LogLikelihood is estimated as:\t\t %s' % self._model['llh'])
203 |
204 | def get_model(self):
205 | """
206 | Get the model
207 | :return: model
208 | """
209 | return self._model
210 |
211 | def get_item(self, item):
212 | """
213 | Get specific item of model
214 | :param item: Key for item
215 | :return: Value
216 | """
217 | return self._model[item]
218 |
219 |
220 | class STARIMA(STARMA):
221 | def __init__(self, p, q, d, ts_matrix, wa_matrices, iterations=2):
222 | """
223 | Initialising object/Instance of type STARIMA
224 | :param p: Number or list of auto-regressive-parameters
225 | :param q: Number or list of moving-average-parameters
226 | :param d: Number or list of differencing
227 | :param ts_matrix: Time series matrix
228 | :param wa_matrices: List of adjacency matrices
229 | :param iterations: Number of iterations for kalman filter
230 | """
231 | STARMA.__init__(self, p, q, ts_matrix, wa_matrices, iterations)
232 | self._ts = ts_matrix
233 | self._d = d # Number of Differencing
234 |
235 | def __str__(self):
236 | return STARMA.__str__(self) + \
237 | '\n\t Difference: %s ' \
238 | % (self._d,)
239 |
240 | def fit(self):
241 | """
242 | Estimate parameter for model
243 | """
244 | self._ts = set_stationary(self._ts, self._d)
245 | self._fit_model(self._ts)
246 |
--------------------------------------------------------------------------------
/pySTARMA/utils.py:
--------------------------------------------------------------------------------
1 | """
2 | Project:
3 | File: diagnostic
4 |
5 | Created by Scrat on 04.04.2017
6 | """
7 | import numpy as np
8 | import math
9 |
10 | import pandas as pd
11 | from numpy.linalg import inv
12 |
13 |
14 | def loglikelihood(model):
15 | """
16 | Calculates Log-Likelihood of model
17 | :param ts_matrix: Matrix of timeseries
18 | :param model: Estimated model
19 | :return: log-likelihood
20 | """
21 | res = model['residuals']
22 | ts_cols = len(res[0])
23 | ts_rows = len(res)
24 | sigma2 = model['sigma2']
25 |
26 | llh = ts_cols * ts_rows * (np.log(2 * math.pi) + np.log(sigma2))
27 |
28 | for t in range(ts_rows):
29 | llh += res[[t]].dot(1 / sigma2).dot(res[[t]].T)
30 | return -llh / 2
31 |
32 |
33 | def prediction(ts_matrix, wa_matrices, phi, theta, prediction_lag=1):
34 | """
35 | Calcuates predictions for time series matrix
36 | :param ts_matrix: time series matrix
37 | :param wa_matrices: list of adjacency matrices
38 | :param phi: parameters phi
39 | :param theta: parameters theta
40 | :param prediction_lag: maximum prediction lag
41 | :return:
42 | """
43 | predictions = ts_matrix[:ts_matrix.shape[0] - prediction_lag, :].copy()
44 | residuals = residuals_estimation(predictions, wa_matrices, phi, theta)
45 |
46 | for h in range(prediction_lag):
47 | predict = 0
48 | for tlag in range(len(phi)):
49 | for slag in range(len(phi[0])):
50 | predict += (predictions[[- tlag - 1]] * phi[tlag, slag]).dot(wa_matrices[slag].T)
51 | for tlag in range(len(theta)):
52 | for slag in range(len(theta[0])):
53 | predict -= (residuals[[- tlag - 1]] * theta[tlag, slag]).dot(wa_matrices[slag].T)
54 | # TODO implement recursive innovation algorithm to update innovations/errors in prediction
55 | residuals = np.concatenate((residuals, np.zeros([1, len(residuals[0])])), axis=0)
56 | predictions = np.concatenate((predictions, predict), axis=0)
57 |
58 | return predictions
59 |
60 |
61 | def kalmanfilter_estimation(ts_matrix, wa_matrices, residuals, ar_matrix, ma_matrix, p_lag, q_lag, max_t_lag):
62 | """
63 | Estimate parameters and variance with kalman filtering. After implementation of the Kalman Filter
64 | by Cipra & Motykova - Study on Kalman filter in time series anlysis (1987) and
65 | Cheysson - starma: Modelling Space Time AutoRegressive Moving Average (STARMA) Processes
66 | :param p_lag: maximum auto regressive parameter
67 | :param max_t_lag: maximum time lag
68 | :param ts_matrix: time series matrix
69 | :param wa_matrices: list of adjacency matrices
70 | :param residuals: calculated residuals
71 | :param ar_matrix: matrix with indexes for auto regressive parameters to estimate
72 | :param ma_matrix: matrix with indexes for moving average parameters to estimate
73 | :param q_lag: maximum moving average parameter
74 | :return: ar-parameters, ar_std, ma-parameters, ma-std, variance matrix
75 | """
76 | # get variables
77 | ar = len(ar_matrix[0])
78 | ma = len(ma_matrix[0])
79 | dim = ar + ma
80 |
81 | # initialise kalman filter
82 | h = np.zeros([dim, ts_matrix.shape[1]])
83 | ksi = np.zeros(dim, )
84 | p = 100000. * np.eye(dim, dim)
85 | sigma2 = (1 / 100000.) * np.eye(ts_matrix.shape[1], ts_matrix.shape[1])
86 |
87 | # run the filter
88 | for t in range(max_t_lag, ts_matrix.shape[0]):
89 | # Update the observation matrix
90 | # Fill for 'phi', AR parameters
91 | for it in range(ar):
92 | weights = wa_matrices[ar_matrix[1, it]]
93 | h[it] = (ts_matrix[[t - 1 - ar_matrix[0, it]], :]).dot(weights.T)
94 |
95 | # Fill for 'theta', MA parameters
96 | for it in range(ar, dim):
97 | weights = wa_matrices[ma_matrix[1, it - ar]]
98 | h[it] = (residuals[[t - 1 - ma_matrix[0, it - ar]], :]).dot(weights.T)
99 |
100 | # Create
101 | nm1 = inv(h.T.dot(p).dot(h) + np.eye(ts_matrix.shape[1], ts_matrix.shape[1]))
102 | nu = ts_matrix[t].T - h.T.dot(ksi)
103 | # Prediction & update equations all - in -ones
104 | ksi += p.dot(h).dot(nm1).dot(nu) # 2.28 Cipra & Motykova 1987
105 | p -= p.dot(h).dot(nm1).dot(h.T).dot(p) # 2.29 Cipra & Motykova 1987
106 | sigma2 = (sigma2 * (t + 1 - max_t_lag) + nu.T * nu) / (t + 2 - max_t_lag) # 2.30 Cipra & Motykova 1987
107 | # Estimate the residual
108 | residuals[[t]] = ts_matrix[[t]] - (ksi.T.dot(h)) # 2.31 Cipra & Motykova 1987
109 |
110 | # Get estimated standard deviation of the parameters
111 | sd = np.sqrt(np.trace(sigma2) * np.diag(p) / ts_matrix.shape[1])
112 |
113 | # Rename and reshape
114 | phi = np.zeros([p_lag, len(wa_matrices)])
115 | phi_sd = np.zeros([p_lag, len(wa_matrices)])
116 | theta = np.zeros([q_lag, len(wa_matrices)])
117 | theta_sd = np.zeros([q_lag, len(wa_matrices)])
118 |
119 | for it in range(ar):
120 | phi[ar_matrix[0, it], ar_matrix[1, it]] = ksi[it];
121 | phi_sd[ar_matrix[0, it], ar_matrix[1, it]] = sd[it];
122 | pass
123 |
124 | for it in range(ar, dim):
125 | theta[ma_matrix[0, it - ar], ma_matrix[1, it - ar]] = ksi[it];
126 | theta_sd[ma_matrix[0, it - ar], ma_matrix[1, it - ar]] = sd[it];
127 | pass
128 |
129 | return {'phi': phi,
130 | 'phi_sd': phi_sd,
131 | 'theta': theta,
132 | 'theta_sd': theta_sd,
133 | 'sigma2VarianceMatrix': sigma2, }
134 |
135 |
136 | def residuals_estimation(ts_matrix, wa_matrices, phi, theta):
137 | """
138 | Calculation of residuals for model
139 | :param ts_matrix: time series matrix
140 | :param wa_matrices: list of adjacency matrices
141 | :param phi: auto regressive parameters
142 | :param theta: moving average parameters
143 | :return: residual matrix
144 | """
145 | residuals = ts_matrix.copy()
146 | for t in range(ts_matrix.shape[0]):
147 | t_lim = min([t, len(phi)])
148 | for t_lag in range(t_lim):
149 | for slag in range(0, len(phi[0])):
150 | weights = wa_matrices[slag]
151 | residuals[[t]] -= (ts_matrix[[t - t_lag - 1]] * phi[t_lag, slag]).dot(weights.T)
152 |
153 | t_lim = min([t, len(theta)])
154 | for t_lag in range(t_lim):
155 | for slag in range(0, len(theta[0])):
156 | weights = wa_matrices[slag]
157 | residuals[[t]] -= (residuals[[t - t_lag - 1]] * theta[t_lag, slag]).dot(weights.T)
158 | return residuals
159 |
160 |
161 | def set_stationary(ts_matrix, lags):
162 | """
163 | Differencing of time series
164 | :param ts_matrix: time series matrix
165 | :param lags: list of differencing
166 | :return: difference time series matrix
167 | """
168 | time_series_matrix = pd.DataFrame(ts_matrix).copy()
169 | for t_lag in lags:
170 | time_series_matrix -= time_series_matrix.shift(t_lag)
171 | time_series_matrix.dropna(inplace=True)
172 | return time_series_matrix.as_matrix()
173 |
174 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | """
2 | Project:
3 | File: setup
4 |
5 | Created by Scrat on 11.05.2017
6 | """
7 |
8 | from setuptools import setup
9 |
10 |
11 | with open('README.md') as f:
12 | readme = f.read()
13 |
14 | with open('LICENSE') as f:
15 | license = f.read()
16 |
17 | setup(
18 | name='pySTARMA',
19 | version='0.1.1',
20 | description='',
21 | long_description=readme,
22 | author='Andreas Wolf',
23 | author_email='andreas.wolf.ke@gmail.com',
24 | url='https://github.com/scrat-online/pySTARMA.git',
25 | license=license,
26 | packages=['pySTARMA'],
27 | install_requires=['numpy', 'pandas', 'prettytable'],
28 | )
--------------------------------------------------------------------------------