Keras LSTM: modeling the layers - neural-network

I'm new to Keras LSTM and I building a script for prediction based on time series.
I have the data set below which describe users' power consumption in a year
User mai/13 jun/13 jul/13 ago/13 set/13 out/13 nov/13 dez/13 jan/14 fev/14 mar/14 abr/14
x1 88 99 108 90 86 79 83 75 80 69 75 61
x2 0 143 163 127 174 199 177 140 100 100 130 119
x3 51 50 41 42 51 48 58 53 53 37 47 41
x4 181 211 166 105 128 123 125 98 114 58 4 0
x5 173 187 180 195 211 212 231 188 193 168 166 0
x6 343 321 293 272 400 397 467 392 409 306 408 353
x7 215 150 161 148 153 130 165 166 198 166 150 148
x8 100 140 132 119 121 125 148 135 144 123 124 16
x9 197 193 181 161 201 161 227 154 176 148 171 172
x10 356 371 347 347 363 377 423 373 395 338 337 302
For each user, my script split the data in windows with size n, i.e., if n=6, user x1 will have the following dataset
88 99 108 90 86 79
99 108 90 86 79 83
108 90 86 79 83 75
90 86 79 83 75 80
86 79 83 75 80 69
79 83 75 80 69 75
83 75 80 69 75 61
I want my net to learn from the patterns of each window, so when I'm going to test it, based on a new window, it predicts a value considering the previous values.
Considering these variables:
dataset_length => number of months
dataset_dim => number of users
sequence_length => window size
The net I'm thinking about is:
1st layer: LSTM with sequence_length units, input_shape(None, 1) and return_sequences set true
2nd layer: LSTM with sequence_length*2 units and return_sequences set false
3rd layer: Dense with 1 unit
Is there anything wrong on my net layout? I'm testing the net with a little bit more data and not getting a very good result (high loss). What can I change for a better prediction? Do I need more layers?
Please let me know if you need some piece of code or the test results.

Related

How to apply k-means without normalization and k-means with normalization on my dataset?

I want to calculate the accuracy of my k-means clustering without normalization and k-means clustering with normalization and want to compare the results.
My dataset looks like this:
age chol
63 233
37 250
41 204
56 236
57 354
57 192
56 294
44 263
52 199
57 168
54 239
48 275
49 266
64 211
58 283
50 219
58 340
66 226
43 247
69 239
59 234
44 233
42 226
61 243
40 199
71 302
59 212
51 175
65 417
53 197
41 198
65 177
44 219
54 273
51 213
46 177
54 304
54 232
65 269
65 360
51 308
48 245
45 208
53 264
39 321
52 325
44 235
47 257
53 216
53 234
How can I write the code for it in Matlab and plot it?

MATLAB Serial incorrectly sending values

I am trying to communicate with a StepRocker motor controller/drive using MATLAB. I have figured out how to format their commands and have been able to get it to move to many of commands. Their commands require that the values be sent in a binary format over RS-232. I started running into some issues and started using an Arduino to echo my commands.
I am currently sending the values 1 - 255 just to test sending bytes over the serial channel. I am sending it to an Arduino and reading the bytes back out of the Arduino. All numbers work except for the numbers between 128 and 159. This is problematic since some of my commands require values in this range.
MATLAB Script:
obj = instrfind; delete(obj); % cleanup any lost objects
clear; close force all; clc; % clear the workspace
sM = serial('COM2','BaudRate',9600, 'Terminator', 'CR', 'Timeout', 10);
fopen(sM);
pause(2); % give port time to open
% make list of numbers 1-255, skip 10/13 since they terminate on the
% arduino
cmd = [1:9 11:12 14:255];
% Send command and get echo
fprintf(sM,cmd);
pause(0.5); % give time for echo
echo = fscanf(sM);
uint8(echo)
fclose(sM);
After executing this script I get the following output:
ans =
Columns 1 through 22
1 2 3 4 5 6 7 8 9 11 12 14 15 16 17 18 19 20 21 22 23 24
Columns 23 through 44
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
Columns 45 through 66
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
Columns 67 through 88
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
Columns 89 through 110
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
Columns 111 through 132
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 63 63 63 63 63 63 63
Columns 133 through 154
63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63
Columns 155 through 176
63 63 63 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
Columns 177 through 198
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
Columns 199 through 220
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
Columns 221 through 242
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
Columns 243 through 254
245 246 247 248 249 250 251 252 253 254 255 13
Looking at the output, you can see that the numbers between 128 and 159 all come through as 63. I am at a loss for what is causing this issue. This is very repeatable, and the problem occurs anytime there is a number in this range, no matter its position in the string, no matter the length of the serial string.
Arduino Code:
bool stringComplete = false;
String inputString = "";
void setup() {
Serial.begin(9600);
}
void loop() {
if (stringComplete) {
Serial.print(inputString);
stringComplete = false;
inputString = "";
}
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == '\r') {
stringComplete = true;
}
}
}
Any suggestions or ideas on how to solve this problem?

changing the range / limits on a polar chart in octave / matlab

I'm using Octave 4.0 using Linux which is similar to Matlab
Is it possible to have a different range of numbers on a polar chart and have them show up along with the degrees also?
The normal polar plot goes from 0-359 degrees shown in black in image, I would like the range and tick values to be from 0 to 100 shown in red in the image is this possible? If so can two ranges be shown on a polar plot at the same time (0-359 and 0-100) almost like plotting 2 y axis using plotyy on the same plot?
See image below of polar plot
Here's the the numbers 0-359 and there corresponding numbers 0-100 matching up.
0 0
1 0.27855
2 0.5571
3 0.83565
4 1.11421
5 1.39276
6 1.67131
7 1.94986
8 2.22841
9 2.50696
10 2.78552
11 3.06407
12 3.34262
13 3.62117
14 3.89972
15 4.17827
16 4.45682
17 4.73538
18 5.01393
19 5.29248
20 5.57103
21 5.84958
22 6.12813
23 6.40669
24 6.68524
25 6.96379
26 7.24234
27 7.52089
28 7.79944
29 8.07799
30 8.35655
31 8.6351
32 8.91365
33 9.1922
34 9.47075
35 9.7493
36 10.0279
37 10.3064
38 10.585
39 10.8635
40 11.1421
41 11.4206
42 11.6992
43 11.9777
44 12.2563
45 12.5348
46 12.8134
47 13.0919
48 13.3705
49 13.649
50 13.9276
51 14.2061
52 14.4847
53 14.7632
54 15.0418
55 15.3203
56 15.5989
57 15.8774
58 16.156
59 16.4345
60 16.7131
61 16.9916
62 17.2702
63 17.5487
64 17.8273
65 18.1058
66 18.3844
67 18.663
68 18.9415
69 19.2201
70 19.4986
71 19.7772
72 20.0557
73 20.3343
74 20.6128
75 20.8914
76 21.1699
77 21.4485
78 21.727
79 22.0056
80 22.2841
81 22.5627
82 22.8412
83 23.1198
84 23.3983
85 23.6769
86 23.9554
87 24.234
88 24.5125
89 24.7911
90 25.0696
91 25.3482
92 25.6267
93 25.9053
94 26.1838
95 26.4624
96 26.7409
97 27.0195
98 27.2981
99 27.5766
100 27.8552
101 28.1337
102 28.4123
103 28.6908
104 28.9694
105 29.2479
106 29.5265
107 29.805
108 30.0836
109 30.3621
110 30.6407
111 30.9192
112 31.1978
113 31.4763
114 31.7549
115 32.0334
116 32.312
117 32.5905
118 32.8691
119 33.1476
120 33.4262
121 33.7047
122 33.9833
123 34.2618
124 34.5404
125 34.8189
126 35.0975
127 35.376
128 35.6546
129 35.9331
130 36.2117
131 36.4903
132 36.7688
133 37.0474
134 37.3259
135 37.6045
136 37.883
137 38.1616
138 38.4401
139 38.7187
140 38.9972
141 39.2758
142 39.5543
143 39.8329
144 40.1114
145 40.39
146 40.6685
147 40.9471
148 41.2256
149 41.5042
150 41.7827
151 42.0613
152 42.3398
153 42.6184
154 42.8969
155 43.1755
156 43.454
157 43.7326
158 44.0111
159 44.2897
160 44.5682
161 44.8468
162 45.1253
163 45.4039
164 45.6825
165 45.961
166 46.2396
167 46.5181
168 46.7967
169 47.0752
170 47.3538
171 47.6323
172 47.9109
173 48.1894
174 48.468
175 48.7465
176 49.0251
177 49.3036
178 49.5822
179 49.8607
180 50.1393
181 50.4178
182 50.6964
183 50.9749
184 51.2535
185 51.532
186 51.8106
187 52.0891
188 52.3677
189 52.6462
190 52.9248
191 53.2033
192 53.4819
193 53.7604
194 54.039
195 54.3175
196 54.5961
197 54.8747
198 55.1532
199 55.4318
200 55.7103
201 55.9889
202 56.2674
203 56.546
204 56.8245
205 57.1031
206 57.3816
207 57.6602
208 57.9387
209 58.2173
210 58.4958
211 58.7744
212 59.0529
213 59.3315
214 59.61
215 59.8886
216 60.1671
217 60.4457
218 60.7242
219 61.0028
220 61.2813
221 61.5599
222 61.8384
223 62.117
224 62.3955
225 62.6741
226 62.9526
227 63.2312
228 63.5097
229 63.7883
230 64.0669
231 64.3454
232 64.624
233 64.9025
234 65.1811
235 65.4596
236 65.7382
237 66.0167
238 66.2953
239 66.5738
240 66.8524
241 67.1309
242 67.4095
243 67.688
244 67.9666
245 68.2451
246 68.5237
247 68.8022
248 69.0808
249 69.3593
250 69.6379
251 69.9164
252 70.195
253 70.4735
254 70.7521
255 71.0306
256 71.3092
257 71.5877
258 71.8663
259 72.1448
260 72.4234
261 72.7019
262 72.9805
263 73.2591
264 73.5376
265 73.8162
266 74.0947
267 74.3733
268 74.6518
269 74.9304
270 75.2089
271 75.4875
272 75.766
273 76.0446
274 76.3231
275 76.6017
276 76.8802
277 77.1588
278 77.4373
279 77.7159
280 77.9944
281 78.273
282 78.5515
283 78.8301
284 79.1086
285 79.3872
286 79.6657
287 79.9443
288 80.2228
289 80.5014
290 80.7799
291 81.0585
292 81.337
293 81.6156
294 81.8942
295 82.1727
296 82.4513
297 82.7298
298 83.0084
299 83.2869
300 83.5655
301 83.844
302 84.1226
303 84.4011
304 84.6797
305 84.9582
306 85.2368
307 85.5153
308 85.7939
309 86.0724
310 86.351
311 86.6295
312 86.9081
313 87.1866
314 87.4652
315 87.7437
316 88.0223
317 88.3008
318 88.5794
319 88.8579
320 89.1365
321 89.415
322 89.6936
323 89.9721
324 90.2507
325 90.5292
326 90.8078
327 91.0864
328 91.3649
329 91.6435
330 91.922
331 92.2006
332 92.4791
333 92.7577
334 93.0362
335 93.3148
336 93.5933
337 93.8719
338 94.1504
339 94.429
340 94.7075
341 94.9861
342 95.2646
343 95.5432
344 95.8217
345 96.1003
346 96.3788
347 96.6574
348 96.9359
349 97.2145
350 97.493
351 97.7716
352 98.0501
353 98.3287
354 98.6072
355 98.8858
356 99.1643
357 99.4429
358 99.7214
359 100
Here's an image of the numbers 0-359 and there corresponding numbers 0-100 matching up.
Numbers matching up
The polar plot object in Octave adds the rtick and ttick properties to the parent axes which allows you to change the location of the ticks, however, there is unfortunately no tticklabel property that we can use to easily find and modify the theta tick marks.
Instead, we can plot your plot that you want the theta range to be 0 - 100 by first transforming your data to instead be 0 - 2*pi (as is expected by polar). Then after plotting both, we can use findall to locate all text objects, figure out which ones are the theta ticks, create a copy of them and modify one of the sets to appear to be 0 - 100.
% Your first plot is going to use the 0 - 2pi range for theta
theta1 = linspace(0, 2*pi, 1000);
rho1 = sin(theta1 * 5);
plot1 = polar(theta1, rho1);
hold on
% For your second plot, just transform your 0 - 100 range to be 0 - 360 instead
theta2 = 0:100;
rho2 = linspace(0, 1, numel(theta2));
modtheta2 = 2*pi * (theta2 ./ 100);
plot2 = polar(modtheta2, rho2);
% Now we need to modify all of the labels
% Find all of the original labels
labels = findall(gca, 'type', 'text');
% Figure out which ones are the radial labels. To do this we compute the distance
% from the center of the plot and find the most common distance
distances = cellfun(#(x)norm(x(1:2)), get(labels, 'Position'));
% Figure out the most common
[~, ~, b] = unique(round(distances * 100));
h = hist(b, 1:max(b));
labels = labels(b == find(h == max(h)));
% Make a copy of these labels (have to use arrayfun for 4.0.x compatibility)
blacklabels = arrayfun(#(L)copyobj(L, gca), labels);
% Shift these labels outward by 15%
arrayfun(#(x)set(x, 'Position', get(x, 'Position') * 1.15), blacklabels);
% Now set the other labels to red and change their values
set(labels, 'COlor', 'red')
for k = 1:numel(labels)
value = str2num(get(labels(k), 'String'))
% Convert the value to be between 0 and 100
newvalue = 100 * (value / 360);
set(labels(k), 'String', sprintf('%0.2f', newvalue))
end

How to delete all numbers in a vector which are smaller than any previous number?

I have data set like:
1 14.8759
2 14.083
3 0.735268
4 18.2378
5 17.3748
6 4.07867
7 18.2032
8 15.6929
9 4.03338
10 19.0308
11 17.4139
12 17.4139
13 19.8453
14 4.91288
15 20.6746
16 16.578
17 14.8548
18 23.9831
19 19.0691
20 19.0777
21 3.24368
22 25.6457
23 -5.95598
24 32.3198
25 8.20419
26 22.3266
27 17.4016
28 9.0672
29 24.8722
30 24.8262
31 19.8966
32 34.7338
33 29.8088
34 33.1393
35 28.1402
36 35.6231
37 26.4872
38 3.2392
39 5.73463
40 26.4754
41 33.9667
42 27.3048
43 34.75
44 37.2759
45 15.6929
46 28.9686
47 44.6922
48 37.2799
49 25.699
50 45.4923
51 32.2579
52 25.699
53 29.7885
54 50.4719
55 20.6746
56 30.6061
57 38.0448
58 11.5342
59 52.9365
60 44.7128
61 38.0448
62 44.6621
63 13.1939
64 28.9542
65 46.3637
66 13.1939
67 10.7318
68 31.4318
69 29.7885
70 22.3399
71 29.7885
72 26.4754
73 55.4135
74 48.8326
75 42.2395
76 19.0174
77 7.4035
78 13.1939
79 33.9055
80 14.8935
81 27.3048
82 6.56548
83 64.4474
84 48.7848
85 59.5214
86 31.4915
87 59.5214
88 19.8966
89 57.0318
90 21.5631
91 20.7273
92 66.0889
93 58.6749
94 20.6803
95 52.1244
96 16.5242
97 51.3028
98 10.7037
99 12.3958
100 26.5265
101 30.6061
102 74.2826
103 50.4806
104 12.3958
105 17.354
106 40.5832
107 19.8514
108 63.6089
109 27.3559
110 9.06318
111 11.564
112 39.7561
113 29.8368
114 17.3615
115 19.0241
116 69.3539
117 35.6231
118 38.8777
119 34.7394
120 60.3455
121 25.6969
122 54.5637
123 25.6969
124 79.2023
125 31.4876
126 28.184
127 13.2268
128 34.7394
129 12.3602
130 29.0096
131 47.9604
132 82.4815
133 77.5533
134 14.8935
135 33.9055
136 16.5172
137 41.4113
138 34.7956
139 64.4558
140 29.8368
141 19.0108
142 26.5265
143 36.4452
144 50.4761
145 4.87781
146 83.3041
147 61.9694
148 26.5265
149 1.5427
150 71.8344
151 24.8158
152 94.7328
153 19.8915
154 36.4452
155 32.2504
156 26.5265
157 89.0202
158 29.8347
159 93.9223
160 87.3855
161 4.89738
162 88.1694
163 24.0448
164 51.2987
165 65.2679
166 89.8386
167 33.9055
168 67.7414
169 88.9942
170 19.0174
171 92.2651
172 49.6527
173 18.1971
174 19.0108
175 33.9667
176 92.2611
177 32.2789
178 92.2577
179 4.89738
180 102.898
181 34.7956
182 95.5292
183 28.9542
184 91.451
185 25.6457
186 74.2944
187 25.6516
188 47.1323
189 34.7338
190 94.7081
191 97.9775
192 105.334
193 89.812
194 93.8991
195 88.1756
196 10.7318
197 49.611
198 97.1618
199 2.40369
200 44.7128
201 35.6263
202 42.1795
203 53.7678
204 70.2067
205 28.9542
206 19.0241
207 111.849
208 19.8915
209 95.5218
210 38.8723
211 101.238
212 19.8393
213 92.2651
214 102.053
215 24.8221
216 116.713
217 88.9912
218 88.1756
219 115.102
220 58.6995
221 19.8393
222 27.3171
223 23.1511
224 53.7678
225 99.6138
226 120.79
227 32.2579
228 90.6265
229 38.0448
230 48.8284
231 111.054
232 112.608
233 66.9162
234 100.431
235 63.6317
236 19.8334
237 35.6263
238 17.3615
239 2.39774
240 29.7885
241 71.0225
242 66.9162
243 25.6457
244 128.908
245 12.3602
246 93.8991
247 123.218
248 24.8221
249 33.1393
250 110.194
251 31.4547
252 12.3958
253 92.2611
254 10.7037
255 90.6302
256 96.3458
257 102.053
258 37.2167
259 93.0788
260 19.0108
261 102.063
262 16.5617
263 49.611
264 135.388
265 117.522
266 92.2879
267 118.378
268 116.706
269 24.0448
270 128.941
271 132.182
272 137.009
273 48.7848
274 32.2789
275 137.826
276 137.009
277 117.522
278 54.5904
279 16.5172
280 141.064
281 63.6317
282 27.3559
283 108.587
284 38.8723
285 140.247
286 106.13
287 135.426
288 67.7371
289 19.8915
290 112.652
291 27.3227
292 117.522
and want to ignore/delete any Y value which is smaller than its previous value (and delete its corresponding X too) and put the new data set into a new file so that all resulted Y values would be in increasing order.
Thanks.
Assuming:
data = [1 14.8759
2 14.083
3 0.735268
... ... ];
You could do that:
keep = false(size(data, 1), 1);
largest = -Inf;
for i = 1:size(data, 1)
if data(i,2) > largest
largest = data(i,2);
keep(i) = true;
end
end
newdata = data(keep,:)
Result:
newdata =
1.0000 14.8759
4.0000 18.2378
10.0000 19.0308
13.0000 19.8453
15.0000 20.6746
18.0000 23.9831
22.0000 25.6457
24.0000 32.3198
32.0000 34.7338
36.0000 35.6231
44.0000 37.2759
47.0000 44.6922
50.0000 45.4923
54.0000 50.4719
59.0000 52.9365
73.0000 55.4135
83.0000 64.4474
92.0000 66.0889
102.0000 74.2826
124.0000 79.2023
132.0000 82.4815
146.0000 83.3041
152.0000 94.7328
180.0000 102.8980
192.0000 105.3340
207.0000 111.8490
216.0000 116.7130
226.0000 120.7900
244.0000 128.9080
264.0000 135.3880
272.0000 137.0090
275.0000 137.8260
280.0000 141.0640
If you've lot of data then it will be better to use vectorization. Removing for loops will make it faster.
Let's say 'A' is your second column (data).
A = 5 4 8 8 2 5 5 7 8 8;
Since your first column is just index we can leave it for now (Even if it's not you can copy second column to 'A' and proceed).
B = A - [-inf A(1:end-1)];
Aout = [find(B>=0);A(B>=0)];
If your first column is not just index copy it to say 'C' and change the last line to the following.
Aout = [C(B>=0);A(B>=0)];
Use bsxfun to compare each element with all the others, and from that generate a logical index that selects the desired rows:
result = data(~any(triu(bsxfun(#lt, data(:,2).', data(:,2)))), :);

How can I display a large matrix without the word "Columns" appearing?

I want to display a large matrix, but I don't like the words "Columns x to y" to show. How can I do this?
You can use the function NUM2STR to format a large 2-D matrix A into a character array and display that. For example:
>> A = magic(15); %# This would likely break up columns when displayed
>> num2str(A) %# This won't
ans =
122 139 156 173 190 207 224 1 18 35 52 69 86 103 120
138 155 172 189 206 223 15 17 34 51 68 85 102 119 121
154 171 188 205 222 14 16 33 50 67 84 101 118 135 137
170 187 204 221 13 30 32 49 66 83 100 117 134 136 153
186 203 220 12 29 31 48 65 82 99 116 133 150 152 169
202 219 11 28 45 47 64 81 98 115 132 149 151 168 185
218 10 27 44 46 63 80 97 114 131 148 165 167 184 201
9 26 43 60 62 79 96 113 130 147 164 166 183 200 217
25 42 59 61 78 95 112 129 146 163 180 182 199 216 8
41 58 75 77 94 111 128 145 162 179 181 198 215 7 24
57 74 76 93 110 127 144 161 178 195 197 214 6 23 40
73 90 92 109 126 143 160 177 194 196 213 5 22 39 56
89 91 108 125 142 159 176 193 210 212 4 21 38 55 72
105 107 124 141 158 175 192 209 211 3 20 37 54 71 88
106 123 140 157 174 191 208 225 2 19 36 53 70 87 104