pyANOVAapprox 0.2.1__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/PKG-INFO +1 -1
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/pyproject.toml +1 -1
- pyanovaapprox-0.2.3/simpleTest/exampleCheb.py +202 -0
- pyanovaapprox-0.2.3/simpleTest/exampleClassification.py +190 -0
- pyanovaapprox-0.2.3/simpleTest/exampleNonPeriodic.py +200 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/simpleTest/examplePeriodic.py +3 -2
- pyanovaapprox-0.2.3/simpleTest/exampleWavelet.py +134 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/__init__.py +0 -21
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/analysis.py +2 -2
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/approx.py +3 -2
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/fista.py +0 -2
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/run_tests.py +1 -1
- pyanovaapprox-0.2.3/tests/wav_lsqr.py +50 -0
- pyanovaapprox-0.2.1/tests/wav_lsqr.py +0 -1
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.github/workflows/ci.yml +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.github/workflows/documentation.yml +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.github/workflows/format.yml +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.github/workflows/release.yml +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/.gitignore +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/LICENSE +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/README.md +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/Makefile +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/Analysis.rst +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/Approximation.rst +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/Errors.rst +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/conf.py +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/docs/source/index.rst +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/errors.py +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/src/pyANOVAapprox/trafos.py +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/TestFunctionCheb.py +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/TestFunctionPeriodic.py +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/cheb_fista.py +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/cheb_lsqr.py +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/per_fista.py +0 -0
- {pyanovaapprox-0.2.1 → pyanovaapprox-0.2.3}/tests/per_lsqr.py +0 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# pip install pyANOVAapprox
|
|
2
|
+
|
|
3
|
+
# Example for approximating an non periodic function
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
import pyANOVAapprox as ANOVAapprox
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def TestFunction(x):
|
|
14
|
+
return x[0] * x[4] + 2 - np.exp(x[3]) + np.sqrt(x[5] + 3 + x[1])
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
rng = np.random.default_rng(1234)
|
|
18
|
+
|
|
19
|
+
##################################
|
|
20
|
+
## Definition of the parameters ##
|
|
21
|
+
##################################
|
|
22
|
+
|
|
23
|
+
d = 6 # dimension
|
|
24
|
+
|
|
25
|
+
M = 10000 # number of used evaluation points to train the model
|
|
26
|
+
M_test = 100000 # number of used evaluation points to test the accuracity the model
|
|
27
|
+
|
|
28
|
+
max_iter = 50 # maximum number of iterations
|
|
29
|
+
|
|
30
|
+
# there are 3 possibilities with varying degree of freedom to define the number of used frequencies
|
|
31
|
+
########### Variant 1:
|
|
32
|
+
ds = 2 # superposition dimension
|
|
33
|
+
num = np.sum([math.comb(6, k) for k in np.arange(1, 2 + 1)]) # number of used subsets
|
|
34
|
+
b = M / (
|
|
35
|
+
math.log10(M) * num
|
|
36
|
+
) # number for the number of frequencies if we use logarithmic oversampling and distribute it evenly to all subsets
|
|
37
|
+
bw = [
|
|
38
|
+
math.floor(b / 2) * 2,
|
|
39
|
+
math.floor(math.sqrt(b) / 2) * 2,
|
|
40
|
+
] # bandwidths (use even numbers)
|
|
41
|
+
# Use all subsets up to ds and use bw[1] many frequences in the the subsets with one element, b[2]^2 many for subsets with two elements and so on
|
|
42
|
+
#
|
|
43
|
+
########### Variant 2:
|
|
44
|
+
# used subsets:
|
|
45
|
+
# U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
|
|
46
|
+
# (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
|
|
47
|
+
# Bandwidths for these subsets:
|
|
48
|
+
# N = [0 , 100, 100, 100, 100, 100, 100,
|
|
49
|
+
# 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
|
|
50
|
+
# Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. For subsets with more then one direction is the same bandwidth in all directions used
|
|
51
|
+
#
|
|
52
|
+
########### Variant 3:
|
|
53
|
+
# used subsets:
|
|
54
|
+
# U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
|
|
55
|
+
# (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
|
|
56
|
+
# Bandwidths for these subsets:
|
|
57
|
+
# N = [(), (100,), (100,), (100,), (100,), (100,), (100,),
|
|
58
|
+
# (10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,)]
|
|
59
|
+
# Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. The bandwidth N[i][j] corresponds to the direction U[i][j]
|
|
60
|
+
|
|
61
|
+
lambdas = np.array([0.0, 1.0]) # used regularisation parameters λ
|
|
62
|
+
|
|
63
|
+
############################
|
|
64
|
+
## Generation of the data ##
|
|
65
|
+
############################
|
|
66
|
+
|
|
67
|
+
X = 2 * rng.random((M, d)) - 1 # construct the evaluation points for training
|
|
68
|
+
X = np.sin(np.pi * (X - 0.5))
|
|
69
|
+
y = np.array(
|
|
70
|
+
[TestFunction(X[i, :].T) for i in range(M)]
|
|
71
|
+
) # evaluate the function at these points
|
|
72
|
+
X_test = 2 * rng.random((M_test, d)) - 1 #
|
|
73
|
+
X_test = np.sin(np.pi * (X_test - 0.5))
|
|
74
|
+
y_test = np.array(
|
|
75
|
+
[TestFunction(X_test[i, :].T) for i in range(M_test)]
|
|
76
|
+
) # the same for the test points
|
|
77
|
+
|
|
78
|
+
##########################
|
|
79
|
+
## Do the approximation ##
|
|
80
|
+
##########################
|
|
81
|
+
|
|
82
|
+
ads = ANOVAapprox.approx(X, y, ds=ds, basis="cheb", N=bw)
|
|
83
|
+
ads.approximate(lam=lambdas, max_iter=max_iter, solver="lsqr")
|
|
84
|
+
|
|
85
|
+
################################
|
|
86
|
+
## get approximation accuracy ##
|
|
87
|
+
################################
|
|
88
|
+
|
|
89
|
+
# mse = ANOVAapprox.get_mse(ads) # get mse error at the given training points
|
|
90
|
+
mse = ANOVAapprox.get_mse(ads, X_test, y_test) # get mse error at the test points
|
|
91
|
+
λ_min = min(
|
|
92
|
+
mse, key=mse.get
|
|
93
|
+
) # get the regularisation parameter which leads to the minimal error
|
|
94
|
+
mse_min = mse[λ_min]
|
|
95
|
+
|
|
96
|
+
print("mse = " + str(mse_min))
|
|
97
|
+
|
|
98
|
+
###############################################
|
|
99
|
+
## Analyze the model to improve the accuracy ##
|
|
100
|
+
###############################################
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
ar = ANOVAapprox.get_AttributeRanking(ads, λ_min) # get the attrbute ranking
|
|
104
|
+
|
|
105
|
+
plt.figure()
|
|
106
|
+
(markers, stemlines, baseline) = plt.stem(
|
|
107
|
+
np.arange(1, d + 1), # x-Werte (1:d)
|
|
108
|
+
ar, # y-Werte (ar)
|
|
109
|
+
linefmt="C0-", # Stil der Stiele
|
|
110
|
+
markerfmt="C0^", # Stil der Markierung (C0 = erste Farbe, ^ = up-triangle)
|
|
111
|
+
basefmt="k:", # Stil der Basislinie (optional)
|
|
112
|
+
)
|
|
113
|
+
plt.setp(markers, markersize=8)
|
|
114
|
+
plt.yscale("log")
|
|
115
|
+
y_min_calc = 10 ** (np.min(np.log10(ar)) - 0.5)
|
|
116
|
+
plt.ylim(y_min_calc, 1)
|
|
117
|
+
plt.title("Attribute Ranking")
|
|
118
|
+
plt.xlabel("Attribut-Index")
|
|
119
|
+
plt.xlim(0.5, d + 0.5)
|
|
120
|
+
plt.grid(True, which="both", ls="--", linewidth=0.5)
|
|
121
|
+
plt.show() # plot the arrtibute ranking in an logplot
|
|
122
|
+
print("active dimensions: " + str(ar[ar > 1e-2]))
|
|
123
|
+
|
|
124
|
+
gsis = ANOVAapprox.get_GSI(ads, λ_min)
|
|
125
|
+
label = list(ads.U[1:])
|
|
126
|
+
l = len(label)
|
|
127
|
+
plt.figure()
|
|
128
|
+
x_values = np.arange(1, l + 1)
|
|
129
|
+
(markers, stemlines, baseline) = plt.stem(
|
|
130
|
+
x_values, # X-Werte: 1 bis l
|
|
131
|
+
gsis, # Y-Werte: gsis
|
|
132
|
+
linefmt="C0-", # Stil der Stiele
|
|
133
|
+
markerfmt="C0^", # Stil der Markierung (^ = up-triangle)
|
|
134
|
+
basefmt="k:", # Stil der Basislinie
|
|
135
|
+
)
|
|
136
|
+
plt.setp(markers, markersize=8)
|
|
137
|
+
plt.xticks(x_values, label, rotation=45, ha="right")
|
|
138
|
+
plt.xlabel("Input Dimension")
|
|
139
|
+
plt.yscale("log")
|
|
140
|
+
plt.ylim(y_min_calc, 1)
|
|
141
|
+
plt.title("Global sensitivity indices")
|
|
142
|
+
plt.grid(True, which="both", ls="--", linewidth=0.5)
|
|
143
|
+
plt.tight_layout() # Stellt sicher, dass die Labels sichtbar sind
|
|
144
|
+
plt.show()
|
|
145
|
+
print(
|
|
146
|
+
"important dimensional interactions: : "
|
|
147
|
+
+ str([label[i] for i in np.arange(0, l)[gsis > 1e-2]])
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
################################################
|
|
151
|
+
## Approximation with better suited index set ##
|
|
152
|
+
################################################
|
|
153
|
+
|
|
154
|
+
Umask = np.append(np.array([True]), gsis > 1e-2)
|
|
155
|
+
U = [ads.U[i] for i in np.arange(0, len(Umask))[Umask]] # get important subsets
|
|
156
|
+
bws = M / (math.log10(M) * (len(U) - 1)) # calculate frequencies per subset
|
|
157
|
+
N = [
|
|
158
|
+
math.floor(bws ** (1 / max(1, len(u))) / 2) * 2 for u in U
|
|
159
|
+
] # distribute the frequencies evenly and make them even
|
|
160
|
+
N[0] = 0
|
|
161
|
+
|
|
162
|
+
a = ANOVAapprox.approx(
|
|
163
|
+
X, y, U, N, "cheb"
|
|
164
|
+
) # generate the data structure for the approximation
|
|
165
|
+
a.approximate(
|
|
166
|
+
lam=lambdas, max_iter=max_iter, solver="lsqr"
|
|
167
|
+
) # do the approximation for all specified regularisation parameters
|
|
168
|
+
|
|
169
|
+
mse = ANOVAapprox.get_mse(a, X_test, y_test) # get mse error at the test points
|
|
170
|
+
λ_min = min(
|
|
171
|
+
mse, key=mse.get
|
|
172
|
+
) # get the regularisation parameter which leads to the minimal error
|
|
173
|
+
mse_min = mse[λ_min]
|
|
174
|
+
print("mse = " + str(mse_min))
|
|
175
|
+
|
|
176
|
+
########################
|
|
177
|
+
## Evaluate the model ##
|
|
178
|
+
########################
|
|
179
|
+
|
|
180
|
+
# y_approx = a.evaluate(lam=λ_min) # evaluate the approximation at the training points for the regularisation λ_min
|
|
181
|
+
# y_approx = a.evaluate(X=X_test, lam=λ_min) # evaluate the approximation at the points X_test for the regularisation λ_min
|
|
182
|
+
|
|
183
|
+
# In the following we plot the real and the approximated anova term for the subset u=[3]
|
|
184
|
+
|
|
185
|
+
y_eval_anova = a.evaluateANOVAterms(
|
|
186
|
+
X=X_test, lam=λ_min
|
|
187
|
+
) # evaluate all of the ANOVA terms
|
|
188
|
+
pos = a.U.index((3,)) # find the index for the subset u=[3]
|
|
189
|
+
y_eval_anova_3 = y_eval_anova.T[pos]
|
|
190
|
+
|
|
191
|
+
perm = np.argsort(X_test.T[3])
|
|
192
|
+
X_plot = X_test.T[3][perm]
|
|
193
|
+
y_eval_anova_3_plot = np.real(y_eval_anova_3[perm])
|
|
194
|
+
y_anova_3_plot = -np.exp(X_plot) + 1.2660446775548282
|
|
195
|
+
|
|
196
|
+
plt.figure()
|
|
197
|
+
plt.plot(X_plot, y_eval_anova_3_plot, label="approximation")
|
|
198
|
+
plt.plot(X_plot, y_anova_3_plot, label="ANOVA term") # ... "ANOVA term"]
|
|
199
|
+
plt.title("Approximation of the ANOVA term 4") # title = "..."
|
|
200
|
+
plt.legend() # Zeigt die Labels/Legende an
|
|
201
|
+
plt.grid(True, linestyle="--", alpha=0.7)
|
|
202
|
+
plt.show()
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# pip install pyANOVAapprox
|
|
2
|
+
|
|
3
|
+
# Example for classification into two sets
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
import pyANOVAapprox as ANOVAapprox
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def TestFunction(x):
|
|
14
|
+
e = (
|
|
15
|
+
abs(x[1] + 1.0j * x[2]) + (np.angle(x[1] + 1.0j * x[2]) / (math.pi * 8))
|
|
16
|
+
) % 0.25 > 0.125
|
|
17
|
+
return e * 2 - 1
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
rng = np.random.default_rng(1234)
|
|
21
|
+
|
|
22
|
+
##################################
|
|
23
|
+
## Definition of the parameters ##
|
|
24
|
+
##################################
|
|
25
|
+
|
|
26
|
+
d = 3 # dimension
|
|
27
|
+
|
|
28
|
+
M = 10000 # number of used evaluation points to train the model
|
|
29
|
+
M_test = 10000 # number of used evaluation points to test the accuracity the model
|
|
30
|
+
|
|
31
|
+
max_iter = 50 # maximum number of iterations
|
|
32
|
+
|
|
33
|
+
# there are 3 possibilities with varying degree of freedom to define the number of used frequencies
|
|
34
|
+
########### Variant 1:
|
|
35
|
+
ds = 2 # superposition dimension
|
|
36
|
+
num = np.sum([math.comb(6, k) for k in np.arange(1, 2 + 1)]) # number of used subsets
|
|
37
|
+
b = M / (
|
|
38
|
+
math.log10(M) * num
|
|
39
|
+
) # number for the number of frequencies if we use logarithmic oversampling and distribute it evenly to all subsets
|
|
40
|
+
bw = [
|
|
41
|
+
math.floor(b / 2) * 2,
|
|
42
|
+
math.floor(math.sqrt(b) / 2) * 2,
|
|
43
|
+
] # bandwidths (use even numbers)
|
|
44
|
+
# Use all subsets up to ds and use bw[1] many frequences in the the subsets with one element, b[2]^2 many for subsets with two elements and so on
|
|
45
|
+
#
|
|
46
|
+
########### Variant 2:
|
|
47
|
+
# used subsets:
|
|
48
|
+
# U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
|
|
49
|
+
# (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
|
|
50
|
+
# Bandwidths for these subsets:
|
|
51
|
+
# N = [0 , 100, 100, 100, 100, 100, 100,
|
|
52
|
+
# 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
|
|
53
|
+
# Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. For subsets with more then one direction is the same bandwidth in all directions used
|
|
54
|
+
#
|
|
55
|
+
########### Variant 3:
|
|
56
|
+
# used subsets:
|
|
57
|
+
# U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
|
|
58
|
+
# (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
|
|
59
|
+
# Bandwidths for these subsets:
|
|
60
|
+
# N = [(), (100,), (100,), (100,), (100,), (100,), (100,),
|
|
61
|
+
# (10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,)]
|
|
62
|
+
# Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. The bandwidth N[i][j] corresponds to the direction U[i][j]
|
|
63
|
+
|
|
64
|
+
lambdas = np.array([0.0]) # used regularisation parameters λ
|
|
65
|
+
|
|
66
|
+
############################
|
|
67
|
+
## Generation of the data ##
|
|
68
|
+
############################
|
|
69
|
+
|
|
70
|
+
X = rng.random((M, d)) - 0.5 # construct the evaluation points for training
|
|
71
|
+
y = np.array(
|
|
72
|
+
[TestFunction(X[i, :].T) for i in range(M)], dtype=float
|
|
73
|
+
) # evaluate the function at these points
|
|
74
|
+
X = X + 0.5
|
|
75
|
+
X_test = rng.random((M_test, d)) - 0.5 #
|
|
76
|
+
y_test = np.array(
|
|
77
|
+
[TestFunction(X_test[i, :].T) for i in range(M_test)], dtype=float
|
|
78
|
+
) # the same for the test points
|
|
79
|
+
X_test = X_test + 0.5
|
|
80
|
+
|
|
81
|
+
###########################
|
|
82
|
+
## Do the classification ##
|
|
83
|
+
###########################
|
|
84
|
+
|
|
85
|
+
ads = ANOVAapprox.approx(X, y, ds=ds, basis="cos", N=bw, classification=True)
|
|
86
|
+
ads.approximate(max_iter=max_iter, lam=lambdas)
|
|
87
|
+
|
|
88
|
+
#################################
|
|
89
|
+
## get classification accuracy ##
|
|
90
|
+
#################################
|
|
91
|
+
|
|
92
|
+
y_approx = ads.evaluate(X=X_test, lam=0.0) # evaluate the classification
|
|
93
|
+
acc = sum(np.sign(y_approx) == y_test) / M_test # calculate the accuracity
|
|
94
|
+
print("accuracity = " + str(acc))
|
|
95
|
+
|
|
96
|
+
###############################################
|
|
97
|
+
## Analyze the model to improve the accuracy ##
|
|
98
|
+
###############################################
|
|
99
|
+
|
|
100
|
+
ar = ANOVAapprox.get_AttributeRanking(ads, 0.0) # get the attrbute ranking
|
|
101
|
+
|
|
102
|
+
plt.figure()
|
|
103
|
+
(markers, stemlines, baseline) = plt.stem(
|
|
104
|
+
np.arange(1, d + 1), # x-Werte (1:d)
|
|
105
|
+
ar, # y-Werte (ar)
|
|
106
|
+
linefmt="C0-", # Stil der Stiele
|
|
107
|
+
markerfmt="C0^", # Stil der Markierung (C0 = erste Farbe, ^ = up-triangle)
|
|
108
|
+
basefmt="k:", # Stil der Basislinie (optional)
|
|
109
|
+
)
|
|
110
|
+
plt.setp(markers, markersize=8)
|
|
111
|
+
plt.yscale("log")
|
|
112
|
+
y_min_calc = 10 ** (np.min(np.log10(ar)) - 0.5)
|
|
113
|
+
plt.ylim(y_min_calc, 1)
|
|
114
|
+
plt.title("Attribute Ranking")
|
|
115
|
+
plt.xlabel("Attribut-Index")
|
|
116
|
+
plt.xlim(0.5, d + 0.5)
|
|
117
|
+
plt.grid(True, which="both", ls="--", linewidth=0.5)
|
|
118
|
+
plt.show() # plot the arrtibute ranking in an logplot
|
|
119
|
+
print("active dimensions: " + str(ar[ar > 1e-2]))
|
|
120
|
+
|
|
121
|
+
gsis = ANOVAapprox.get_GSI(ads, 0.0)
|
|
122
|
+
label = list(ads.U[1:])
|
|
123
|
+
l = len(label)
|
|
124
|
+
plt.figure()
|
|
125
|
+
x_values = np.arange(1, l + 1)
|
|
126
|
+
(markers, stemlines, baseline) = plt.stem(
|
|
127
|
+
x_values, # X-Werte: 1 bis l
|
|
128
|
+
gsis, # Y-Werte: gsis
|
|
129
|
+
linefmt="C0-", # Stil der Stiele
|
|
130
|
+
markerfmt="C0^", # Stil der Markierung (^ = up-triangle)
|
|
131
|
+
basefmt="k:", # Stil der Basislinie
|
|
132
|
+
)
|
|
133
|
+
plt.setp(markers, markersize=8)
|
|
134
|
+
plt.xticks(x_values, label, rotation=45, ha="right")
|
|
135
|
+
plt.xlabel("Input Dimension")
|
|
136
|
+
plt.yscale("log")
|
|
137
|
+
plt.ylim(y_min_calc, 1)
|
|
138
|
+
plt.title("Global sensitivity indices")
|
|
139
|
+
plt.grid(True, which="both", ls="--", linewidth=0.5)
|
|
140
|
+
plt.tight_layout() # Stellt sicher, dass die Labels sichtbar sind
|
|
141
|
+
plt.show()
|
|
142
|
+
print(
|
|
143
|
+
"important dimensional interactions: : "
|
|
144
|
+
+ str([label[i] for i in np.arange(0, l)[gsis > 1e-2]])
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
#################################################
|
|
148
|
+
## Classification with better suited index set ##
|
|
149
|
+
#################################################
|
|
150
|
+
|
|
151
|
+
Umask = np.append(np.array([True]), gsis > 1e-2)
|
|
152
|
+
U = [ads.U[i] for i in np.arange(0, len(Umask))[Umask]] # get important subsets
|
|
153
|
+
bws = M / (math.log10(M) * (len(U) - 1)) # calculate frequencies per subset
|
|
154
|
+
N = [
|
|
155
|
+
math.floor(bws ** (1 / max(1, len(u))) / 2) * 2 for u in U
|
|
156
|
+
] # distribute the frequencies evenly and make them even
|
|
157
|
+
N[0] = 0
|
|
158
|
+
|
|
159
|
+
a = ANOVAapprox.approx(
|
|
160
|
+
X, y, U, N, "cos", classification=True
|
|
161
|
+
) # generate the data structure for the classification
|
|
162
|
+
a.approximate(
|
|
163
|
+
lam=lambdas, max_iter=max_iter
|
|
164
|
+
) # do the approximation for all specified regularisation parameters
|
|
165
|
+
|
|
166
|
+
y_approx = a.evaluate(X=X_test, lam=0.0) # evaluate the classification
|
|
167
|
+
acc = sum(np.sign(y_approx) == y_test) / M_test # calculate the accuracity
|
|
168
|
+
print("accuracity = " + str(acc))
|
|
169
|
+
|
|
170
|
+
########################
|
|
171
|
+
## Evaluate the model ##
|
|
172
|
+
########################
|
|
173
|
+
|
|
174
|
+
# y_approx = a.evaluate(X=X_test) # evaluate the classification at the training points for the regularisation λ_min
|
|
175
|
+
y_approx = a.evaluate(
|
|
176
|
+
X=X_test, lam=0.0
|
|
177
|
+
) # evaluate the classification at the points X_test for the regularisation λ_min
|
|
178
|
+
|
|
179
|
+
plt.figure()
|
|
180
|
+
scatter = plt.scatter(
|
|
181
|
+
X_test[:, 1],
|
|
182
|
+
X_test[:, 2],
|
|
183
|
+
c=np.sign(y_approx),
|
|
184
|
+
cmap="winter",
|
|
185
|
+
s=100,
|
|
186
|
+
alpha=0.8,
|
|
187
|
+
edgecolors="black",
|
|
188
|
+
linewidths=0.5,
|
|
189
|
+
)
|
|
190
|
+
plt.show()
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# pip install pyANOVAapprox
|
|
2
|
+
|
|
3
|
+
# Example for approximating an non periodic function
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
import pyANOVAapprox as ANOVAapprox
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def TestFunction(x):
|
|
14
|
+
return x[0] * x[4] + 2 - np.exp(x[3]) + np.sqrt(x[5] + 3 + x[1])
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
rng = np.random.default_rng(1234)
|
|
18
|
+
|
|
19
|
+
##################################
|
|
20
|
+
## Definition of the parameters ##
|
|
21
|
+
##################################
|
|
22
|
+
|
|
23
|
+
d = 6 # dimension
|
|
24
|
+
|
|
25
|
+
M = 10000 # number of used evaluation points to train the model
|
|
26
|
+
M_test = 100000 # number of used evaluation points to test the accuracity the model
|
|
27
|
+
|
|
28
|
+
max_iter = 50 # maximum number of iterations
|
|
29
|
+
|
|
30
|
+
# there are 3 possibilities with varying degree of freedom to define the number of used frequencies
|
|
31
|
+
########### Variant 1:
|
|
32
|
+
ds = 2 # superposition dimension
|
|
33
|
+
num = np.sum([math.comb(6, k) for k in np.arange(1, 2 + 1)]) # number of used subsets
|
|
34
|
+
b = M / (
|
|
35
|
+
math.log10(M) * num
|
|
36
|
+
) # number for the number of frequencies if we use logarithmic oversampling and distribute it evenly to all subsets
|
|
37
|
+
bw = [
|
|
38
|
+
math.floor(b / 2) * 2,
|
|
39
|
+
math.floor(math.sqrt(b) / 2) * 2,
|
|
40
|
+
] # bandwidths (use even numbers)
|
|
41
|
+
# Use all subsets up to ds and use bw[1] many frequences in the the subsets with one element, b[2]^2 many for subsets with two elements and so on
|
|
42
|
+
#
|
|
43
|
+
########### Variant 2:
|
|
44
|
+
# used subsets:
|
|
45
|
+
# U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
|
|
46
|
+
# (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
|
|
47
|
+
# Bandwidths for these subsets:
|
|
48
|
+
# N = [0 , 100, 100, 100, 100, 100, 100,
|
|
49
|
+
# 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
|
|
50
|
+
# Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. For subsets with more then one direction is the same bandwidth in all directions used
|
|
51
|
+
#
|
|
52
|
+
########### Variant 3:
|
|
53
|
+
# used subsets:
|
|
54
|
+
# U = [(), (0,), (1,), (2,), (3,), (4,), (5,),
|
|
55
|
+
# (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]
|
|
56
|
+
# Bandwidths for these subsets:
|
|
57
|
+
# N = [(), (100,), (100,), (100,), (100,), (100,), (100,),
|
|
58
|
+
# (10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,),(10,10,)]
|
|
59
|
+
# Use the subsets U with the bandwiths N. The bandwith N[i] corresponds to the subset U[i]. The bandwidth N[i][j] corresponds to the direction U[i][j]
|
|
60
|
+
|
|
61
|
+
lambdas = np.array([0.0, 1.0]) # used regularisation parameters λ
|
|
62
|
+
|
|
63
|
+
############################
|
|
64
|
+
## Generation of the data ##
|
|
65
|
+
############################
|
|
66
|
+
|
|
67
|
+
X = rng.random((M, d)) # construct the evaluation points for training
|
|
68
|
+
y = np.array(
|
|
69
|
+
[TestFunction(X[i, :].T) for i in range(M)]
|
|
70
|
+
) # evaluate the function at these points
|
|
71
|
+
X_test = rng.random((M_test, d)) #
|
|
72
|
+
y_test = np.array(
|
|
73
|
+
[TestFunction(X_test[i, :].T) for i in range(M_test)]
|
|
74
|
+
) # the same for the test points
|
|
75
|
+
|
|
76
|
+
##########################
|
|
77
|
+
## Do the approximation ##
|
|
78
|
+
##########################
|
|
79
|
+
|
|
80
|
+
ads = ANOVAapprox.approx(X, y, ds=ds, basis="cos", N=bw)
|
|
81
|
+
ads.approximate(lam=lambdas, max_iter=max_iter, solver="lsqr")
|
|
82
|
+
|
|
83
|
+
################################
|
|
84
|
+
## get approximation accuracy ##
|
|
85
|
+
################################
|
|
86
|
+
|
|
87
|
+
# mse = ANOVAapprox.get_mse(ads) # get mse error at the given training points
|
|
88
|
+
mse = ANOVAapprox.get_mse(ads, X_test, y_test) # get mse error at the test points
|
|
89
|
+
λ_min = min(
|
|
90
|
+
mse, key=mse.get
|
|
91
|
+
) # get the regularisation parameter which leads to the minimal error
|
|
92
|
+
mse_min = mse[λ_min]
|
|
93
|
+
|
|
94
|
+
print("mse = " + str(mse_min))
|
|
95
|
+
|
|
96
|
+
###############################################
|
|
97
|
+
## Analyze the model to improve the accuracy ##
|
|
98
|
+
###############################################
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
ar = ANOVAapprox.get_AttributeRanking(ads, λ_min) # get the attrbute ranking
|
|
102
|
+
|
|
103
|
+
plt.figure()
|
|
104
|
+
(markers, stemlines, baseline) = plt.stem(
|
|
105
|
+
np.arange(1, d + 1), # x-Werte (1:d)
|
|
106
|
+
ar, # y-Werte (ar)
|
|
107
|
+
linefmt="C0-", # Stil der Stiele
|
|
108
|
+
markerfmt="C0^", # Stil der Markierung (C0 = erste Farbe, ^ = up-triangle)
|
|
109
|
+
basefmt="k:", # Stil der Basislinie (optional)
|
|
110
|
+
)
|
|
111
|
+
plt.setp(markers, markersize=8)
|
|
112
|
+
plt.yscale("log")
|
|
113
|
+
y_min_calc = 10 ** (np.min(np.log10(ar)) - 0.5)
|
|
114
|
+
plt.ylim(y_min_calc, 1)
|
|
115
|
+
plt.title("Attribute Ranking")
|
|
116
|
+
plt.xlabel("Attribut-Index")
|
|
117
|
+
plt.xlim(0.5, d + 0.5)
|
|
118
|
+
plt.grid(True, which="both", ls="--", linewidth=0.5)
|
|
119
|
+
plt.show() # plot the arrtibute ranking in an logplot
|
|
120
|
+
print("active dimensions: " + str(ar[ar > 1e-2]))
|
|
121
|
+
|
|
122
|
+
gsis = ANOVAapprox.get_GSI(ads, λ_min)
|
|
123
|
+
label = list(ads.U[1:])
|
|
124
|
+
l = len(label)
|
|
125
|
+
plt.figure()
|
|
126
|
+
x_values = np.arange(1, l + 1)
|
|
127
|
+
(markers, stemlines, baseline) = plt.stem(
|
|
128
|
+
x_values, # X-Werte: 1 bis l
|
|
129
|
+
gsis, # Y-Werte: gsis
|
|
130
|
+
linefmt="C0-", # Stil der Stiele
|
|
131
|
+
markerfmt="C0^", # Stil der Markierung (^ = up-triangle)
|
|
132
|
+
basefmt="k:", # Stil der Basislinie
|
|
133
|
+
)
|
|
134
|
+
plt.setp(markers, markersize=8)
|
|
135
|
+
plt.xticks(x_values, label, rotation=45, ha="right")
|
|
136
|
+
plt.xlabel("Input Dimension")
|
|
137
|
+
plt.yscale("log")
|
|
138
|
+
plt.ylim(y_min_calc, 1)
|
|
139
|
+
plt.title("Global sensitivity indices")
|
|
140
|
+
plt.grid(True, which="both", ls="--", linewidth=0.5)
|
|
141
|
+
plt.tight_layout() # Stellt sicher, dass die Labels sichtbar sind
|
|
142
|
+
plt.show()
|
|
143
|
+
print(
|
|
144
|
+
"important dimensional interactions: : "
|
|
145
|
+
+ str([label[i] for i in np.arange(0, l)[gsis > 1e-2]])
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
################################################
|
|
149
|
+
## Approximation with better suited index set ##
|
|
150
|
+
################################################
|
|
151
|
+
|
|
152
|
+
Umask = np.append(np.array([True]), gsis > 1e-2)
|
|
153
|
+
U = [ads.U[i] for i in np.arange(0, len(Umask))[Umask]] # get important subsets
|
|
154
|
+
bws = M / (math.log10(M) * (len(U) - 1)) # calculate frequencies per subset
|
|
155
|
+
N = [
|
|
156
|
+
math.floor(bws ** (1 / max(1, len(u))) / 2) * 2 for u in U
|
|
157
|
+
] # distribute the frequencies evenly and make them even
|
|
158
|
+
N[0] = 0
|
|
159
|
+
|
|
160
|
+
a = ANOVAapprox.approx(
|
|
161
|
+
X, y, U, N, "cos"
|
|
162
|
+
) # generate the data structure for the approximation
|
|
163
|
+
a.approximate(
|
|
164
|
+
lam=lambdas, max_iter=max_iter, solver="lsqr"
|
|
165
|
+
) # do the approximation for all specified regularisation parameters
|
|
166
|
+
|
|
167
|
+
mse = ANOVAapprox.get_mse(a, X_test, y_test) # get mse error at the test points
|
|
168
|
+
λ_min = min(
|
|
169
|
+
mse, key=mse.get
|
|
170
|
+
) # get the regularisation parameter which leads to the minimal error
|
|
171
|
+
mse_min = mse[λ_min]
|
|
172
|
+
print("mse = " + str(mse_min))
|
|
173
|
+
|
|
174
|
+
########################
|
|
175
|
+
## Evaluate the model ##
|
|
176
|
+
########################
|
|
177
|
+
|
|
178
|
+
# y_approx = a.evaluate(lam=λ_min) # evaluate the approximation at the training points for the regularisation λ_min
|
|
179
|
+
# y_approx = a.evaluate(X=X_test, lam=λ_min) # evaluate the approximation at the points X_test for the regularisation λ_min
|
|
180
|
+
|
|
181
|
+
# In the following we plot the real and the approximated anova term for the subset u=[3]
|
|
182
|
+
|
|
183
|
+
y_eval_anova = a.evaluateANOVAterms(
|
|
184
|
+
X=X_test, lam=λ_min
|
|
185
|
+
) # evaluate all of the ANOVA terms
|
|
186
|
+
pos = a.U.index((3,)) # find the index for the subset u=[3]
|
|
187
|
+
y_eval_anova_3 = y_eval_anova.T[pos]
|
|
188
|
+
|
|
189
|
+
perm = np.argsort(X_test.T[3])
|
|
190
|
+
X_plot = X_test.T[3][perm]
|
|
191
|
+
y_eval_anova_3_plot = np.real(y_eval_anova_3[perm])
|
|
192
|
+
y_anova_3_plot = -np.exp(X_plot) + np.exp(1) - 1
|
|
193
|
+
|
|
194
|
+
plt.figure()
|
|
195
|
+
plt.plot(X_plot, y_eval_anova_3_plot, label="approximation")
|
|
196
|
+
plt.plot(X_plot, y_anova_3_plot, label="ANOVA term") # ... "ANOVA term"]
|
|
197
|
+
plt.title("Approximation of the ANOVA term 4") # title = "..."
|
|
198
|
+
plt.legend() # Zeigt die Labels/Legende an
|
|
199
|
+
plt.grid(True, linestyle="--", alpha=0.7)
|
|
200
|
+
plt.show()
|
|
@@ -68,6 +68,7 @@ lambdas = np.array([0.0, 1.0]) # used regularisation parameters λ
|
|
|
68
68
|
############################
|
|
69
69
|
## Generation of the data ##
|
|
70
70
|
############################
|
|
71
|
+
|
|
71
72
|
X = rng.random((M, d)) - 0.5 # construct the evaluation points for training
|
|
72
73
|
y = np.array(
|
|
73
74
|
[TestFunction(X[i, :].T) for i in range(M)], dtype=complex
|
|
@@ -82,7 +83,7 @@ y_test = np.array(
|
|
|
82
83
|
##########################
|
|
83
84
|
|
|
84
85
|
ads = ANOVAapprox.approx(X, y, ds=ds, basis="per", N=bw)
|
|
85
|
-
ads.approximate(lam=lambdas, solver="lsqr")
|
|
86
|
+
ads.approximate(lam=lambdas, max_iter=max_iter, solver="lsqr")
|
|
86
87
|
|
|
87
88
|
################################
|
|
88
89
|
## get approximation accuracy ##
|
|
@@ -165,7 +166,7 @@ a = ANOVAapprox.approx(
|
|
|
165
166
|
X, y, U, N, "per"
|
|
166
167
|
) # generate the data structure for the approximation
|
|
167
168
|
a.approximate(
|
|
168
|
-
lam=lambdas, solver="lsqr"
|
|
169
|
+
lam=lambdas, max_iter=max_iter, solver="lsqr"
|
|
169
170
|
) # do the approximation for all specified regularisation parameters
|
|
170
171
|
|
|
171
172
|
mse = ANOVAapprox.get_mse(a, X_test, y_test) # get mse error at the test points
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# pip install pyANOVAapprox
|
|
2
|
+
|
|
3
|
+
# Example for approximating an non periodic function
|
|
4
|
+
|
|
5
|
+
import math
|
|
6
|
+
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
import pyANOVAapprox as ANOVAapprox
|
|
11
|
+
|
|
12
|
+
basis = "chui3"
|
|
13
|
+
# for 'cos' the samples have to be in [0,1]^d
|
|
14
|
+
# for a periodic function use 'per' or wavelets 'chui2', 'chui3', 'chui4' (samples have to be in [-0.5,0.5]^d here, 'chuim' are the Chui-Wang wavelets of order m)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def TestFunction(x): # this function is of the form f_0 + f_1 + f_2 + f_3 + f_4 + f_2,3
|
|
18
|
+
return 2 * abs(x[0]) + abs(math.sin(math.pi * x[1] * x[2])) + np.cos(3 + x[3])
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
rng = np.random.default_rng(1234)
|
|
22
|
+
|
|
23
|
+
##################################
|
|
24
|
+
## Definition of the parameters ##
|
|
25
|
+
##################################
|
|
26
|
+
|
|
27
|
+
d = 8 # dimension
|
|
28
|
+
q = 2 # superposition dimension
|
|
29
|
+
M = 10000 # number of used evaluation points to train the model
|
|
30
|
+
M_test = 10000 # number of used evaluation points to test the accuracity the model
|
|
31
|
+
N = [5, 2] # number of parameters, should be vector of length q:
|
|
32
|
+
# for wavelets the total number of parameters scales exponentially, i.e.:
|
|
33
|
+
# for q = 1 and N = [N1] the total number of parameters scales like ~O(d*2^N1)
|
|
34
|
+
# for q = 2 and N = [N1 , N2] the total number of parameters scales like ~O(d*2^N1) + O(d^2 * N2*2^N2)
|
|
35
|
+
|
|
36
|
+
lambdas = np.array([0.0]) # used regularisation parameters λ
|
|
37
|
+
|
|
38
|
+
############################
|
|
39
|
+
## Generation of the data ##
|
|
40
|
+
############################
|
|
41
|
+
|
|
42
|
+
if basis == "chui2" or basis == "chui3" or basis == "chui4" or basis == "per":
|
|
43
|
+
X = (
|
|
44
|
+
rng.random((M, d)) - 0.5
|
|
45
|
+
) # for perioidic approximation samples have to be in [-0.5,0.5]^d
|
|
46
|
+
elif basis == "cos":
|
|
47
|
+
X = rng.random((M, d))
|
|
48
|
+
y = np.array(
|
|
49
|
+
[TestFunction(X[i, :].T) for i in range(M)]
|
|
50
|
+
) # evaluate the function at these points
|
|
51
|
+
|
|
52
|
+
if (
|
|
53
|
+
basis == "chui1"
|
|
54
|
+
or basis == "chui2"
|
|
55
|
+
or basis == "chui3"
|
|
56
|
+
or basis == "chui4"
|
|
57
|
+
or basis == "per"
|
|
58
|
+
):
|
|
59
|
+
X_test = (
|
|
60
|
+
rng.random((M_test, d)) - 0.5
|
|
61
|
+
) # for perioidic approximation samples have to be in [-0.5,0.5]^d
|
|
62
|
+
elif basis == "cos":
|
|
63
|
+
X_test = rng.random((M_test, d))
|
|
64
|
+
y_test = np.array(
|
|
65
|
+
[TestFunction(X_test[i, :].T) for i in range(M_test)]
|
|
66
|
+
) # the same for the test points
|
|
67
|
+
|
|
68
|
+
##########################
|
|
69
|
+
## Do the approximation ##
|
|
70
|
+
##########################
|
|
71
|
+
|
|
72
|
+
#### construct model for ANOVAapprox ####
|
|
73
|
+
anova_model = ANOVAapprox.approx(X, y, ds=q, basis=basis, N=N)
|
|
74
|
+
|
|
75
|
+
#### Do approximation by least-squares ###
|
|
76
|
+
anova_model.approximate(lam=lambdas, solver="lsqr")
|
|
77
|
+
print("Total number of used parameters = " + str(len(anova_model.fc[lambdas[0]].vec())))
|
|
78
|
+
|
|
79
|
+
#######################
|
|
80
|
+
## Analyze the model ##
|
|
81
|
+
#######################
|
|
82
|
+
|
|
83
|
+
### Do sensitivity analysis ####
|
|
84
|
+
gsis = ANOVAapprox.get_GSI(
|
|
85
|
+
anova_model, 0.0
|
|
86
|
+
) # calculates indices for importance of terms (gsis is vector, with indices belonging to terms in anova_model.U)
|
|
87
|
+
gsis_as_dict = ANOVAapprox.get_GSI(anova_model,0.0,dict=true)
|
|
88
|
+
|
|
89
|
+
y_min_calc = 10 ** (np.min(np.log10(gsis)) - 0.5)
|
|
90
|
+
label = list(anova_model.U[1:])
|
|
91
|
+
l = len(label)
|
|
92
|
+
plt.figure()
|
|
93
|
+
x_values = np.arange(1, l + 1)
|
|
94
|
+
(markers, stemlines, baseline) = plt.stem(
|
|
95
|
+
x_values, # X-Werte: 1 bis l
|
|
96
|
+
gsis, # Y-Werte: gsis
|
|
97
|
+
linefmt="C0-", # Stil der Stiele
|
|
98
|
+
markerfmt="C0^", # Stil der Markierung (^ = up-triangle)
|
|
99
|
+
basefmt="k:", # Stil der Basislinie
|
|
100
|
+
)
|
|
101
|
+
plt.setp(markers, markersize=8)
|
|
102
|
+
plt.xticks(x_values, label, rotation=45, ha="right")
|
|
103
|
+
plt.xlabel("Input Dimension")
|
|
104
|
+
plt.yscale("log")
|
|
105
|
+
plt.ylim(y_min_calc, 1)
|
|
106
|
+
plt.title("Global sensitivity indices")
|
|
107
|
+
plt.grid(True, which="both", ls="--", linewidth=0.5)
|
|
108
|
+
plt.tight_layout() # Stellt sicher, dass die Labels sichtbar sind
|
|
109
|
+
plt.show()
|
|
110
|
+
|
|
111
|
+
################################
|
|
112
|
+
## get approximation accuracy ##
|
|
113
|
+
################################
|
|
114
|
+
|
|
115
|
+
### error analysis ###
|
|
116
|
+
mse_train = ANOVAapprox.get_mse(anova_model, lam=0.0)
|
|
117
|
+
mse_test = ANOVAapprox.get_mse(anova_model, X_test, y_test, lam=0.0)
|
|
118
|
+
|
|
119
|
+
print("MSE on test points: " + str(mse_test))
|
|
120
|
+
|
|
121
|
+
################################################
|
|
122
|
+
## Approximation with better suited index set ##
|
|
123
|
+
################################################
|
|
124
|
+
|
|
125
|
+
U = ANOVAapprox.get_ActiveSet(anova_model, [0.01, 0.01], lam=0.0)
|
|
126
|
+
print("Found index-set U: " + str(U))
|
|
127
|
+
anova_model = ANOVAapprox.approx(
|
|
128
|
+
X, y, U=U, N=[i + 2 for i in N], basis=basis
|
|
129
|
+
) # increase number of paramers in N for the important terms
|
|
130
|
+
anova_model.approximate(lam=lambdas)
|
|
131
|
+
print("Total number of used parameters = " + str(len(anova_model.fc[lambdas[0]].vec())))
|
|
132
|
+
mse_train = ANOVAapprox.get_mse(anova_model, lam=0.0)
|
|
133
|
+
mse_test = ANOVAapprox.get_mse(anova_model, X_test, y_test, lam=0.0)
|
|
134
|
+
print("MSE on test points after ANOVA truncation: " + str(mse_test))
|
|
@@ -9,27 +9,6 @@ from scipy.special import erf
|
|
|
9
9
|
|
|
10
10
|
# from sklearn.metrics import roc_auc_score
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
def get_superposition_set(d, ds): # TODO: Später funktion aut GT verwenden
|
|
14
|
-
"""
|
|
15
|
-
get_superposition_set( d::Int, ds::Int )::Vector{Vector{Int}}
|
|
16
|
-
|
|
17
|
-
This function returns ``U^{(d,ds)} = \{ \pmb u \subset \{1,2,\dots,d\} : |\pmb u| \leq ds \}``.
|
|
18
|
-
"""
|
|
19
|
-
nset = [[j] for j in range(d)]
|
|
20
|
-
returnset = [[]] + nset
|
|
21
|
-
for i in range(ds - 1):
|
|
22
|
-
nextnset = []
|
|
23
|
-
for s in nset:
|
|
24
|
-
for j in range(d):
|
|
25
|
-
if s[-1] < j:
|
|
26
|
-
nextnset.append(s + [j])
|
|
27
|
-
returnset = returnset + nextnset
|
|
28
|
-
nset = nextnset
|
|
29
|
-
|
|
30
|
-
return [tuple(item) for item in returnset]
|
|
31
|
-
|
|
32
|
-
|
|
33
12
|
def bisection(l, r, fun, maxiter=1000):
|
|
34
13
|
lval = fun(l)
|
|
35
14
|
rval = fun(r)
|
|
@@ -47,7 +47,7 @@ def _GSI(a, lam, Dict): # helpfunction for get_GSI
|
|
|
47
47
|
|
|
48
48
|
if Dict:
|
|
49
49
|
if a.basis.startswith("chui"):
|
|
50
|
-
variances =
|
|
50
|
+
variances = a.fc[lam].norms(Dict=True, m=int(a.basis[-1]))
|
|
51
51
|
else:
|
|
52
52
|
variances = a.fc[lam].norms(Dict=True)
|
|
53
53
|
return {u: (variances[u] ** 2) / variance_f for u in list(variances)}
|
|
@@ -129,7 +129,7 @@ def lam_ActiveSet(a, eps, lam): # helpfunction for get_ActiveSet
|
|
|
129
129
|
n += 1
|
|
130
130
|
|
|
131
131
|
U_active = [None] * (n + 1)
|
|
132
|
-
U_active[0] =
|
|
132
|
+
U_active[0] = ()
|
|
133
133
|
|
|
134
134
|
idx = 1
|
|
135
135
|
for i in range(len(gsi)):
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from pyGroupedTransforms.GroupedTransform import * # TODO: Kann wahrscheinlich weg sobald in pyGroupedTransform GreoupedTransform exportiert wird
|
|
2
|
-
|
|
3
1
|
from pyANOVAapprox import *
|
|
4
2
|
from pyANOVAapprox.fista import *
|
|
5
3
|
|
|
@@ -83,6 +81,7 @@ class approx:
|
|
|
83
81
|
classification=False,
|
|
84
82
|
basis_vect=[],
|
|
85
83
|
fastmult=None,
|
|
84
|
+
parallel=True,
|
|
86
85
|
ds=None,
|
|
87
86
|
):
|
|
88
87
|
|
|
@@ -185,6 +184,7 @@ class approx:
|
|
|
185
184
|
N=N,
|
|
186
185
|
X=Xt,
|
|
187
186
|
fastmult=fastmult,
|
|
187
|
+
parallel=parallel,
|
|
188
188
|
basis_vect=basis_vect,
|
|
189
189
|
)
|
|
190
190
|
|
|
@@ -198,6 +198,7 @@ class approx:
|
|
|
198
198
|
self.classification = classification
|
|
199
199
|
self.basis_vect = basis_vect
|
|
200
200
|
self.fastmult = fastmult
|
|
201
|
+
self.parallel = parallel
|
|
201
202
|
|
|
202
203
|
def Approximate(
|
|
203
204
|
self, lam, max_iter=50, weights=None, verbose=False, solver=None, tol=1e-8
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
src_aa = os.path.abspath(os.path.join(os.getcwd(), "src"))
|
|
5
|
+
sys.path.insert(0, src_aa)
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from pyGroupedTransforms import *
|
|
9
|
+
from TestFunctionPeriodic import *
|
|
10
|
+
|
|
11
|
+
import pyANOVAapprox as ANOVAapprox
|
|
12
|
+
|
|
13
|
+
d = 6
|
|
14
|
+
ds = 2
|
|
15
|
+
M = 10000
|
|
16
|
+
max_iter = 50
|
|
17
|
+
bw = [4, 4]
|
|
18
|
+
lambdas = np.array([0.0, 1.0])
|
|
19
|
+
|
|
20
|
+
rng = np.random.default_rng()
|
|
21
|
+
X = rng.random((M, d)) - 0.5
|
|
22
|
+
y = np.array([f(X[i, :].T) for i in range(M)])
|
|
23
|
+
X_test = rng.random((M, d)) - 0.5
|
|
24
|
+
y_test = np.array([f(X_test[i, :].T) for i in range(M)])
|
|
25
|
+
|
|
26
|
+
ads = ANOVAapprox.approx(X, y, ds=ds, N=bw, basis="chui2")
|
|
27
|
+
ads.approximate(lam=lambdas, solver="lsqr")
|
|
28
|
+
|
|
29
|
+
print("AR: " + str(sum(ANOVAapprox.get_AttributeRanking(ads, 0.0))))
|
|
30
|
+
assert abs(sum(ANOVAapprox.get_AttributeRanking(ads, 0.0)) - 1) < 0.0001
|
|
31
|
+
|
|
32
|
+
bw = ANOVAapprox.get_orderDependentBW(AS, [4, 4])
|
|
33
|
+
aU = ANOVAapprox.approx(X, y, U=AS, N=bw, basis="chui2")
|
|
34
|
+
aU.approximate(lam=lambdas, solver="lsqr")
|
|
35
|
+
|
|
36
|
+
err_l2_ds = ANOVAapprox.get_l2_error(ads)[0.0]
|
|
37
|
+
err_l2_U = ANOVAapprox.get_l2_error(aU)[0.0]
|
|
38
|
+
err_l2_rand_ds = ANOVAapprox.get_l2_error(ads, X_test, y_test)[0.0]
|
|
39
|
+
err_l2_rand_U = ANOVAapprox.get_l2_error(aU, X_test, y_test)[0.0]
|
|
40
|
+
|
|
41
|
+
print("== WAVELET LSQR ==")
|
|
42
|
+
print("l2 ds: ", err_l2_ds)
|
|
43
|
+
print("l2 U: ", err_l2_U)
|
|
44
|
+
print("l2 rand ds: ", err_l2_rand_ds)
|
|
45
|
+
print("l2 rand U: ", err_l2_rand_U)
|
|
46
|
+
|
|
47
|
+
assert err_l2_ds < 0.01
|
|
48
|
+
assert err_l2_U < 0.01 # maybe restrict to 0.005
|
|
49
|
+
assert err_l2_rand_ds < 0.01
|
|
50
|
+
assert err_l2_rand_U < 0.01
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# hier bin ich unverhofft auf probleme gestoßen, deswegen erstmal ein dummyfile nur...
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|