├── .gitignore
├── .vscode
└── tags
├── LICENSE
├── README.md
├── example.py
├── greytheory
├── __init__.py
└── packages
│ ├── __init__.py
│ ├── libs
│ ├── __init__.py
│ ├── grey_lib.py
│ └── grey_math.py
│ └── models
│ ├── __init__.py
│ ├── grey_class.py
│ ├── grey_factory.py
│ ├── grey_forecast.py
│ ├── grey_gm0n.py
│ ├── grey_gm11.py
│ ├── grey_gm1n.py
│ └── grey_run.py
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | dist
3 | *.pyc
4 | greytheory.egg-info
5 |
--------------------------------------------------------------------------------
/.vscode/tags:
--------------------------------------------------------------------------------
1 | !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
2 | !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
3 | !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
4 | !_TAG_PROGRAM_NAME Exuberant Ctags //
5 | !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
6 | !_TAG_PROGRAM_VERSION 5.8 //
7 | GreyClass ../packages/models/grey_class.py /^class GreyClass (object):$/;" kind:class line:7
8 | GreyFactory ../packages/models/grey_class.py /^from grey_factory import GreyFactory$/;" kind:namespace line:4
9 | GreyFactory ../packages/models/grey_factory.py /^class GreyFactory:$/;" kind:class line:2
10 | GreyForecast ../packages/models/grey_class.py /^from grey_forecast import GreyForecast$/;" kind:namespace line:5
11 | GreyForecast ../packages/models/grey_forecast.py /^class GreyForecast:$/;" kind:class line:2
12 | GreyGM0N ../grey_theory.py /^from packages.models.grey_gm0n import GreyGM0N$/;" kind:namespace line:1
13 | GreyGM0N ../packages/models/grey_gm0n.py /^class GreyGM0N (GreyClass):$/;" kind:class line:3
14 | GreyGM11 ../grey_theory.py /^from packages.models.grey_gm11 import GreyGM11$/;" kind:namespace line:3
15 | GreyGM11 ../packages/models/grey_gm11.py /^class GreyGM11 (GreyClass):$/;" kind:class line:4
16 | GreyGM1N ../grey_theory.py /^from packages.models.grey_gm1n import GreyGM1N$/;" kind:namespace line:2
17 | GreyGM1N ../packages/models/grey_gm1n.py /^class GreyGM1N (GreyClass):$/;" kind:class line:3
18 | GreyLib ../packages/libs/grey_lib.py /^class GreyLib:$/;" kind:class line:3
19 | GreyLib ../packages/models/grey_class.py /^from ..libs.grey_lib import GreyLib$/;" kind:namespace line:2
20 | GreyMath ../packages/libs/grey_math.py /^class GreyMath:$/;" kind:class line:3
21 | GreyMath ../packages/models/grey_class.py /^from ..libs.grey_math import GreyMath$/;" kind:namespace line:3
22 | GreyTheory ../example.py /^from grey_theory import GreyTheory$/;" kind:namespace line:1
23 | GreyTheory ../grey_theory.py /^class GreyTheory:$/;" kind:class line:5
24 | _TAG_FORECAST_HISTORY ../packages/models/grey_class.py /^ _TAG_FORECAST_HISTORY = "history"$/;" kind:variable line:10
25 | _TAG_FORECAST_NEXT_MOMENT ../packages/models/grey_class.py /^ _TAG_FORECAST_NEXT_MOMENT = "forecasted_next_moment"$/;" kind:variable line:9
26 | __forecast ../packages/models/grey_gm11.py /^ def __forecast(self, patterns, period=1):$/;" kind:member line:16
27 | __forecast_value ../packages/models/grey_gm11.py /^ def __forecast_value(self, x1, a_value, b_value, k):$/;" kind:member line:13
28 | __init__ ../grey_theory.py /^ def __init__(self):$/;" kind:member line:6
29 | __init__ ../packages/libs/grey_lib.py /^ def __init__(self, alpha=0.5):$/;" kind:member line:5
30 | __init__ ../packages/models/grey_class.py /^ def __init__(self):$/;" kind:member line:12
31 | __init__ ../packages/models/grey_gm11.py /^ def __init__(self):$/;" kind:member line:6
32 | __init__.py ../__init__.py 1;" kind:file line:1
33 | __init__.py ../packages/__init__.py 1;" kind:file line:1
34 | __init__.py ../packages/libs/__init__.py 1;" kind:file line:1
35 | __init__.py ../packages/models/__init__.py 1;" kind:file line:1
36 | _add_outputs ../packages/models/grey_class.py /^ def _add_outputs(self, outputs, pattern_key):$/;" kind:member line:21
37 | _add_patterns ../packages/models/grey_class.py /^ def _add_patterns(self, patterns, pattern_key):$/;" kind:member line:26
38 | add_outputs ../packages/models/grey_gm0n.py /^ def add_outputs(self, outputs, pattern_key):$/;" kind:member line:5
39 | add_outputs ../packages/models/grey_gm1n.py /^ def add_outputs(self, outputs, pattern_key):$/;" kind:member line:5
40 | add_pattern ../packages/models/grey_gm11.py /^ def add_pattern(self, pattern, pattern_key):$/;" kind:member line:10
41 | add_patterns ../packages/models/grey_gm0n.py /^ def add_patterns(self, patterns, pattern_key):$/;" kind:member line:8
42 | add_patterns ../packages/models/grey_gm1n.py /^ def add_patterns(self, patterns, pattern_key):$/;" kind:member line:8
43 | ago ../packages/libs/grey_lib.py /^ def ago(self, patterns):$/;" kind:member line:9
44 | ago ../packages/models/grey_class.py /^ def ago(self, patterns):$/;" kind:member line:30
45 | alpha ../packages/models/grey_class.py /^ def alpha(self):$/;" kind:member line:74
46 | alpha ../packages/models/grey_class.py /^ def alpha(self, value = 0.5):$/;" kind:member line:78
47 | analyze ../packages/models/grey_gm0n.py /^ def analyze(self):$/;" kind:member line:11
48 | analyze ../packages/models/grey_gm1n.py /^ def analyze(self):$/;" kind:member line:11
49 | average_error_rate ../packages/models/grey_forecast.py /^ average_error_rate = 0.0$/;" kind:variable line:9
50 | clean_forecasted ../packages/models/grey_gm11.py /^ def clean_forecasted(self):$/;" kind:member line:124
51 | continue_forecasting ../packages/models/grey_gm11.py /^ def continue_forecasting(self, last_forecasted_outputs = []):$/;" kind:member line:120
52 | equation_value ../packages/models/grey_factory.py /^ equation_value = ""$/;" kind:variable line:5
53 | error_rate ../packages/models/grey_forecast.py /^ error_rate = 0.0$/;" kind:variable line:8
54 | example.py ../example.py 1;" kind:file line:1
55 | forecast ../packages/models/grey_gm11.py /^ def forecast(self, period=1):$/;" kind:member line:75
56 | forecast_convolution ../packages/models/grey_gm11.py /^ def forecast_convolution(self, stride=1, length=4):$/;" kind:member line:80
57 | forecast_value ../packages/models/grey_forecast.py /^ forecast_value = 0.0$/;" kind:variable line:7
58 | gm0n ../example.py /^gm0n = grey.gm0n$/;" kind:variable line:6
59 | gm11 ../example.py /^gm11 = grey.gm11$/;" kind:variable line:36
60 | gm1n ../example.py /^gm1n = grey.gm1n$/;" kind:variable line:21
61 | grey ../example.py /^grey = GreyTheory()$/;" kind:variable line:3
62 | grey_class.py ../packages/models/grey_class.py 1;" kind:file line:1
63 | grey_factory.py ../packages/models/grey_factory.py 1;" kind:file line:1
64 | grey_forecast.py ../packages/models/grey_forecast.py 1;" kind:file line:1
65 | grey_gm0n.py ../packages/models/grey_gm0n.py 1;" kind:file line:1
66 | grey_gm11.py ../packages/models/grey_gm11.py 1;" kind:file line:1
67 | grey_gm1n.py ../packages/models/grey_gm1n.py 1;" kind:file line:1
68 | grey_lib.py ../packages/libs/grey_lib.py 1;" kind:file line:1
69 | grey_math.py ../packages/libs/grey_math.py 1;" kind:file line:1
70 | grey_theory.py ../grey_theory.py 1;" kind:file line:1
71 | k ../packages/models/grey_forecast.py /^ k = 0$/;" kind:variable line:5
72 | last_moment ../packages/models/grey_gm11.py /^ def last_moment(self):$/;" kind:member line:128
73 | math ../packages/models/grey_gm11.py /^import math$/;" kind:namespace line:2
74 | name ../packages/models/grey_factory.py /^ name = ""$/;" kind:variable line:4
75 | np ../packages/libs/grey_lib.py /^import numpy as np$/;" kind:namespace line:1
76 | np ../packages/libs/grey_math.py /^import numpy as np$/;" kind:namespace line:1
77 | np ../packages/models/grey_class.py /^import numpy as np$/;" kind:namespace line:1
78 | original_value ../packages/models/grey_forecast.py /^ original_value = 0.0$/;" kind:variable line:6
79 | print_analyzed_results ../packages/models/grey_class.py /^ def print_analyzed_results(self):$/;" kind:member line:47
80 | print_forecasted_results ../packages/models/grey_class.py /^ def print_forecasted_results(self):$/;" kind:member line:57
81 | print_influence_degrees ../packages/models/grey_class.py /^ def print_influence_degrees(self):$/;" kind:member line:52
82 | print_self ../packages/models/grey_class.py /^ def print_self(self):$/;" kind:member line:44
83 | ranking ../packages/models/grey_factory.py /^ ranking = ""$/;" kind:variable line:6
84 | remove_all_analysis ../packages/models/grey_class.py /^ def remove_all_analysis(self):$/;" kind:member line:33
85 | solve_equations ../packages/libs/grey_math.py /^ def solve_equations(self, equations, equals):$/;" kind:member line:6
86 | tag ../packages/models/grey_forecast.py /^ tag = ""$/;" kind:variable line:4
87 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Kuo-Ming Lin (Kalvar Lin)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## About
2 |
3 | Grey Theory System that means uncertain relationships between the various factors within the system, this system in which part of information is known and another part is unknown. This theory has 3 methods are : GM0N, GM1N, GM11.
4 |
5 | [Grey Relational Analysis](https://en.wikipedia.org/wiki/Grey_relational_analysis)
6 | [灰色系統理論](http://wiki.mbalib.com/zh-tw/%E7%81%B0%E8%89%B2%E7%B3%BB%E7%BB%9F%E7%90%86%E8%AE%BA)
7 | [灰色關聯分析](http://wiki.mbalib.com/zh-tw/%E7%81%B0%E8%89%B2%E5%85%B3%E8%81%94%E5%88%86%E6%9E%90)
8 | [灰色預測法](http://wiki.mbalib.com/zh-tw/%E7%81%B0%E8%89%B2%E9%A2%84%E6%B5%8B%E6%B3%95)
9 | [《Grey system theory-based models in time series prediction》2009.](http://www.mecha.ee.boun.edu.tr/Prof.%20Dr.%20Okyay%20Kaynak%20Publications/c%20Journal%20Papers(appearing%20in%20SCI%20or%20SCIE%20or%20CompuMath)/62.pdf)
10 | [改良式 GM(1,1)灰預測模型於台電電量需求預測之研究](http://www.engh.kuas.edu.tw/files/ne/pnz67gteh2.pdf)
11 |
12 | ## How to Install
13 | Now install version is 0.1.
14 | ```console
15 | pip3 install greytheory
16 | ```
17 |
18 | ## How to Use
19 |
20 | #### Import
21 | ``` python
22 | from greytheory import GreyTheory
23 | grey = GreyTheory()
24 | ```
25 |
26 | #### GM0N
27 | ``` python
28 |
29 | gm0n = grey.gm0n
30 |
31 | gm0n.add_outputs([1., 1., 1., 1., 1., 1.], "x1")
32 | gm0n.add_patterns([.75, 1.22, .2, 1., 1., 1.], "x2")
33 | gm0n.add_patterns([.5, 1., .7, .66, 1., .5], "x3")
34 | gm0n.add_patterns([1., 1.09, .4, .33, .66, .25], "x4")
35 | gm0n.add_patterns([.25, .99, 1., .66, .33, .25], "x5")
36 |
37 | gm0n.analyze()
38 |
39 | # Looks GM0N the results as below:
40 | gm0n.print_analyzed_results()
41 | """
42 | Pattern key: 'x3', grey value: 0.745169986457907, ranking: 1
43 | Pattern key: 'x4', grey value: 0.5714064714568454, ranking: 2
44 | Pattern key: 'x2', grey value: 0.501334367966725, ranking: 3
45 | Pattern key: 'x5', grey value: 0.49555636151070015, ranking: 4
46 | """
47 |
48 | gm0n.print_influence_degrees()
49 | """
50 | The keys of parameters their influence degrees (ordering): 'x3 > x4 > x2 > x5'
51 | """
52 | ```
53 |
54 | #### GM1N
55 | ``` python
56 | gm1n = grey.gm1n
57 |
58 | gm1n.add_outputs([2., 11., 1.5, 2., 2.2, 3.], "x1")
59 | gm1n.add_patterns([3., 13.5, 1., 3., 3., 4.], "x2")
60 | gm1n.add_patterns([2., 11., 3.5, 2., 3., 2.], "x3")
61 | gm1n.add_patterns([4., 12., 2., 1., 2., 1.], "x4")
62 | gm1n.add_patterns([1., 10., 5., 2., 1., 1.], "x5")
63 |
64 | gm1n.analyze()
65 |
66 | # Looks GM1N the results as below:
67 | gm1n.print_analyzed_results()
68 | """
69 | Pattern key: 'x1', grey value: 1.4385641363407546, ranking: 0
70 | Pattern key: 'x2', grey value: 1.3300049398977922, ranking: 1
71 | Pattern key: 'x4', grey value: 0.6084241725675539, ranking: 2
72 | Pattern key: 'x3', grey value: 0.5977013008400084, ranking: 3
73 | Pattern key: 'x5', grey value: 0.19277457599259723, ranking: 4
74 | """
75 |
76 | gm1n.print_influence_degrees()
77 | """
78 | The keys of parameters their influence degrees (ordering): 'x2 > x4 > x3 > x5'
79 | """
80 | ```
81 |
82 | #### GM11
83 | ``` python
84 | gm11 = grey.gm11
85 |
86 | gm11.add_pattern(223.3, "a1")
87 | gm11.add_pattern(227.3, "a2")
88 | gm11.add_pattern(230.5, "a3")
89 | gm11.add_pattern(238.1, "a4")
90 | gm11.add_pattern(242.9, "a5")
91 | gm11.add_pattern(251.1, "a6")
92 |
93 | gm11.period = 2 # Default is 1, the parameter means how many next moments need to forcast continually.
94 | gm11.forecast()
95 |
96 | # Looks GM11 the results for example as below:
97 | gm11.print_forecasted_results()
98 | """
99 | K = 1
100 | From original value 227.3 to forecasted value is 226.08736263692822
101 | The error rate is 0.005334964201811667
102 | K = 2
103 | From original value 230.5 to forecasted value is 231.87637984134398
104 | The error rate is 0.005971279138151739
105 | K = 3
106 | From original value 238.1 to forecasted value is 237.81362611881437
107 | The error rate is 0.0012027462460547044
108 | K = 4
109 | From original value 242.9 to forecasted value is 243.9028969077225
110 | The error rate is 0.00412884688234865
111 | K = 5
112 | From original value 251.1 to forecasted value is 250.14808482949547
113 | The error rate is 0.003790980368397134
114 | K = 6
115 | Forcated next moment value is 256.55318217699795
116 | K = 7
117 | Forcated next moment value is 263.1222834666411
118 | Forcated next moment value is 283.85614494317775
119 | The average error rate 0.0040857633673527785
120 | """
121 | ```
122 |
123 | #### GM11 Convolutional Forecasting
124 | ``` python
125 | gm11.convolution = True # To open convolution mode.
126 | gm11.stride = 1
127 | gm11.length = 4
128 |
129 | gm11.add_pattern(223.3, "a1")
130 | gm11.add_pattern(227.3, "a2")
131 | gm11.add_pattern(230.5, "a3")
132 | gm11.add_pattern(238.1, "a4")
133 | gm11.add_pattern(242.9, "a5")
134 | gm11.add_pattern(251.1, "a6")
135 |
136 | gm11.forecast()
137 | ```
138 |
139 | #### Alpha for Z
140 | ``` python
141 | # For example, if you wanna customize alpha value to reduce error-rate of prediction before calculate AGO,
142 | # Directly try to setup the alpha value before start .analyze() and .forecast().
143 | gm11.alpha = 0.8
144 | gm11.add_pattern()
145 | gm11.forecast()
146 | ```
147 |
148 | #### Multi-Processing
149 | 1. Put objects of gm0n, gm1n or gm11 into their own arrays.
150 | 2. Run specific functions are: grey.run.gm0n(array), grey.run.gm1n(array) or grey.run.gm11(array).
151 | 3. Enumerate the arrays, or enumerate .run.gm0n(), .run.gm1n() and .run.gm11() they returned arrays.
152 | ``` python
153 | # multiprocessing examples:
154 | # for GM0N, GM1N
155 | queue = []
156 | queue.append(gm0n.deepcopy())
157 | queue.append(gm0n.deepcopy())
158 | queue.append(gm0n.deepcopy())
159 | queue.append(gm0n.deepcopy())
160 | queue.append(gm0n.deepcopy())
161 | queue.append(gm0n.deepcopy())
162 | queue.append(gm0n.deepcopy())
163 |
164 | grey.run.gm0n(queue)
165 |
166 | for gm in queue:
167 | gm.print_influence_degrees()
168 | ```
169 |
170 | ``` python
171 | # for GM11
172 | gm11_queue = []
173 | gm11_queue.append(gm11.deepcopy())
174 | gm11_queue.append(gm11.deepcopy())
175 | gm11_queue.append(gm11.deepcopy())
176 | gm11_queue.append(gm11.deepcopy())
177 | gm11_queue.append(gm11.deepcopy())
178 | gm11_queue.append(gm11.deepcopy())
179 | gm11_queue.append(gm11.deepcopy())
180 |
181 | grey.run.gm11(gm11_queue)
182 |
183 | for gm in gm11_queue:
184 | gm.print_forecasted_results()
185 | ```
186 |
187 | ## Version
188 |
189 | V1.3.1
190 |
191 | ## LICENSE
192 |
193 | MIT.
194 |
195 | ## Note
196 |
197 | 卷積的部份,是跑 2 層的 GM11:
198 |
1 -> 2 -> 3, 預測 4
199 | 2 -> 3 -> 4, 預測 5
200 | 3 -> 4 -> 5, 預測 6
201 | ... 其餘類推
202 |
203 | 之後會把預測 4,5,6 再丟進去 GM11 跑最終結果。等於是先做一次特徵提取,第 1 層提取每一個區間的預測輸出,再對這預測輸出做平均誤差的修正,而後再丟入第 2 層的 GM11 去做總輸出。
204 |
--------------------------------------------------------------------------------
/example.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | from greytheory import GreyTheory
5 |
6 | grey = GreyTheory()
7 |
8 |
9 | # GM0N
10 | gm0n = grey.gm0n
11 |
12 | gm0n.add_outputs([1., 1., 1., 1., 1., 1.], "x1")
13 | gm0n.add_patterns([.75, 1.22, .2, 1., 1., 1.], "x2")
14 | gm0n.add_patterns([.5, 1., .7, .66, 1., .5], "x3")
15 | gm0n.add_patterns([1., 1.09, .4, .33, .66, .25], "x4")
16 | gm0n.add_patterns([.25, .99, 1., .66, .33, .25], "x5")
17 |
18 | gm0n.analyze()
19 |
20 | # Looks GM0N the results as below:
21 | gm0n.print_analyzed_results()
22 | gm0n.print_influence_degrees()
23 |
24 | # GM1N
25 | gm1n = grey.gm1n
26 |
27 | gm1n.add_outputs([2., 11., 1.5, 2., 2.2, 3.], "x1")
28 | gm1n.add_patterns([3., 13.5, 1., 3., 3., 4.], "x2")
29 | gm1n.add_patterns([2., 11., 3.5, 2., 3., 2.], "x3")
30 | gm1n.add_patterns([4., 12., 2., 1., 2., 1.], "x4")
31 | gm1n.add_patterns([1., 10., 5., 2., 1., 1.], "x5")
32 |
33 | gm1n.analyze()
34 |
35 | # Looks GM1N the results as below:
36 | gm1n.print_analyzed_results()
37 | gm1n.print_influence_degrees()
38 |
39 | # GM11
40 | gm11 = grey.gm11
41 |
42 | # To try customized alpha for IAGO of Z.
43 | gm11.alpha = 0.5
44 | gm11.convolution = True # Convolutional forecasting of GM11.
45 | gm11.stride = 1
46 | gm11.length = 4
47 |
48 | # gm11.add_pattern(533.0, "x1")
49 | # gm11.add_pattern(665.0, "x2")
50 | # gm11.add_pattern(655.0, "x3")
51 | # gm11.add_pattern(740.0, "x4")
52 |
53 | gm11.add_pattern(223.3, "a1")
54 | gm11.add_pattern(227.3, "a2")
55 | gm11.add_pattern(230.5, "a3")
56 | gm11.add_pattern(238.1, "a4")
57 | gm11.add_pattern(242.9, "a5")
58 | gm11.add_pattern(251.1, "a6")
59 |
60 | gm11.forecast()
61 |
62 | # To record last forecasted result.
63 | #last_forecasted_results = gm11.forecasted_outputs
64 |
65 | # To clean all forecasted results.
66 | #gm11.clean_forecasted()
67 |
68 | # In next iteration of forecasting, we wanna continue use last forecasted results to do next forecasting,
69 | # but if we removed gm11.forecasted_outputs list before,
70 | # we can use continue_forecasting() to extend / recall the last for ecasted result come back to be convolutional features.
71 | #gm11.continue_forecasting(last_forecasted_results)
72 |
73 | # Looks GM11 the results for example as below:
74 | gm11.print_forecasted_results()
75 |
76 | """
77 | # multiprocessing examples:
78 | # for GM0N, GM1N
79 | queue = []
80 | queue.append(gm0n.deepcopy())
81 | queue.append(gm0n.deepcopy())
82 | queue.append(gm0n.deepcopy())
83 | queue.append(gm0n.deepcopy())
84 | queue.append(gm0n.deepcopy())
85 | queue.append(gm0n.deepcopy())
86 | queue.append(gm0n.deepcopy())
87 |
88 | grey.run.gm0n(queue)
89 |
90 | for gm in queue:
91 | gm.print_influence_degrees()
92 |
93 | # for GM11
94 | gm11_queue = []
95 | gm11_queue.append(gm11.deepcopy())
96 | gm11_queue.append(gm11.deepcopy())
97 | gm11_queue.append(gm11.deepcopy())
98 | gm11_queue.append(gm11.deepcopy())
99 | gm11_queue.append(gm11.deepcopy())
100 | gm11_queue.append(gm11.deepcopy())
101 | gm11_queue.append(gm11.deepcopy())
102 |
103 | grey.run.gm11(gm11_queue)
104 |
105 | for gm in gm11_queue:
106 | gm.print_forecasted_results()
107 |
108 | """
109 |
--------------------------------------------------------------------------------
/greytheory/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from .packages.models.grey_gm0n import GreyGM0N
3 | from .packages.models.grey_gm1n import GreyGM1N
4 | from .packages.models.grey_gm11 import GreyGM11
5 | from .packages.models.grey_run import GreyRun
6 |
7 | __version__ = "0.1"
8 |
9 | class GreyTheory:
10 | def __init__(self):
11 | self.gm0n = GreyGM0N()
12 | self.gm1n = GreyGM1N()
13 | self.gm11 = GreyGM11()
14 | self.run = GreyRun()
--------------------------------------------------------------------------------
/greytheory/packages/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kalvar/python-GreyTheory/820ee5764dda51a94a335921a125b329a0950b7c/greytheory/packages/__init__.py
--------------------------------------------------------------------------------
/greytheory/packages/libs/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kalvar/python-GreyTheory/820ee5764dda51a94a335921a125b329a0950b7c/greytheory/packages/libs/__init__.py
--------------------------------------------------------------------------------
/greytheory/packages/libs/grey_lib.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | class GreyLib:
4 |
5 | def __init__(self, alpha=0.5):
6 | self.alpha = alpha
7 |
8 | # Generates AGO via patterns.
9 | def ago(self, patterns):
10 | # do ago
11 | ago_boxes = [] #np.array([], dtype=np.float)
12 | z_boxes = []
13 | pattern_index = 0
14 | # x1 which is index 0 the output, x2 ~ xn are the inputs.
15 | for x_patterns in patterns:
16 | x_ago = []
17 | sum = 0.0
18 | z_value = 0.0
19 | x_index = 0
20 | for x_value in x_patterns:
21 | sum += x_value
22 | x_ago.append(sum)
23 | # Only first pattern need to calculate the Z value.
24 | if pattern_index == 0 and x_index > 0:
25 | # Alpha 0.5 that means z is mean value, others alpha number means z is IAGO.
26 | z_value = (self.alpha * sum) + (self.alpha * x_ago[x_index - 1])
27 | z_boxes.append(z_value)
28 | x_index += 1
29 | ago_boxes.append(x_ago)
30 | pattern_index += 1
31 |
32 | return (ago_boxes, z_boxes)
33 |
34 |
--------------------------------------------------------------------------------
/greytheory/packages/libs/grey_math.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | class GreyMath:
4 |
5 | # Least Squares Method (LSM) to solve the equations, solves that simultaneous equations.
6 | def solve_equations(self, equations, equals):
7 | # Formula is ( B^T x B )^-1 x B^T x Yn, to be a square matrix first.
8 | transposed_equations = np.asarray(equations).T.tolist()
9 | # Doing ( B^T x B )
10 | square_matrix = np.dot(transposed_equations, equations)
11 | # Doing (B^T x Yn)
12 | bx_y = np.dot(transposed_equations, equals)
13 | # Solves equations.
14 | return np.linalg.solve(square_matrix, bx_y).tolist()
15 |
--------------------------------------------------------------------------------
/greytheory/packages/models/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Kalvar/python-GreyTheory/820ee5764dda51a94a335921a125b329a0950b7c/greytheory/packages/models/__init__.py
--------------------------------------------------------------------------------
/greytheory/packages/models/grey_class.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | import copy
5 | import numpy as np
6 | from ..libs.grey_lib import GreyLib
7 | from ..libs.grey_math import GreyMath
8 | from .grey_factory import GreyFactory
9 | from .grey_forecast import GreyForecast
10 |
11 | class GreyClass (object):
12 |
13 | _TAG_FORECAST_NEXT_MOMENT = "forecasted_next_moment"
14 | _TAG_FORECAST_HISTORY = "history"
15 |
16 | def __init__(self):
17 | self.tag = self.__class__.__name__
18 | self.patterns = []
19 | self.keys = []
20 | self.analyzed_results = []
21 | self.influence_degrees = []
22 | self.grey_lib = GreyLib()
23 | self.grey_math = GreyMath()
24 |
25 | # Those outputs are the results of all patterns.
26 | def _add_outputs(self, outputs, pattern_key):
27 | self.patterns.insert(0, outputs)
28 | self.keys.append(pattern_key)
29 |
30 | # Those patterns are using in AGO generator.
31 | def _add_patterns(self, patterns, pattern_key):
32 | self.patterns.append(patterns)
33 | self.keys.append(pattern_key)
34 |
35 | def ago(self, patterns):
36 | return self.grey_lib.ago(patterns)
37 |
38 | def remove_all_analysis(self):
39 | # Deeply removing without others copied array.
40 | self.analyzed_results = []
41 | self.influence_degrees = []
42 | self.forecasts = []
43 |
44 | # Removing all reference links with others array.
45 | #del self.analyzed_results
46 | #del self.influence_degrees
47 | #del self.forecasts
48 |
49 | def print_self(self):
50 | print("%r" % self.__class__.__name__)
51 |
52 | def print_analyzed_results(self):
53 | self.print_self()
54 | for factory in self.analyzed_results:
55 | print("Pattern key: %r, grey value: %r, ranking: %r" % (factory.name, factory.equation_value, factory.ranking))
56 |
57 | def print_influence_degrees(self):
58 | self.print_self()
59 | string = " > ".join(self.influence_degrees)
60 | print("The keys of parameters their influence degrees (ordering): %r" % string)
61 |
62 | def print_forecasted_results(self):
63 | self.print_self()
64 | for forecast in self.analyzed_results:
65 | print("K = %r" % forecast.k)
66 | if forecast.tag == self._TAG_FORECAST_HISTORY:
67 | # History.
68 | print("From original value %r to forecasted value is %r" % (forecast.original_value, forecast.forecast_value))
69 | print("The error rate is %r" % forecast.error_rate)
70 | else:
71 | # Next moments.
72 | print("Forcated next moment value is %r" % forecast.forecast_value)
73 |
74 | # Last forecasted moment.
75 | last_moment = self.analyzed_results[-1]
76 | print("The average error rate %r" % last_moment.average_error_rate)
77 |
78 | def deepcopy(self):
79 | return copy.deepcopy(self)
80 |
81 | @property
82 | def alpha(self):
83 | return self.grey_lib.alpha
84 |
85 | @alpha.setter
86 | def alpha(self, value = 0.5):
87 | self.grey_lib.alpha = value
--------------------------------------------------------------------------------
/greytheory/packages/models/grey_factory.py:
--------------------------------------------------------------------------------
1 |
2 | class GreyFactory:
3 |
4 | name = ""
5 | equation_value = ""
6 | ranking = ""
7 |
--------------------------------------------------------------------------------
/greytheory/packages/models/grey_forecast.py:
--------------------------------------------------------------------------------
1 |
2 | class GreyForecast:
3 |
4 | tag = ""
5 | k = 0
6 | original_value = 0.0
7 | forecast_value = 0.0
8 | error_rate = 0.0
9 | average_error_rate = 0.0
10 |
11 |
12 |
--------------------------------------------------------------------------------
/greytheory/packages/models/grey_gm0n.py:
--------------------------------------------------------------------------------
1 | from .grey_class import *
2 |
3 | class GreyGM0N (GreyClass):
4 |
5 | def add_outputs(self, outputs, pattern_key):
6 | self._add_outputs(outputs, pattern_key)
7 |
8 | def add_patterns(self, patterns, pattern_key):
9 | self._add_patterns(patterns, pattern_key)
10 |
11 | def analyze(self):
12 | self.remove_all_analysis()
13 |
14 | ago = self.ago(self.patterns)
15 | ago_boxes = ago[0]
16 | z_boxes = ago[1] # X
17 |
18 | # Fetchs ago matrixes after x2[1] (ago_boxes[1]) then transpose them.
19 | factors = np.asarray(ago_boxes[1:len(ago_boxes)]).T.tolist()
20 | grey_equations = factors[1:len(factors)] # Y
21 |
22 | # all_factors are the equations (x, y, z ...) and z_boxes are the goals of equations.
23 | solved_equations = self.grey_math.solve_equations(grey_equations, z_boxes) # B
24 |
25 | # Desc sorting the abs() equation values
26 | sorts = []
27 | length = len(solved_equations)
28 | for i in range(0, length):
29 | equation_value = abs(solved_equations[i])
30 | factory_info = {}
31 | equation_name = self.keys[i+1] # The keys of patterns are start in index 1, the index 0 is key of output-goal.
32 | grey_factory = GreyFactory()
33 | grey_factory.name = equation_name
34 | grey_factory.equation_value = equation_value
35 | sorts.append(grey_factory)
36 |
37 | # DESC
38 | # key=lambda d: d["equation_value"]
39 | self.analyzed_results = sorted(sorts, key=lambda factory: factory.equation_value, reverse=True)
40 | # Ranking all grey factories and setup their influence degrees step by step.
41 | ranking = 0
42 | for grey_factory in self.analyzed_results:
43 | ranking += 1
44 | grey_factory.ranking = ranking
45 | self.influence_degrees.append(grey_factory.name)
46 | #print "gm0n %r" % grey_factory.name
47 |
48 |
49 |
--------------------------------------------------------------------------------
/greytheory/packages/models/grey_gm11.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # -*- coding: utf-8 -*-
3 |
4 | from .grey_class import *
5 | import math
6 |
7 | class GreyGM11 (GreyClass):
8 |
9 | def __init__(self):
10 | super(GreyGM11, self).__init__() # Calling super object __init__
11 | self.forecasted_outputs = []
12 | self.stride = 1
13 | self.length = 4
14 | self.period = 1 # Default is 1, the parameter means how many next moments need to forcast continually.
15 | self.convolution = False
16 |
17 | def add_pattern(self, pattern, pattern_key):
18 | self._add_patterns(pattern, pattern_key)
19 |
20 | def __forecast_value(self, x1, a_value, b_value, k):
21 | return (1 - math.exp(a_value)) * (x1 - (b_value / a_value)) * math.exp(-a_value * k)
22 |
23 | def __forecast(self, patterns, period=1):
24 | self.remove_all_analysis()
25 | ago = self.ago([patterns])
26 | z_boxes = ago[1]
27 | # Building B matrix, manual transpose z_boxes and add 1.0 to every sub-object.
28 | factors = []
29 | for z in z_boxes:
30 | x_t = []
31 | # Add negative z
32 | x_t.append(-z)
33 | x_t.append(1.0)
34 | factors.append(x_t)
35 |
36 | # Building Y matrix to be output-goals of equations.
37 | y_vectors = []
38 | for passed_number in patterns[1::]:
39 | y_vectors.append(passed_number)
40 |
41 | solved_equations = self.grey_math.solve_equations(factors, y_vectors)
42 | # Then, forecasting them at all include next moment value.
43 | analyzed_results = []
44 | sum_error = 0.0
45 | x1 = patterns[0]
46 | a_value = solved_equations[0]
47 | b_value = solved_equations[1]
48 | k = 1
49 | length = len(patterns)
50 | for passed_number in patterns[1::]:
51 | grey_forecast = GreyForecast()
52 | forecast_value = self.__forecast_value(x1, a_value, b_value, k)
53 |
54 | original_value = patterns[k]
55 | error_rate = abs((original_value - forecast_value) / original_value)
56 | sum_error += error_rate
57 | grey_forecast.tag = self._TAG_FORECAST_HISTORY
58 | grey_forecast.k = k
59 | grey_forecast.original_value = original_value
60 | grey_forecast.forecast_value = forecast_value
61 | grey_forecast.error_rate = error_rate
62 |
63 | analyzed_results.append(grey_forecast)
64 | k += 1
65 |
66 | # Continuous forecasting next moments.
67 | if period > 0:
68 | for go_head in range(0, period):
69 | forecast_value = self.__forecast_value(x1, a_value, b_value, k)
70 |
71 | grey_forecast = GreyForecast()
72 | grey_forecast.tag = self._TAG_FORECAST_NEXT_MOMENT
73 | grey_forecast.k = k # This k means the next moment of forecasted.
74 | grey_forecast.average_error_rate = sum_error / (length - 1)
75 | grey_forecast.forecast_value = forecast_value
76 | analyzed_results.append(grey_forecast)
77 | k += 1
78 |
79 | self.analyzed_results = analyzed_results
80 | return analyzed_results
81 |
82 | # stride: the N-gram, shift step-size for each forecasting.
83 | # length: the Filter kernel, shift length of distance for each forecasting.
84 | def __forecast_convolution(self, patterns=[], stride=1, length=4):
85 | pattern_count = len(patterns)
86 | # Convolution formula: (pattern_count - length) / stride + 1,
87 | # e.g. (7 - 3) / 1 + 1 = 5 (Needs to shift 5 times.)
88 | # e.g. (7 - 3) / 3 + 1 = 2.33, to get floor() or ceil()
89 | # total_times at least for once.
90 | total_times = int(math.floor(float(pattern_count - length) / stride + 1))
91 | convolutions = []
92 | stride_index = 0
93 | for i in range(0, total_times):
94 | # If it is last convolution, we directly pick it all.
95 | stride_length = stride_index+length
96 | if i == total_times - 1:
97 | stride_length = len(patterns)
98 |
99 | convolution_patterns = patterns[stride_index:stride_length]
100 | period_forecasts = self.__forecast(convolution_patterns)
101 | convolutions.append(period_forecasts)
102 |
103 | # Fetchs forecasted moment and revises it to be fix with average error rate.
104 | forecasted_moment = period_forecasts[-1]
105 | forecasted_value = forecasted_moment.forecast_value
106 | revised_value = forecasted_value + (forecasted_value * forecasted_moment.average_error_rate)
107 | self.forecasted_outputs.append(revised_value)
108 |
109 | # Next stride start index.
110 | stride_index += stride
111 |
112 | #print "forecasted_outputs % r" % self.forecasted_outputs
113 |
114 | # Using extracted convolution that forecasted values to do final forecasting.
115 | if total_times > 1:
116 | self.__forecast(self.forecasted_outputs)
117 | self.forecasted_outputs.append(self.last_moment)
118 |
119 | return convolutions
120 |
121 | # period: 連續預測多長的時間區間, default: 只預測下一刻
122 | def forecast(self):
123 | if self.convolution == True:
124 | return self.__forecast_convolution(self.patterns, self.stride, self.length)
125 | else:
126 | return self.__forecast(self.patterns, self.period)
127 |
128 | # In next iteration of forecasting, we wanna continue use last forecasted results to do next forecasting,
129 | # but if we removed gm11.forecasted_outputs list before,
130 | # we can use continue_forecasting() to extend / recall the last forecasted result come back to be convolutional features.
131 | def continue_forecasting(self, last_forecasted_outputs = []):
132 | self.forecasted_outputs.extend(last_forecasted_outputs)
133 |
134 | # Clean forecasted outputs.
135 | def clean_forecasted(self):
136 | self.forecasted_outputs = []
137 |
138 | @property
139 | def last_moment(self):
140 | # Last GreyForecast() object is the next moment forecasted.
141 | return self.analyzed_results[-1].forecast_value
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/greytheory/packages/models/grey_gm1n.py:
--------------------------------------------------------------------------------
1 | from .grey_class import *
2 |
3 | class GreyGM1N (GreyClass):
4 |
5 | def add_outputs(self, outputs, pattern_key):
6 | self._add_outputs(outputs, pattern_key)
7 |
8 | def add_patterns(self, patterns, pattern_key):
9 | self._add_patterns(patterns, pattern_key)
10 |
11 | def analyze(self):
12 | self.remove_all_analysis()
13 |
14 | ago = self.ago(self.patterns)
15 | ago_boxes = ago[0]
16 | z_boxes = ago[1]
17 |
18 | # Fetchs from ago_boxes[1] to [last] then transpose it.
19 | factors = np.asarray(ago_boxes[1:len(ago_boxes)]).T.tolist()
20 | grey_equations = factors[1:len(factors)]
21 | # Then, to add -Z value from z_boxes into every sub-factors.
22 | index = -1
23 | for z_value in z_boxes:
24 | index += 1
25 | grey_equations[index].insert(0, -z_value)
26 | # Refactoring that x1 (the outputs) to be an output vector by following the Grey Theory GM(1, N) formula
27 | outputs = self.patterns[0][1::]
28 | solved_equations = self.grey_math.solve_equations(grey_equations, outputs)
29 |
30 | # Desc sorting the abs() equation values first, they named b(2) to b(n), but ignore the result (a) the output-goal factory in this loop
31 | sorts = []
32 | goal_factory = GreyFactory()
33 | length = len(solved_equations)
34 | for i in range(0, length):
35 | equation_value = abs(solved_equations[i])
36 | factory_info = {}
37 | equation_name = self.keys[i]
38 | grey_factory = GreyFactory()
39 | grey_factory.name = equation_name
40 | grey_factory.equation_value = equation_value
41 | if i > 0:
42 | sorts.append(grey_factory)
43 | else:
44 | goal_factory = grey_factory
45 |
46 | self.analyzed_results = sorted(sorts, key=lambda factory: factory.equation_value, reverse=True)
47 | self.analyzed_results.insert(0, goal_factory) # The output-goal always is first object in solved_equations array.
48 | ranking = -1
49 | for grey_factory in self.analyzed_results:
50 | ranking += 1
51 | grey_factory.ranking = ranking
52 | # Ranking 0 is the output-goal (a), the output-goal is not the influence degree,
53 | # Other paramenters are the real influence degrees of GM1N.
54 | if ranking > 0:
55 | self.influence_degrees.append(grey_factory.name)
56 | #print "gm1n %r" % grey_factory.name
57 |
58 |
59 |
--------------------------------------------------------------------------------
/greytheory/packages/models/grey_run.py:
--------------------------------------------------------------------------------
1 | import multiprocessing as mp
2 | import math
3 |
4 | class GreyRun:
5 |
6 | def __init__(self):
7 | mp.freeze_support() # for windows
8 | self.cpu_count = mp.cpu_count()
9 |
10 | def _is_empty(self, array = []):
11 | return not bool(array)
12 |
13 | def _close_pool(self, pool):
14 | pool.close()
15 | pool.join()
16 |
17 | # multiprocessing
18 | def _execute_models(self, gmnn_queue=[], is_gm11=False):
19 | if self._is_empty(gmnn_queue):
20 | return []
21 | pool = mp.Pool()
22 | cpu_count = self.cpu_count
23 | length = len(gmnn_queue)
24 | block_count = int(math.ceil(length / float(cpu_count)))
25 | start_index = 0
26 | end_length = cpu_count
27 | for block in xrange(0, block_count):
28 | for gm_model in gmnn_queue[start_index:end_length]:
29 | if is_gm11 == False:
30 | pool.apply_async(gm_model.analyze())
31 | else:
32 | pool.apply_async(gm_model.forecast())
33 |
34 | start_index += cpu_count
35 | end_length += cpu_count
36 | if end_length > length:
37 | end_length = length
38 |
39 | self._close_pool(pool)
40 | return gmnn_queue
41 |
42 | def gm0n(self, queue):
43 | return self._execute_models(queue)
44 |
45 | def gm1n(self, queue):
46 | return self._execute_models(queue)
47 |
48 | def gm11(self, queue):
49 | return self._execute_models(queue, True)
50 |
51 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 | with open("README.md", "r") as fh:
4 | long_description = fh.read()
5 |
6 | setuptools.setup(
7 | name="greytheory",
8 | version="0.1",
9 | author="Kalvar",
10 | author_email="ilovekalvar@gmail.com",
11 | description="Grey theory, implemented by python.",
12 | long_description=long_description,
13 | long_description_content_type="text/markdown",
14 | url="https://github.com/Kalvar/python-GreyTheory.git",
15 | packages=setuptools.find_packages(),
16 | classifiers=[
17 | "Development Status :: 5 - Production/Stable",
18 | "Programming Language :: Python :: 3",
19 | "License :: OSI Approved :: MIT License",
20 | "Operating System :: OS Independent",
21 | ],
22 | python_requires='>=3.6',
23 | )
--------------------------------------------------------------------------------