-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinselect-demo.html
561 lines (477 loc) · 51.7 KB
/
linselect-demo.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="author" content="Jonathan Landy" />
<meta property="og:type" content="article" />
<meta name="twitter:card" content="summary">
<meta name="keywords" content="linselect, linselect, " />
<meta property="og:title" content="linselect demo: a tech sector stock analysis "/>
<meta property="og:url" content="./linselect-demo" />
<meta property="og:description" content="This is a tutorial post relating to our python feature selection package, linselect. The package allows one to easily identify minimal, informative feature subsets within a given data set. Here, we demonstrate linselect‘s basic API by exploring the relationship between the daily percentage lifts of 50 tech stocks over …" />
<meta property="og:site_name" content="EFAVDB" />
<meta property="og:article:author" content="Jonathan Landy" />
<meta property="og:article:published_time" content="2018-05-31T14:17:00-07:00" />
<meta name="twitter:title" content="linselect demo: a tech sector stock analysis ">
<meta name="twitter:description" content="This is a tutorial post relating to our python feature selection package, linselect. The package allows one to easily identify minimal, informative feature subsets within a given data set. Here, we demonstrate linselect‘s basic API by exploring the relationship between the daily percentage lifts of 50 tech stocks over …">
<title>linselect demo: a tech sector stock analysis · EFAVDB
</title>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Fira+Sans:300,400,700" rel="stylesheet" type='text/css' />
<link href="https://fonts.googleapis.com/css?family=Cardo:400,700" rel="stylesheet" type='text/css' />
<link rel="stylesheet" type="text/css" href="./theme/css/elegant.prod.css" media="screen">
<link rel="stylesheet" type="text/css" href="./theme/css/custom.css" media="screen">
<link rel="apple-touch-icon" sizes="180x180" href="./images/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="./images/favicon-16x16.png">
<link rel="manifest" href="./images/site.webmanifest">
<link rel="mask-icon" href="./images/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
</head>
<body>
<div id="content">
<div class="navbar navbar-static-top">
<div class="navbar-inner">
<div class="container-fluid">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="./"><span class=site-name>EFAVDB</span></a>
<div class="nav-collapse collapse">
<ul class="nav pull-right top-menu">
<li >
<a href=
.
>Home</a>
</li>
<li ><a href="./pages/authors.html">Authors</a></li>
<li ><a href="./categories.html">Categories</a></li>
<li ><a href="./tags.html">Tags</a></li>
<li ><a href="./archives.html">Archives</a></li>
<li><form class="navbar-search" action="./search.html" onsubmit="return validateForm(this.elements['q'].value);"> <input type="text" class="search-query" placeholder="Search" name="q" id="tipue_search_input"></form></li>
</ul>
</div>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span1"></div>
<div class="span10">
<article itemscope>
<div class="row-fluid">
<header class="page-header span8 offset2">
<h1>
<a href="./linselect-demo">
linselect demo: a tech sector stock analysis
</a>
</h1>
</header>
<div class="span2"></div>
</div>
<div class="row-fluid">
<div class="span8 offset2 article-content">
<p>This is a tutorial post relating to our python feature selection package, <code>linselect</code>. The package allows one to easily identify minimal, informative feature subsets within a given data set.</p>
<p>Here, we demonstrate <code>linselect</code><span class="quo">‘</span>s basic <span class="caps">API</span> by exploring the relationship between the daily percentage lifts of 50 tech stocks over one trading year. We will be interested in identifying minimal stock subsets that can be used to predict the lifts of the others.</p>
<p>This is a demonstration walkthrough, with commentary and interpretation throughout. See the package docs folder for docstrings that succinctly detail the <span class="caps">API</span>.</p>
<p>Contents:</p>
<ul>
<li>Load the data and examine some stock traces</li>
<li>FwdSelect, RevSelect; supervised, single target</li>
<li>FwdSelect, RevSelect; supervised, multiple targets</li>
<li>FwdSelect, RevSelect; unsupervised</li>
<li>GenSelect</li>
</ul>
<p>The data and a Jupyter notebook containing the code for this demo are available on our github, <a href="https://github.com/EFavDB/linselect_demos">here</a>.</p>
<p>The <code>linselect</code> package can be found on our github, <a href="https://github.com/efavdb/linselect">here</a>.</p>
<h2>1 - Load the data and examine some stock traces</h2>
<p>In this tutorial, we will explore using <code>linselect</code> to carry out various feature selection tasks on a prepared data set of daily percentage lifts for 50 of the largest tech stocks. This covers data from 2017-04-18 to 2018-04-13. In this section, we load the data and take a look at a couple of the stock traces that we will be studying.</p>
<h3>Load data</h3>
<p>The code snippet below loads the data and shows a small sample.</p>
<div class="highlight"><pre><span></span><code><span class="c1"># load packages </span>
<span class="kn">from</span> <span class="nn">linselect</span> <span class="kn">import</span> <span class="n">FwdSelect</span><span class="p">,</span> <span class="n">RevSelect</span><span class="p">,</span> <span class="n">GenSelect</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
<span class="c1"># load the data, print out a sample </span>
<span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">read_csv</span><span class="p">(</span><span class="s1">'stocks.csv'</span><span class="p">)</span>
<span class="nb">print</span> <span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[:</span><span class="mi">3</span><span class="p">,</span> <span class="p">:</span><span class="mi">5</span><span class="p">]</span>
<span class="nb">print</span> <span class="n">df</span><span class="o">.</span><span class="n">shape</span>
<span class="c1"># date AAPL ADBE ADP ADSK </span>
<span class="c1"># 0 2017-04-18 -0.004442 -0.001385 0.000687 0.004884 </span>
<span class="c1"># 1 2017-04-19 -0.003683 0.003158 0.001374 0.017591 </span>
<span class="c1"># 2 2017-04-20 0.012511 0.009215 0.009503 0.005459 </span>
<span class="c1"># (248, 51) </span>
</code></pre></div>
<p>The last line here shows that there were 248 trading days in the range considered.</p>
<h3>Plot some stock traces</h3>
<p>The plot below shows Apple’s and Google’s daily lifts on top of each other, over our full date range (the code for the plot can be found in our notebook). Visually, it’s clear that the two are highly correlated — when one goes up or down, the other tends to as well. This suggests that it should be possible to get a good fit to any one of the stocks using the changes in each of the other stocks.</p>
<p><a href="./wp-content/uploads/2018/05/apple_google.jpg"><img alt="apple_google" src="./wp-content/uploads/2018/05/apple_google.jpg"></a></p>
<p>In general, a stock’s daily price change should be a function of the market at large, the behavior of its market segment(s) and sub-segment(s), and some idiosyncratic behavior special to the company in question. Given this intuition, it seems reasonable to expect one to be able to fit a given stock given the lifts from just a small subset of the other stocks — stocks representative of the sectors relevant to the stock in question. Adding multiple stocks from each segment shouldn’t provide much additional value since these should be redundant. We’ll confirm this intuition below and use <code>linselect</code> to identify these optimal subsets.</p>
<p><strong>Lesson</strong>: The fluctuations of related stocks are often highly correlated. Below, we will be using <code>linselect</code> to find minimal subsets of the 50 stocks that we can use to develop good linear fits to one, multiple, or all of the others.</p>
<h2>2 - FwdSelect and RevSelect; supervised, single target</h2>
<p>Goal: Demonstrate how to identify subsets of the stocks that can be used to fit a given target stock well.</p>
<ul>
<li>First we carry out a <code>FwdSelect</code> fit to identify good choices.</li>
<li>Next, we compare the <code>FwdSelect</code> and <code>RevSelect</code> results</li>
</ul>
<h3>Forward selection applied to <span class="caps">AAPL</span></h3>
<p>The code snippet below uses our forward selection class, <code>FwdSelect</code> to seek the best feature subsets to fit <span class="caps">AAPL</span>’s performance.</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Define X, y variables </span>
<span class="k">def</span> <span class="nf">get_feature_tickers</span><span class="p">(</span><span class="n">targets</span><span class="p">):</span>
<span class="n">all_tickers</span> <span class="o">=</span> <span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">:]</span><span class="o">.</span><span class="n">columns</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">c</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">all_tickers</span> <span class="k">if</span> <span class="n">c</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">targets</span><span class="p">)</span>
<span class="n">TARGET_TICKERS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'AAPL'</span><span class="p">]</span>
<span class="n">FEATURE_TICKERS</span> <span class="o">=</span> <span class="n">get_feature_tickers</span><span class="p">(</span><span class="n">TARGET_TICKERS</span><span class="p">)</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">FEATURE_TICKERS</span><span class="p">]</span><span class="o">.</span><span class="n">values</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">TARGET_TICKERS</span><span class="p">]</span><span class="o">.</span><span class="n">values</span>
<span class="c1"># Forward step-wise selection </span>
<span class="n">selector</span> <span class="o">=</span> <span class="n">FwdSelect</span><span class="p">()</span>
<span class="n">selector</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="c1"># Print out main results of selection process (ordered feature indices, CODs) </span>
<span class="nb">print</span> <span class="n">selector</span><span class="o">.</span><span class="n">ordered_features</span><span class="p">[:</span><span class="mi">3</span><span class="p">]</span>
<span class="nb">print</span> <span class="n">selector</span><span class="o">.</span><span class="n">ordered_cods</span><span class="p">[:</span><span class="mi">3</span><span class="p">]</span>
<span class="c1"># [25, 7, 41] </span>
<span class="c1"># [0.43813848, 0.54534304, 0.58577418] </span>
</code></pre></div>
<p>The last two lines above print out the main outputs of <code>FwdSelect</code>:</p>
<ul>
<li>The <code>ordered_features</code> list provides the indices of the features, ranked by the algorithm. The first index shown provides the best possible single feature fit to <span class="caps">AAPL</span>, the second index provides the next best addition, etc. Note that we can get the tickers corresponding to these indices using:<br>
<code>python
print [FEATURE_TICKERS[i] for i in selector.ordered_features[:3]]
# ['MSFT' 'AVGO' 'TSM']</code><br>
A little thought plus a Google search rationalizes why these might be the top three predictors for <span class="caps">AAPL</span>: First, Microsoft is probably a good representative of the large-scale tech sector, and second the latter two companies work closely with Apple. <span class="caps">AVGO</span> (Qualcomm) made Apple’s modem chips until very recently, while <span class="caps">TSM</span> (Taiwan semi-conductor) makes the processors for iphones and ipads — and may perhaps soon also provide the CPUs for all Apple computers. Apparently, we can predict <span class="caps">APPL</span> performance using only a combination of (a) a read on the tech sector at large, plus (b) a bit of idiosyncratic information also present in <span class="caps">APPL</span>’s partner stocks.</li>
<li>The <code>ordered_cods</code> list records the coefficient of determination (<span class="caps">COD</span> or R^2) of the fits in question — the first number gives the <span class="caps">COD</span> obtained with just <span class="caps">MSFT</span>, the second with <span class="caps">MSFT</span> and <span class="caps">AVGO</span>, etc.</li>
</ul>
<p>A plot of the values in <code>ordered_cods</code> versus feature count is given below. Here, we have labeled the x-axis with the tickers corresponding to the elements of our <code>selector.ordered_features</code>. We see that the top three features almost fit <span class="caps">AAPL</span>’s performance as well as the full set!</p>
<p><a href="./wp-content/uploads/2018/05/apple.png"><img alt="apple" src="./wp-content/uploads/2018/05/apple.png"></a></p>
<p><strong>Lesson</strong>: We can often use <code>linselect</code> to significantly reduce the dimension of a given feature set, with minimal cost in performance. This can be used to compress a data set and can also improve our understanding of the problem considered.</p>
<p><strong>Lesson</strong>: To get a feel for the effective number of useful features we have at hand, we can plot the output <code>ordered_cods</code> versus feature count.</p>
<h3>Compare forward and reverse selection applied to <span class="caps">TSLA</span></h3>
<p>The code snippet below applies both <code>FwdSelect</code> and <code>RevSelect</code> to seek minimal subsets that fit Tesla’s daily lifts well. The outputs are plotted below this. This shows that <code>FwdSelect</code> performs slightly better when two or fewer features are included here, but that <code>RevSelect</code> finds better subsets after that.</p>
<p><strong>Lesson</strong>: In general, we expect forward selection to work better when looking for small subsets and reverse selection to perform better at large subsets.</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Define X, y variables </span>
<span class="n">TARGET_TICKERS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'TSLA'</span><span class="p">]</span>
<span class="n">FEATURE_TICKERS</span> <span class="o">=</span> <span class="n">get_feature_tickers</span><span class="p">(</span><span class="n">TARGET_TICKERS</span><span class="p">)</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">FEATURE_TICKERS</span><span class="p">]</span><span class="o">.</span><span class="n">values</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">TARGET_TICKERS</span><span class="p">]</span><span class="o">.</span><span class="n">values</span>
<span class="c1"># Forward step-wise selection </span>
<span class="n">selector</span> <span class="o">=</span> <span class="n">FwdSelect</span><span class="p">()</span>
<span class="n">selector</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="c1"># Reverse step-wise selection </span>
<span class="n">selector2</span> <span class="o">=</span> <span class="n">RevSelect</span><span class="p">()</span>
<span class="n">selector2</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
</code></pre></div>
<p><a href="./wp-content/uploads/2018/05/rev2.jpg"><img alt="rev2" src="./wp-content/uploads/2018/05/rev2.jpg"></a></p>
<h2>3 - FwdSelect and RevSelect; supervised, multiple targets</h2>
<p>In the code below, we seek feature subsets that perform well when fitting multiple targets simultaneously.</p>
<p><strong>Lesson</strong>: <code>linselect</code> can be used to find minimal feature subsets useful for fitting multiple targets. The optimal, “perfect score” <span class="caps">COD</span> in this case is equal to number of targets (three in our example).</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Define X, y variables </span>
<span class="n">TARGET_TICKERS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'TSLA'</span><span class="p">,</span> <span class="s1">'ADP'</span><span class="p">,</span> <span class="s1">'NFLX'</span><span class="p">]</span>
<span class="n">FEATURE_TICKERS</span> <span class="o">=</span> <span class="n">get_feature_tickers</span><span class="p">(</span><span class="n">TARGET_TICKERS</span><span class="p">)</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">FEATURE_TICKERS</span><span class="p">]</span><span class="o">.</span><span class="n">values</span>
<span class="n">y</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">TARGET_TICKERS</span><span class="p">]</span><span class="o">.</span><span class="n">values</span>
<span class="c1"># Forward step-wise selection </span>
<span class="n">selector</span> <span class="o">=</span> <span class="n">FwdSelect</span><span class="p">()</span>
<span class="n">selector</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
<span class="c1"># Reverse step-wise selection </span>
<span class="n">selector2</span> <span class="o">=</span> <span class="n">RevSelect</span><span class="p">()</span>
<span class="n">selector2</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
</code></pre></div>
<p><a href="./wp-content/uploads/2018/05/multiple.jpg"><img alt="multiple" src="./wp-content/uploads/2018/05/multiple.jpg"></a></p>
<h2>4 - FwdSelect and RevSelect; unsupervised</h2>
<p>Here, we seek those features that give us a best fit to / linear representation of the whole set. This goal is analogous to that addressed by <span class="caps">PCA</span>, but is a feature selection variant: Whereas <span class="caps">PCA</span> returns a set of linear combinations of the original features, the approach here will return a subset of the original features. This has the benefit of leaving one with a feature subset that is interpretable.</p>
<p>(Note: See [1] for more examples like this. There, I show that if you try to fit smoothed versions of the stock performances, very good, small subsets can be found. Without smoothing, noise obscures this point).</p>
<p><strong>Lesson</strong>: Unsupervised selection seeks to find those features that best describe the full data set — a feature selection analog of <span class="caps">PCA</span>.</p>
<p><strong>Lesson</strong>: Again, a perfect <span class="caps">COD</span> score is equal to the number of targets. In the unsupervised case, this is also the number of features (50 in our example).</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Set X equal to full data set. </span>
<span class="n">ALL_TICKERS</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">:]</span><span class="o">.</span><span class="n">columns</span><span class="p">)</span>
<span class="n">X</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">ALL_TICKERS</span><span class="p">]</span><span class="o">.</span><span class="n">values</span>
<span class="c1"># Stepwise regressions </span>
<span class="n">selector</span> <span class="o">=</span> <span class="n">FwdSelect</span><span class="p">()</span>
<span class="n">selector</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
<span class="n">selector2</span> <span class="o">=</span> <span class="n">RevSelect</span><span class="p">()</span>
<span class="n">selector2</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
</code></pre></div>
<p><a href="./wp-content/uploads/2018/05/unsupervised.jpg"><img alt="unsupervised" src="./wp-content/uploads/2018/05/unsupervised.jpg"></a></p>
<h2>5 - GenSelect</h2>
<p><code>GenSelect</code><span class="quo">‘</span>s <span class="caps">API</span> is designed to expose the full flexibility of the efficient linear stepwise algorithm. Because of this, its <span class="caps">API</span> is somewhat more complex than that of <code>FwdSelect</code> and <code>RevSelect</code>. Here, our aim is to quickly demo this <span class="caps">API</span>.</p>
<p>The Essential ingredients:</p>
<ul>
<li>We pass only a single data matrix <code>X</code>, and must specify which columns are the predictors and which are targets.</li>
<li>Because we might sweep up and down, we cannot define an <code>ordered_features</code> list as in <code>FwdSelect</code> and <code>RevSelect</code> (the best subset of size three now may not contain the features in the best subset of size two). Instead, <code>GenSelect</code> maintains a dictionary <code>best_results</code> that stores information on the best results seen so far for each possible feature count. The keys of this dictionary correspond to the possible feature set sizes. The values are also dictionaries, each having two keys: <code>s</code> and <code>cod</code>. These specify the best feature subset seen so far with size equal to the outer key, and the corresponding <span class="caps">COD</span>, respectively.</li>
<li>We can move back and forth, adding features to or removing them from the predictor set. We can specify the search protocol for doing this.</li>
<li>We can reposition our search to any predictor set location and continue the search from there.</li>
<li>We can access the costs of each possible move from our current location, without stepping.</li>
</ul>
<p>If an <span class="math">\(m \times n\)</span> data matrix <code>X</code> is passed to <code>GenSelect</code>, three Boolean arrays define the state of the search.</p>
<ul>
<li><code>s</code> — This array specifies which of the columns are currently being used as predictors.</li>
<li><code>targets</code> — This specifies which of the columns are the target variables.</li>
<li><code>mobile</code> — This specifies which of the columns are locked into or out of our fit — those that are not mobile are marked <code>False</code>.</li>
</ul>
<p>Note: We usually want the targets to not be mobile — though this is not the case in unsupervised applications. One might sometimes also want to lock certain features into the predictor set, and the <code>mobile</code> parameter can be used to accomplish this.</p>
<h3>Use GenSelect to carry out a forward sweep for <span class="caps">TSLA</span></h3>
<p>The code below carries out a single forward sweep for <span class="caps">TSLA</span>. Note that the <code>protocol</code> argument of <code>search</code> is set to <code>(1, 0)</code>, which gives a forward search (see docstrings). For this reason, our results match those of <code>FwdSelect</code> at this point.</p>
<p><strong>Lesson</strong>: Setting up a basic <code>GenSelect</code> call requires defining a few input parameters.</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Define X </span>
<span class="n">X</span> <span class="o">=</span> <span class="n">df</span><span class="p">[</span><span class="n">ALL_TICKERS</span><span class="p">]</span><span class="o">.</span><span class="n">values</span>
<span class="c1"># Define targets and mobile Boolean arrays </span>
<span class="n">TARGET_TICKERS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'TSLA'</span><span class="p">]</span>
<span class="n">FEATURE_TICKERS</span> <span class="o">=</span> <span class="n">get_feature_tickers</span><span class="p">(</span><span class="n">TARGET_TICKERS</span><span class="p">)</span>
<span class="n">targets</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">in1d</span><span class="p">(</span><span class="n">ALL_TICKERS</span><span class="p">,</span> <span class="n">TARGET_TICKERS</span><span class="p">)</span>
<span class="n">mobile</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">in1d</span><span class="p">(</span><span class="n">ALL_TICKERS</span><span class="p">,</span> <span class="n">FEATURE_TICKERS</span><span class="p">)</span>
<span class="c1"># Set up search with an initial \`position\`. Then search. </span>
<span class="n">selector</span> <span class="o">=</span> <span class="n">GenSelect</span><span class="p">()</span>
<span class="n">selector</span><span class="o">.</span><span class="n">position</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">mobile</span><span class="o">=</span><span class="n">mobile</span><span class="p">,</span> <span class="n">targets</span><span class="o">=</span><span class="n">targets</span><span class="p">)</span>
<span class="n">selector</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">protocol</span><span class="o">=</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">steps</span><span class="o">=</span><span class="n">X</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="c1"># Review best 3 feature set found </span>
<span class="nb">print</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">ALL_TICKERS</span><span class="p">)[</span><span class="n">selector</span><span class="o">.</span><span class="n">best_results</span><span class="p">[</span><span class="mi">3</span><span class="p">][</span><span class="s1">'s'</span><span class="p">]],</span> <span class="n">selector</span><span class="o">.</span><span class="n">best_results</span><span class="p">[</span><span class="mi">3</span><span class="p">][</span><span class="s1">'cod'</span><span class="p">]</span>
<span class="c1"># ['ATVI' 'AVGO' 'CTSH'] 0.225758 </span>
</code></pre></div>
<h3>Continue the search above</h3>
<p>A <code>GenSelect</code> instance always retains a summary of the best results it has seen so far. This means that we can continue a search where we left off after a <code>search</code> call completes. Below, we reposition our search and sweep back and forth to better explore a particular region. Note that this slightly improves our result.</p>
<p><strong>Lesson</strong>: We can carry out general search protocols using <code>GenSelect</code><span class="quo">‘</span>s <code>position</code> and <code>search</code> methods.</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Reposition back to the best fit of size 3 seen above. </span>
<span class="n">s</span> <span class="o">=</span> <span class="n">selector</span><span class="o">.</span><span class="n">best_results</span><span class="p">[</span><span class="mi">3</span><span class="p">][</span><span class="s1">'s'</span><span class="p">]</span>
<span class="n">selector</span><span class="o">.</span><span class="n">position</span><span class="p">(</span><span class="n">s</span><span class="o">=</span><span class="n">s</span><span class="p">)</span>
<span class="c1"># Now sweep back and forth around there a few times. </span>
<span class="n">STEPS</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">SWEEPS</span> <span class="o">=</span> <span class="mi">3</span>
<span class="n">selector</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">protocol</span><span class="o">=</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">steps</span><span class="o">=</span><span class="n">STEPS</span><span class="p">)</span>
<span class="n">selector</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">protocol</span><span class="o">=</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">STEPS</span><span class="p">,</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">STEPS</span><span class="p">),</span> <span class="n">steps</span><span class="o">=</span><span class="n">SWEEPS</span> <span class="o">*</span> <span class="mi">4</span> <span class="o">*</span> <span class="n">STEPS</span><span class="p">)</span>
<span class="c1"># Review best results found now with exactly N_RETAINED features (different from first pass in cell above?) </span>
<span class="nb">print</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">ALL_TICKERS</span><span class="p">)[</span><span class="n">selector</span><span class="o">.</span><span class="n">best_results</span><span class="p">[</span><span class="mi">3</span><span class="p">][</span><span class="s1">'s'</span><span class="p">]],</span> <span class="n">selector</span><span class="o">.</span><span class="n">best_results</span><span class="p">[</span><span class="mi">3</span><span class="p">][</span><span class="s1">'cod'</span><span class="p">]</span>
<span class="c1"># ['AMZN' 'NVDA' 'ZNGA'] 0.229958 </span>
</code></pre></div>
<h3>Compare to forward and reverse search results</h3>
<p>Below, we compare the <span class="caps">COD</span> values of our three classes.</p>
<p><strong>Lesson</strong>: <code>GenSelect</code> can be used to do a more thorough search than <code>FwdSelect</code> and <code>RevSelect</code>, and so can sometimes find better feature subsets.</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Get the best COD values seen for each feature set size from GenSelect search </span>
<span class="n">gen_select_cods</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">X</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]):</span>
<span class="k">if</span> <span class="n">i</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">selector</span><span class="o">.</span><span class="n">best_results</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">gen_select_cods</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">selector</span><span class="o">.</span><span class="n">best_results</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="s1">'cod'</span><span class="p">])</span>
<span class="c1"># Plot cod versus feature set size. </span>
<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplots</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">5</span><span class="p">))</span>
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">gen_select_cods</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s1">'GenSelect'</span><span class="p">)</span>
<span class="c1"># FwdSelect again to get corresponding results. </span>
<span class="n">selector2</span> <span class="o">=</span> <span class="n">FwdSelect</span><span class="p">()</span>
<span class="n">selector2</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">[:,</span> <span class="n">mobile</span><span class="p">],</span> <span class="n">X</span><span class="p">[:,</span> <span class="n">targets</span><span class="p">])</span>
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">selector2</span><span class="o">.</span><span class="n">ordered_cods</span><span class="p">,</span><span class="s1">'--'</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s1">'FwdSelect'</span><span class="p">)</span>
<span class="c1"># RevSelect again to get corresponding results. </span>
<span class="n">selector3</span> <span class="o">=</span> <span class="n">RevSelect</span><span class="p">()</span>
<span class="n">selector3</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">[:,</span> <span class="n">mobile</span><span class="p">],</span> <span class="n">X</span><span class="p">[:,</span> <span class="n">targets</span><span class="p">])</span>
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">selector3</span><span class="o">.</span><span class="n">ordered_cods</span><span class="p">,</span> <span class="s1">'-.'</span><span class="p">,</span><span class="n">label</span><span class="o">=</span><span class="s1">'RevSelect'</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="s1">'Coefficient of Determination (COD or R^2) for </span><span class="si">{target}</span><span class="s1"> vs features retained'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">target</span><span class="o">=</span><span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">TARGET_TICKERS</span><span class="p">)))</span>
<span class="n">plt</span><span class="o">.</span><span class="n">legend</span><span class="p">()</span>
<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</code></pre></div>
<p><a href="./wp-content/uploads/2018/05/comparison.jpg"><img alt="comparison" src="./wp-content/uploads/2018/05/comparison.jpg"></a></p>
<h3>Examine the cost of removing a feature from the predictor set</h3>
<p>Below, we reposition to the best feature set of size 10 seen so far. We then apply the method <code>reverse_cods</code> to expose the cost of removing each of these individuals from the predictor set at this point. Were we to take a reverse step, the feature with the least cost would be the one taken (looks like <span class="caps">FB</span> from the plot).</p>
<p><strong>Lesson</strong>: We can easily access the costs associated with removing individual features from our current location. We can also access the <span class="caps">COD</span> gains associated with adding in new features by calling the <code>forward_cods</code> method.</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Reposition </span>
<span class="n">s</span> <span class="o">=</span> <span class="n">selector</span><span class="o">.</span><span class="n">best_results</span><span class="p">[</span><span class="mi">10</span><span class="p">][</span><span class="s1">'s'</span><span class="p">]</span>
<span class="n">selector</span><span class="o">.</span><span class="n">position</span><span class="p">(</span><span class="n">s</span><span class="o">=</span><span class="n">s</span><span class="p">)</span>
<span class="c1"># Get costs to remove a feature (see also \`forward_cods\` method) </span>
<span class="n">costs</span> <span class="o">=</span> <span class="n">selector</span><span class="o">.</span><span class="n">reverse_cods</span><span class="p">()[</span><span class="n">s</span><span class="p">]</span>
<span class="n">TICKERS</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">ALL_TICKERS</span><span class="p">)[</span><span class="n">selector</span><span class="o">.</span><span class="n">best_results</span><span class="p">[</span><span class="mi">10</span><span class="p">][</span><span class="s1">'s'</span><span class="p">]]</span>
<span class="c1"># Plot costs to remove each feature given current position </span>
<span class="n">fig</span><span class="p">,</span> <span class="n">ax</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">subplots</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">5</span><span class="p">))</span>
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">costs</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">xticks</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">TICKERS</span><span class="p">)),</span> <span class="n">rotation</span><span class="o">=</span><span class="mi">90</span><span class="p">)</span>
<span class="n">ax</span><span class="o">.</span><span class="n">set_xticklabels</span><span class="p">(</span><span class="n">TICKERS</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</code></pre></div>
<p><a href="./wp-content/uploads/2018/05/cost.jpg"><img alt="cost" src="./wp-content/uploads/2018/05/cost.jpg"></a></p>
<h2>Final comments</h2>
<p>In this tutorial, we’ve illustrated many of the basic <span class="caps">API</span> calls available in <code>linselect</code>. In a future tutorial post, we plan to illustrate some interesting use cases of some of these <span class="caps">API</span> calls — e.g., how to use <code>GenSelect</code><span class="quo">‘</span>s arguments to explore the value of supplemental features, added to an already existing data set.</p>
<h2>References</h2>
<p>[1] J. Landy. Stepwise regression for unsupervised learning, 2017. <a href="https://arxiv.org/abs/1706.03265">arxiv.1706.03265</a>.</p>
<script type="text/javascript">if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {
var align = "center",
indent = "0em",
linebreak = "false";
if (false) {
align = (screen.width < 768) ? "left" : align;
indent = (screen.width < 768) ? "0em" : indent;
linebreak = (screen.width < 768) ? 'true' : linebreak;
}
var mathjaxscript = document.createElement('script');
mathjaxscript.id = 'mathjaxscript_pelican_#%@#$@#';
mathjaxscript.type = 'text/javascript';
mathjaxscript.src = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/latest.js?config=TeX-AMS-MML_HTMLorMML';
var configscript = document.createElement('script');
configscript.type = 'text/x-mathjax-config';
configscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({" +
" config: ['MMLorHTML.js']," +
" TeX: { extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'], equationNumbers: { autoNumber: 'none' } }," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
" displayIndent: '"+ indent +"'," +
" showMathMenu: true," +
" messageStyle: 'normal'," +
" tex2jax: { " +
" inlineMath: [ ['\\\\(','\\\\)'] ], " +
" displayMath: [ ['$$','$$'] ]," +
" processEscapes: true," +
" preview: 'TeX'," +
" }, " +
" 'HTML-CSS': { " +
" availableFonts: ['STIX', 'TeX']," +
" preferredFont: 'STIX'," +
" styles: { '.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn': {color: 'inherit ! important'} }," +
" linebreaks: { automatic: "+ linebreak +", width: '90% container' }," +
" }, " +
"}); " +
"if ('default' !== 'default') {" +
"MathJax.Hub.Register.StartupHook('HTML-CSS Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax['HTML-CSS'].FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"MathJax.Hub.Register.StartupHook('SVG Jax Ready',function () {" +
"var VARIANT = MathJax.OutputJax.SVG.FONTDATA.VARIANT;" +
"VARIANT['normal'].fonts.unshift('MathJax_default');" +
"VARIANT['bold'].fonts.unshift('MathJax_default-bold');" +
"VARIANT['italic'].fonts.unshift('MathJax_default-italic');" +
"VARIANT['-tex-mathit'].fonts.unshift('MathJax_default-italic');" +
"});" +
"}";
(document.body || document.getElementsByTagName('head')[0]).appendChild(configscript);
(document.body || document.getElementsByTagName('head')[0]).appendChild(mathjaxscript);
}
</script>
<p id="post-share-links">
Like this post? Share on:
<a href="https://twitter.com/intent/tweet?text=linselect%20demo%3A%20a%20tech%20sector%20stock%C2%A0analysis&url=/linselect-demo&hashtags=linselect" target="_blank" rel="nofollow noopener noreferrer" title="Share on Twitter">Twitter</a>
|
<a href="https://www.facebook.com/sharer/sharer.php?u=/linselect-demo" target="_blank" rel="nofollow noopener noreferrer" title="Share on Facebook">Facebook</a>
|
<a href="mailto:?subject=linselect%20demo%3A%20a%20tech%20sector%20stock%C2%A0analysis&body=/linselect-demo" target="_blank" rel="nofollow noopener noreferrer" title="Share via Email">Email</a>
</p>
<hr />
<div class="author_blurb">
<a href="" target="_blank" rel="nofollow noopener noreferrer">
<img src=/wp-content/uploads/2014/12/JonathanLinkedIn.jpg alt="Jonathan Landy Avatar" title="Jonathan Landy">
<span class="author_name">Jonathan Landy</span>
</a>
Jonathan grew up in the midwest and then went to school at Caltech and UCLA. Following this, he did two postdocs, one at UCSB and one at UC Berkeley. His academic research focused primarily on applications of statistical mechanics, but his professional passion has always been in the mastering, development, and practical application of slick math methods/tools. He currently works as a data-scientist at Stitch Fix.
</div>
<hr/>
<aside>
<nav>
<ul class="articles-timeline">
<li class="previous-article">« <a href="./gans" title="Previous: Making AI Interpretable with Generative Adversarial Networks">Making AI Interpretable with Generative Adversarial Networks</a></li>
<li class="next-article"><a href="./unsupervised-feature-selection-in-python-with-linselect" title="Next: Linear compression in python: PCA vs unsupervised feature selection">Linear compression in python: PCA vs unsupervised feature selection</a> »</li>
</ul>
</nav>
</aside>
</div>
<section id="article-sidebar" class="span2">
<h4>Published</h4>
<time itemprop="dateCreated" datetime="2018-05-31T14:17:00-07:00">May 31, 2018</time>
<h4>Category</h4>
<a class="category-link" href="./categories.html#linselect-ref">linselect</a>
<h4>Tags</h4>
<ul class="list-of-tags tags-in-article">
<li><a href="./tags.html#linselect-ref">linselect
<span>2</span>
</a></li>
</ul>
<h4>Contact</h4>
<div id="sidebar-social-link">
<a href="https://twitter.com/efavdb" title="" target="_blank" rel="nofollow noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" aria-label="Twitter" role="img" viewBox="0 0 512 512"><rect width="512" height="512" rx="15%" fill="#1da1f3"/><path fill="#fff" d="M437 152a72 72 0 0 1-40 12 72 72 0 0 0 32-40 72 72 0 0 1-45 17 72 72 0 0 0-122 65 200 200 0 0 1-145-74 72 72 0 0 0 22 94 72 72 0 0 1-32-7 72 72 0 0 0 56 69 72 72 0 0 1-32 1 72 72 0 0 0 67 50 200 200 0 0 1-105 29 200 200 0 0 0 309-179 200 200 0 0 0 35-37"/></svg>
</a>
<a href="https://github.com/efavdb" title="" target="_blank" rel="nofollow noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" aria-label="GitHub" role="img" viewBox="0 0 512 512"><rect width="512" height="512" rx="15%" fill="#1B1817"/><path fill="#fff" d="M335 499c14 0 12 17 12 17H165s-2-17 12-17c13 0 16-6 16-12l-1-50c-71 16-86-28-86-28-12-30-28-37-28-37-24-16 1-16 1-16 26 2 40 26 40 26 22 39 59 28 74 22 2-17 9-28 16-35-57-6-116-28-116-126 0-28 10-51 26-69-3-6-11-32 3-67 0 0 21-7 70 26 42-12 86-12 128 0 49-33 70-26 70-26 14 35 6 61 3 67 16 18 26 41 26 69 0 98-60 120-117 126 10 8 18 24 18 48l-1 70c0 6 3 12 16 12z"/></svg>
</a>
<a href="https://www.youtube.com/channel/UClfvjoSiu0VvWOh5OpnuusA" title="" target="_blank" rel="nofollow noopener noreferrer">
<svg xmlns="http://www.w3.org/2000/svg" aria-label="YouTube" role="img" viewBox="0 0 512 512" fill="#ed1d24"><rect width="512" height="512" rx="15%"/><path d="m427 169c-4-15-17-27-32-31-34-9-239-10-278 0-15 4-28 16-32 31-9 38-10 135 0 174 4 15 17 27 32 31 36 10 241 10 278 0 15-4 28-16 32-31 9-36 9-137 0-174" fill="#fff"/><path d="m220 203v106l93-53"/></svg>
</a>
</div>
</section>
</div>
</article>
<button onclick="topFunction()" id="myBtn" title="Go to top">▲</button>
</div>
<div class="span1"></div>
</div>
</div>
</div>
<footer>
<div>
<span class="site-name"><a href= .>EFAVDB</span> - Everybody's Favorite Data Blog</a>
</div>
<!-- <div id="fpowered"> -->
<!-- Powered by: <a href="http://getpelican.com/" title="Pelican Home Page" target="_blank" rel="nofollow noopener noreferrer">Pelican</a> -->
<!-- Theme: <a href="https://elegant.oncrashreboot.com/" title="Theme Elegant Home Page" target="_blank" rel="nofollow noopener noreferrer">Elegant</a> -->
<!-- -->
<!-- </div> -->
</footer> <script src="//code.jquery.com/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script>
function validateForm(query)
{
return (query.length > 0);
}
</script>
<script>
//** Scroll to top button **
//Get the button:
mybutton = document.getElementById("myBtn");
// When the user scrolls down 30px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 30 || document.documentElement.scrollTop > 30) {
mybutton.style.display = "block";
} else {
mybutton.style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0; // For Safari
document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
}
</script>
<script>
(function () {
if (window.location.hash.match(/^#comment-\d+$/)) {
$('#comment_thread').collapse('show');
}
})();
window.onhashchange=function(){
if (window.location.hash.match(/^#comment-\d+$/))
window.location.reload(true);
}
$('#comment_thread').on('shown', function () {
var link = document.getElementById('comment-accordion-toggle');
var old_innerHTML = link.innerHTML;
$(link).fadeOut(200, function() {
$(this).text('Click here to hide comments').fadeIn(200);
});
$('#comment_thread').on('hidden', function () {
$(link).fadeOut(200, function() {
$(this).text(old_innerHTML).fadeIn(200);
});
})
})
</script>
</body>
<!-- Theme: Elegant built for Pelican
License : MIT -->
</html>