nirvdrum-ai4r 1.9.1
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.
- data/.gitignore +1 -0
- data/.rakeTasks +7 -0
- data/README.rdoc +56 -0
- data/Rakefile.rb +42 -0
- data/VERSION +1 -0
- data/ai4r.gemspec +221 -0
- data/change_log +49 -0
- data/examples/classifiers/id3_data.csv +121 -0
- data/examples/classifiers/id3_example.rb +29 -0
- data/examples/classifiers/naive_bayes_data.csv +11 -0
- data/examples/classifiers/naive_bayes_example.rb +16 -0
- data/examples/classifiers/results.txt +31 -0
- data/examples/genetic_algorithm/genetic_algorithm_example.rb +37 -0
- data/examples/genetic_algorithm/travel_cost.csv +16 -0
- data/examples/neural_network/backpropagation_example.rb +67 -0
- data/examples/neural_network/patterns_with_base_noise.rb +68 -0
- data/examples/neural_network/patterns_with_noise.rb +66 -0
- data/examples/neural_network/training_patterns.rb +68 -0
- data/examples/neural_network/xor_example.rb +35 -0
- data/examples/som/som_data.rb +156 -0
- data/examples/som/som_multi_node_example.rb +22 -0
- data/examples/som/som_single_example.rb +24 -0
- data/lib/ai4r.rb +32 -0
- data/lib/ai4r/classifiers/classifier.rb +59 -0
- data/lib/ai4r/classifiers/hyperpipes.rb +118 -0
- data/lib/ai4r/classifiers/id3.rb +326 -0
- data/lib/ai4r/classifiers/multilayer_perceptron.rb +135 -0
- data/lib/ai4r/classifiers/naive_bayes.rb +259 -0
- data/lib/ai4r/classifiers/one_r.rb +110 -0
- data/lib/ai4r/classifiers/prism.rb +197 -0
- data/lib/ai4r/classifiers/zero_r.rb +73 -0
- data/lib/ai4r/clusterers/average_linkage.rb +59 -0
- data/lib/ai4r/clusterers/bisecting_k_means.rb +93 -0
- data/lib/ai4r/clusterers/centroid_linkage.rb +66 -0
- data/lib/ai4r/clusterers/clusterer.rb +61 -0
- data/lib/ai4r/clusterers/complete_linkage.rb +67 -0
- data/lib/ai4r/clusterers/diana.rb +139 -0
- data/lib/ai4r/clusterers/k_means.rb +126 -0
- data/lib/ai4r/clusterers/median_linkage.rb +61 -0
- data/lib/ai4r/clusterers/single_linkage.rb +194 -0
- data/lib/ai4r/clusterers/ward_linkage.rb +64 -0
- data/lib/ai4r/clusterers/weighted_average_linkage.rb +61 -0
- data/lib/ai4r/data/data_set.rb +266 -0
- data/lib/ai4r/data/parameterizable.rb +64 -0
- data/lib/ai4r/data/proximity.rb +100 -0
- data/lib/ai4r/data/statistics.rb +77 -0
- data/lib/ai4r/experiment/classifier_evaluator.rb +95 -0
- data/lib/ai4r/genetic_algorithm/genetic_algorithm.rb +270 -0
- data/lib/ai4r/neural_network/backpropagation.rb +293 -0
- data/lib/ai4r/neural_network/hopfield.rb +149 -0
- data/lib/ai4r/som/layer.rb +68 -0
- data/lib/ai4r/som/node.rb +96 -0
- data/lib/ai4r/som/som.rb +155 -0
- data/lib/ai4r/som/two_phase_layer.rb +90 -0
- data/site/forrest.properties +152 -0
- data/site/forrest.properties.dispatcher.properties +25 -0
- data/site/forrest.properties.xml +29 -0
- data/site/src/documentation/README.txt +7 -0
- data/site/src/documentation/classes/CatalogManager.properties +62 -0
- data/site/src/documentation/content/locationmap.xml +72 -0
- data/site/src/documentation/content/xdocs/downloads.html +9 -0
- data/site/src/documentation/content/xdocs/geneticAlgorithms.xml +294 -0
- data/site/src/documentation/content/xdocs/index.xml +155 -0
- data/site/src/documentation/content/xdocs/machineLearning.xml +131 -0
- data/site/src/documentation/content/xdocs/neuralNetworks.xml +270 -0
- data/site/src/documentation/content/xdocs/site.xml +54 -0
- data/site/src/documentation/content/xdocs/sourceCode.xml +43 -0
- data/site/src/documentation/content/xdocs/tabs.xml +35 -0
- data/site/src/documentation/resources/images/ai4r-logo.png +0 -0
- data/site/src/documentation/resources/images/c.png +0 -0
- data/site/src/documentation/resources/images/c_wbn.png +0 -0
- data/site/src/documentation/resources/images/c_wn.png +0 -0
- data/site/src/documentation/resources/images/ellipse-2.svg +30 -0
- data/site/src/documentation/resources/images/ero.gif +0 -0
- data/site/src/documentation/resources/images/europe2.png +0 -0
- data/site/src/documentation/resources/images/europe3.png +0 -0
- data/site/src/documentation/resources/images/fitness.png +0 -0
- data/site/src/documentation/resources/images/genetic_algorithms_example.png +0 -0
- data/site/src/documentation/resources/images/icon-a.png +0 -0
- data/site/src/documentation/resources/images/icon-b.png +0 -0
- data/site/src/documentation/resources/images/icon.png +0 -0
- data/site/src/documentation/resources/images/jadeferret.png +0 -0
- data/site/src/documentation/resources/images/my_email.png +0 -0
- data/site/src/documentation/resources/images/neural_network_example.png +0 -0
- data/site/src/documentation/resources/images/project-logo.png +0 -0
- data/site/src/documentation/resources/images/rubyforge.png +0 -0
- data/site/src/documentation/resources/images/s.png +0 -0
- data/site/src/documentation/resources/images/s_wbn.png +0 -0
- data/site/src/documentation/resources/images/s_wn.png +0 -0
- data/site/src/documentation/resources/images/sigmoid.png +0 -0
- data/site/src/documentation/resources/images/sub-dir/icon-c.png +0 -0
- data/site/src/documentation/resources/images/t.png +0 -0
- data/site/src/documentation/resources/images/t_wbn.png +0 -0
- data/site/src/documentation/resources/images/t_wn.png +0 -0
- data/site/src/documentation/resources/schema/catalog.xcat +29 -0
- data/site/src/documentation/resources/schema/hello-v10.dtd +51 -0
- data/site/src/documentation/resources/schema/symbols-project-v10.ent +26 -0
- data/site/src/documentation/resources/stylesheets/hello2document.xsl +33 -0
- data/site/src/documentation/sitemap.xmap +66 -0
- data/site/src/documentation/skinconf.xml +418 -0
- data/site/src/documentation/translations/langcode.xml +29 -0
- data/site/src/documentation/translations/languages_de.xml +24 -0
- data/site/src/documentation/translations/languages_en.xml +24 -0
- data/site/src/documentation/translations/languages_es.xml +22 -0
- data/site/src/documentation/translations/languages_fr.xml +24 -0
- data/site/src/documentation/translations/languages_nl.xml +24 -0
- data/site/src/documentation/translations/menu.xml +33 -0
- data/site/src/documentation/translations/menu_af.xml +33 -0
- data/site/src/documentation/translations/menu_de.xml +33 -0
- data/site/src/documentation/translations/menu_es.xml +33 -0
- data/site/src/documentation/translations/menu_fr.xml +33 -0
- data/site/src/documentation/translations/menu_it.xml +33 -0
- data/site/src/documentation/translations/menu_nl.xml +33 -0
- data/site/src/documentation/translations/menu_no.xml +33 -0
- data/site/src/documentation/translations/menu_ru.xml +33 -0
- data/site/src/documentation/translations/menu_sk.xml +33 -0
- data/site/src/documentation/translations/tabs.xml +22 -0
- data/site/src/documentation/translations/tabs_de.xml +22 -0
- data/site/src/documentation/translations/tabs_es.xml +22 -0
- data/site/src/documentation/translations/tabs_fr.xml +22 -0
- data/site/src/documentation/translations/tabs_nl.xml +22 -0
- data/test/classifiers/hyperpipes_test.rb +84 -0
- data/test/classifiers/id3_test.rb +208 -0
- data/test/classifiers/multilayer_perceptron_test.rb +79 -0
- data/test/classifiers/naive_bayes_test.rb +43 -0
- data/test/classifiers/one_r_test.rb +62 -0
- data/test/classifiers/prism_test.rb +85 -0
- data/test/classifiers/zero_r_test.rb +50 -0
- data/test/clusterers/average_linkage_test.rb +51 -0
- data/test/clusterers/bisecting_k_means_test.rb +66 -0
- data/test/clusterers/centroid_linkage_test.rb +53 -0
- data/test/clusterers/complete_linkage_test.rb +57 -0
- data/test/clusterers/diana_test.rb +69 -0
- data/test/clusterers/k_means_test.rb +100 -0
- data/test/clusterers/median_linkage_test.rb +53 -0
- data/test/clusterers/single_linkage_test.rb +122 -0
- data/test/clusterers/ward_linkage_test.rb +53 -0
- data/test/clusterers/weighted_average_linkage_test.rb +53 -0
- data/test/data/data_set.csv +121 -0
- data/test/data/data_set_test.rb +96 -0
- data/test/data/proximity_test.rb +81 -0
- data/test/data/statistics_data_set.csv +5 -0
- data/test/data/statistics_test.rb +65 -0
- data/test/experiment/classifier_evaluator_test.rb +76 -0
- data/test/genetic_algorithm/chromosome_test.rb +58 -0
- data/test/genetic_algorithm/genetic_algorithm_test.rb +81 -0
- data/test/neural_network/backpropagation_test.rb +69 -0
- data/test/neural_network/hopfield_test.rb +72 -0
- data/test/som/som_test.rb +97 -0
- metadata +238 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
4
|
+
contributor license agreements. See the NOTICE file distributed with
|
|
5
|
+
this work for additional information regarding copyright ownership.
|
|
6
|
+
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
7
|
+
(the "License"); you may not use this file except in compliance with
|
|
8
|
+
the License. You may obtain a copy of the License at
|
|
9
|
+
|
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
|
|
12
|
+
Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
See the License for the specific language governing permissions and
|
|
16
|
+
limitations under the License.
|
|
17
|
+
-->
|
|
18
|
+
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
|
|
19
|
+
<document>
|
|
20
|
+
<header>
|
|
21
|
+
<title>AI4R :: Artificial Intelligence for Ruby</title>
|
|
22
|
+
</header>
|
|
23
|
+
<body>
|
|
24
|
+
<section id="Introduction">
|
|
25
|
+
<title>Introduction</title>
|
|
26
|
+
<p>
|
|
27
|
+
AI4R is a collection of ruby algorithms implementations,
|
|
28
|
+
covering several Artificial intelligence fields, and simple practical
|
|
29
|
+
examples using them. A Ruby playground for AI researchers.
|
|
30
|
+
It implements:
|
|
31
|
+
</p>
|
|
32
|
+
<ul>
|
|
33
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/GeneticAlgorithm.html">Genetic algorithms</a></li>
|
|
34
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Som.html">Self-organized maps (SOM)</a></li>
|
|
35
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/NeuralNetwork.html">Neural Networks</a>
|
|
36
|
+
<ul>
|
|
37
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/NeuralNetwork/Backpropagation.html">Multilayer perceptron with Backpropagation learning</a></li>
|
|
38
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/NeuralNetwork/Hopfield.html">Hopfield net</a></li>
|
|
39
|
+
</ul>
|
|
40
|
+
</li>
|
|
41
|
+
<li><a href="machineLearning.html">Automatic classifiers (Machine Learning)</a>
|
|
42
|
+
<ul>
|
|
43
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Classifiers/ID3.html">ID3 (Decision Trees)</a></li>
|
|
44
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Classifiers/Prism.html">PRISM (J. Cendrowska, 1987)</a></li>
|
|
45
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Classifiers/MultilayerPerceptron.html">Multilayer Perceptron</a></li>
|
|
46
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Classifiers/OneR.html">OneR (AKA One Attribute Rule, 1R)</a></li>
|
|
47
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Classifiers/ZeroR.html">ZeroR</a></li>
|
|
48
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Classifiers/Hyperpipes.html">Hyperpipes</a></li>
|
|
49
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Classifiers/NaiveBayes.html">Naive Bayes</a></li>
|
|
50
|
+
</ul>
|
|
51
|
+
</li>
|
|
52
|
+
<li><a href="http://en.wikipedia.org/wiki/Data_clustering">Data clustering</a>
|
|
53
|
+
<ul>
|
|
54
|
+
<li><a href="http://en.wikipedia.org/wiki/k_means">K-means</a></li>
|
|
55
|
+
<li><a href="http://en.wikipedia.org/wiki/k_means">Bisecting k-means</a></li>
|
|
56
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Clusterers/SingleLinkage.html">Single linkage</a></li>
|
|
57
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Clusterers/CompleteLinkage.html">Complete linkage</a></li>
|
|
58
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Clusterers/AverageLinkage.html">Average linkage</a></li>
|
|
59
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Clusterers/WeightedAverageLinkage.html">Weighted Average linkage</a></li>
|
|
60
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Clusterers/CentroidLinkage.html">Centroid linkage</a></li>
|
|
61
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Clusterers/MedianLinkage.html">Median linkage</a></li>
|
|
62
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Clusterers/WardLinkage.html">Ward's method linkage</a></li>
|
|
63
|
+
<li><a href="http://ai4r.rubyforge.org/rdoc/classes/Ai4r/Clusterers/Diana.html">Diana (Divisive Analysis)</a></li>
|
|
64
|
+
</ul>
|
|
65
|
+
</li>
|
|
66
|
+
</ul>
|
|
67
|
+
</section>
|
|
68
|
+
|
|
69
|
+
<section id="Examples_offered">
|
|
70
|
+
<title>Practical examples</title>
|
|
71
|
+
<p>
|
|
72
|
+
<strong>Genetic Algorithms</strong><br />
|
|
73
|
+
<a href="geneticAlgorithms.html">Optimization of the Travelling salesman problem (NP-hard problem)</a><br />
|
|
74
|
+
<a href="geneticAlgorithms.html">
|
|
75
|
+
<img src="images/genetic_algorithms_example.png" alt="Genetic Algorithms Example" />
|
|
76
|
+
</a>
|
|
77
|
+
</p>
|
|
78
|
+
<p>
|
|
79
|
+
<strong>Neural networks</strong><br />
|
|
80
|
+
<a href="neuralNetworks.html">Simple OCR (recognition of visual patterns)</a><br />
|
|
81
|
+
<a href="neuralNetworks.html">
|
|
82
|
+
<img src="images/neural_network_example.png" alt="Neural Network Example" />
|
|
83
|
+
</a>
|
|
84
|
+
</p>
|
|
85
|
+
<p>
|
|
86
|
+
<strong>Automatic classifiers</strong><br />
|
|
87
|
+
<a href="machineLearning.html">Automatic identification of relevant marketing targets</a>
|
|
88
|
+
</p>
|
|
89
|
+
|
|
90
|
+
</section>
|
|
91
|
+
|
|
92
|
+
<section id="howtoinstall">
|
|
93
|
+
<title>How to install</title>
|
|
94
|
+
<p>1. Install the gem:</p>
|
|
95
|
+
<source>gem install ai4r</source>
|
|
96
|
+
<p>2. Include require statements in your code:</p>
|
|
97
|
+
<source>
|
|
98
|
+
require "rubygems"
|
|
99
|
+
require "ai4r"
|
|
100
|
+
</source>
|
|
101
|
+
</section>
|
|
102
|
+
|
|
103
|
+
<section id="roadmap">
|
|
104
|
+
<title>Development Roadmap</title>
|
|
105
|
+
<p>
|
|
106
|
+
AI4R is an active project. If you are interested about what we are
|
|
107
|
+
working on, checkout the
|
|
108
|
+
<a href="http://wiki.jadeferret.com/AI4R_RoadMap" title="Ai4r Roadmap">
|
|
109
|
+
development roadmap
|
|
110
|
+
</a>
|
|
111
|
+
</p>
|
|
112
|
+
<p>Current active contributors are:</p>
|
|
113
|
+
<ul>
|
|
114
|
+
<li>Thomas Kern</li>
|
|
115
|
+
<li>Sergio Fierens</li>
|
|
116
|
+
</ul>
|
|
117
|
+
</section>
|
|
118
|
+
|
|
119
|
+
<section id="ContactMe">
|
|
120
|
+
<title>Contact</title>
|
|
121
|
+
<p>
|
|
122
|
+
If you have questions or constructive comments about this project,
|
|
123
|
+
please post them in the
|
|
124
|
+
<a href="http://forum.jadeferret.com/viewforum.php?f=3" title="Ai4r Forum">forum</a>.
|
|
125
|
+
I get an email notification when you post, and I do my best to answer as soon as possible.
|
|
126
|
+
</p>
|
|
127
|
+
<p>
|
|
128
|
+
If you do not want to make it public, send it to me:
|
|
129
|
+
Sergio Fierens, email address: <img src="images/my_email.png" alt="(sergio (dot) fierens (at) gmail (dot) com)"
|
|
130
|
+
title="Sergio Fierens contact email" />. But please, try to post them in the
|
|
131
|
+
forum. I get tons of emails and it would be great to make them
|
|
132
|
+
public to help everyone.
|
|
133
|
+
</p>
|
|
134
|
+
<p>
|
|
135
|
+
Also, there is an irc channel on Freenode (#AI4R), where developers
|
|
136
|
+
discuss the current progress.
|
|
137
|
+
</p>
|
|
138
|
+
</section>
|
|
139
|
+
|
|
140
|
+
<section id="warranty">
|
|
141
|
+
<title>Disclaimer Note</title>
|
|
142
|
+
<p>In plain English:</p>
|
|
143
|
+
<p>This project was created by Sergio Fierens, but the AI algorithms were
|
|
144
|
+
created by other people who are actually much more clever than Sergio.
|
|
145
|
+
He does his best implementing them, but he cannot warranty that these
|
|
146
|
+
implementations are accurate.</p>
|
|
147
|
+
<p>In Legalese:</p>
|
|
148
|
+
<p>
|
|
149
|
+
This software is provided "as is" and without any express or implied
|
|
150
|
+
warranties, including, without limitation, the implied warranties of
|
|
151
|
+
merchantibility and fitness for a particular purpose.
|
|
152
|
+
</p>
|
|
153
|
+
</section>
|
|
154
|
+
</body>
|
|
155
|
+
</document>
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
|
|
3
|
+
<document>
|
|
4
|
+
<header>
|
|
5
|
+
<title>Machine Learning with ID3 Decision Trees in Ruby</title>
|
|
6
|
+
</header>
|
|
7
|
+
<body>
|
|
8
|
+
<section id="mach-intro">
|
|
9
|
+
<title>Introduction to ID3 algorithm</title>
|
|
10
|
+
<p>
|
|
11
|
+
AI4R implements the ID3 algorithm (Quinlan) as one of its automatic classifiers.
|
|
12
|
+
Given a set of preclassified examples, it builds a top-down
|
|
13
|
+
induction of decision tree, biased by the information gain and
|
|
14
|
+
entropy measure.
|
|
15
|
+
</p>
|
|
16
|
+
<p>
|
|
17
|
+
The good thing about this automatic learning method is that humans learns as well.
|
|
18
|
+
Unlike other AI techniques like neural networks, classifiers can
|
|
19
|
+
generate ruby code with if / else sentences. You
|
|
20
|
+
can use this to evaluate parameters on realtime, copy paste them in a
|
|
21
|
+
code, or just read them to learn about your problem domain.
|
|
22
|
+
</p>
|
|
23
|
+
</section>
|
|
24
|
+
|
|
25
|
+
<section id="mach-HowTo">
|
|
26
|
+
<title>Marketing target strategy example using ID3 Decision Trees in Ruby</title>
|
|
27
|
+
<p>Let's suppose that you are writting an application that must identify people as relevant marketing targets or not.
|
|
28
|
+
The only information that you have is a collection of examples, provided by a marketing survey:</p>
|
|
29
|
+
<source>
|
|
30
|
+
<![CDATA[
|
|
31
|
+
DATA_LABELS = [ 'city', 'age_range', 'gender', 'marketing_target' ]
|
|
32
|
+
|
|
33
|
+
DATA_SET = [
|
|
34
|
+
['New York', '<30', 'M', 'Y'],
|
|
35
|
+
['Chicago', '<30', 'M', 'Y'],
|
|
36
|
+
['Chicago', '<30', 'F', 'Y'],
|
|
37
|
+
['New York', '<30', 'M', 'Y'],
|
|
38
|
+
['New York', '<30', 'M', 'Y'],
|
|
39
|
+
['Chicago', '[30-50)', 'M', 'Y'],
|
|
40
|
+
['New York', '[30-50)', 'F', 'N'],
|
|
41
|
+
['Chicago', '[30-50)', 'F', 'Y'],
|
|
42
|
+
['New York', '[30-50)', 'F', 'N'],
|
|
43
|
+
['Chicago', '[50-80]', 'M', 'N'],
|
|
44
|
+
['New York', '[50-80]', 'F', 'N'],
|
|
45
|
+
['New York', '[50-80]', 'M', 'N'],
|
|
46
|
+
['Chicago', '[50-80]', 'M', 'N'],
|
|
47
|
+
['New York', '[50-80]', 'F', 'N'],
|
|
48
|
+
['Chicago', '>80', 'F', 'Y']
|
|
49
|
+
]
|
|
50
|
+
]]>
|
|
51
|
+
</source>
|
|
52
|
+
<p>You can create an ID3 Decision tree to do the dirty job for you:</p>
|
|
53
|
+
<source>
|
|
54
|
+
<![CDATA[
|
|
55
|
+
id3 = ID3.new(DATA_SET, DATA_LABELS)
|
|
56
|
+
]]>
|
|
57
|
+
</source>
|
|
58
|
+
<p>The Decision tree will automatically create the "rules" to parse new data,
|
|
59
|
+
and identify new posible marketing targets:</p>
|
|
60
|
+
<source>
|
|
61
|
+
<![CDATA[
|
|
62
|
+
id3.get_rules
|
|
63
|
+
# => if age_range=='<30' then marketing_target='Y'
|
|
64
|
+
elsif age_range=='[30-50)' and city=='Chicago' then marketing_target='Y'
|
|
65
|
+
elsif age_range=='[30-50)' and city=='New York' then marketing_target='N'
|
|
66
|
+
elsif age_range=='[50-80]' then marketing_target='N'
|
|
67
|
+
elsif age_range=='>80' then marketing_target='Y'
|
|
68
|
+
else raise 'There was not enough information during training to do a proper induction for this data element' end
|
|
69
|
+
|
|
70
|
+
id3.eval(['New York', '<30', 'M'])
|
|
71
|
+
# => 'Y'
|
|
72
|
+
]]>
|
|
73
|
+
</source>
|
|
74
|
+
</section>
|
|
75
|
+
|
|
76
|
+
<section id="mach-dataload">
|
|
77
|
+
<title>Better data loading</title>
|
|
78
|
+
<p>
|
|
79
|
+
In real life you will use many more data training examples,
|
|
80
|
+
with more attributes.
|
|
81
|
+
Consider moving your data to an external CSV (comma separate values) file.
|
|
82
|
+
</p>
|
|
83
|
+
<source>
|
|
84
|
+
<![CDATA[
|
|
85
|
+
data_set = []
|
|
86
|
+
CSV::Reader.parse(File.open("#{File.dirname(__FILE__)}/data_set.csv", 'r')) do |row|
|
|
87
|
+
data_set << row
|
|
88
|
+
end
|
|
89
|
+
data_labels = data_set.shift
|
|
90
|
+
|
|
91
|
+
id3 = ID3.new(data_set, data_labels)
|
|
92
|
+
]]></source>
|
|
93
|
+
|
|
94
|
+
</section>
|
|
95
|
+
|
|
96
|
+
<section id="mach-eval">
|
|
97
|
+
<title>A good tip for data evaluation</title>
|
|
98
|
+
<p>
|
|
99
|
+
The ID3 class provides a method to evaluate new data.
|
|
100
|
+
</p>
|
|
101
|
+
<source>
|
|
102
|
+
<![CDATA[
|
|
103
|
+
id3.eval(['New York', '<30', 'M'])
|
|
104
|
+
# => 'Y'
|
|
105
|
+
]]></source>
|
|
106
|
+
<p>
|
|
107
|
+
But instead of going through the tree every time, you can take advantage of the
|
|
108
|
+
fact that the method "get_rules" generates proper ruby code!
|
|
109
|
+
</p>
|
|
110
|
+
<source>
|
|
111
|
+
<![CDATA[
|
|
112
|
+
id3 = ID3.new(DATA_SET, DATA_LABELS)
|
|
113
|
+
age_range = '<30'
|
|
114
|
+
city = 'New York'
|
|
115
|
+
gender = 'M'
|
|
116
|
+
marketing_target = nil
|
|
117
|
+
eval id3.get_rules
|
|
118
|
+
puts marketing_target
|
|
119
|
+
# => 'Y'
|
|
120
|
+
]]></source>
|
|
121
|
+
</section>
|
|
122
|
+
|
|
123
|
+
<section id="mach-more">
|
|
124
|
+
<title>More about ID3 and decision trees</title>
|
|
125
|
+
<p>
|
|
126
|
+
<a href="http://en.wikipedia.org/wiki/Decision_tree">Wikipedia article on Decision trees</a>
|
|
127
|
+
<a href="http://en.wikipedia.org/wiki/ID3_algorithm">Wikipedia article on ID3 Algorithm</a>
|
|
128
|
+
</p>
|
|
129
|
+
</section>
|
|
130
|
+
</body>
|
|
131
|
+
</document>
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
4
|
+
contributor license agreements. See the NOTICE file distributed with
|
|
5
|
+
this work for additional information regarding copyright ownership.
|
|
6
|
+
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
7
|
+
(the "License"); you may not use this file except in compliance with
|
|
8
|
+
the License. You may obtain a copy of the License at
|
|
9
|
+
|
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
|
|
12
|
+
Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
See the License for the specific language governing permissions and
|
|
16
|
+
limitations under the License.
|
|
17
|
+
|
|
18
|
+
-->
|
|
19
|
+
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
|
|
20
|
+
<document>
|
|
21
|
+
<header>
|
|
22
|
+
<title>OCR example using Backpropagation networks in ruby :: ai4r</title>
|
|
23
|
+
</header>
|
|
24
|
+
<body>
|
|
25
|
+
<section id="nn-Introduction">
|
|
26
|
+
<title>Introduction to Neural Networks</title>
|
|
27
|
+
<p>
|
|
28
|
+
The utility of artificial neural network models lies in the fact
|
|
29
|
+
that they can be used to infer a function from observations. This is
|
|
30
|
+
particularly useful in applications where the complexity of the data
|
|
31
|
+
or task makes the design of such a function by hand impractical.
|
|
32
|
+
Neural Networks are being used in many businesses and applications.
|
|
33
|
+
Their ability to learn by example makes them attractive in environments
|
|
34
|
+
where the business rules are either not well defined or are hard to
|
|
35
|
+
enumerate and define. Many people believe that Neural Networks can
|
|
36
|
+
only solve toy problems. Give them a try, and let you decide if they
|
|
37
|
+
are good enough to solve your needs.
|
|
38
|
+
</p>
|
|
39
|
+
<p>
|
|
40
|
+
In this module you will find an implementation of neural networks
|
|
41
|
+
using the Backpropagation is a supervised learning technique
|
|
42
|
+
(described by Paul Werbos in 1974, and further developed by David E.
|
|
43
|
+
Rumelhart, Geoffrey E. Hinton and Ronald J. Williams in 1986)
|
|
44
|
+
</p>
|
|
45
|
+
</section>
|
|
46
|
+
<section id="nn-example">
|
|
47
|
+
<title>Modeling the OCR problem using Neural Networks networks</title>
|
|
48
|
+
<p>
|
|
49
|
+
Let's imagine that we have to implement a program to identify simple patterns
|
|
50
|
+
(triangles, squares, crosses, etc). The main problem is that this program must
|
|
51
|
+
be resistant to random noise in the image (pixels with wrong values) and
|
|
52
|
+
line noise (similar to the unwanted direct current that we usually have in a
|
|
53
|
+
signal).
|
|
54
|
+
</p>
|
|
55
|
+
<p>
|
|
56
|
+
In order to solve this problem, we can take an example of each pattern
|
|
57
|
+
to be recognized, and train a neural network to identify similar patterns.
|
|
58
|
+
In fact, one of the most popular uses of neural networks in business
|
|
59
|
+
applications is OCR (opticar character recognition)
|
|
60
|
+
</p>
|
|
61
|
+
<p>
|
|
62
|
+
In our porposed solotion, we create a network with the following
|
|
63
|
+
architecture: 256 input neurons and 3 output neurons. We feed this network
|
|
64
|
+
with 16x16 matrices (in fact will convert them to vectors of length 256).
|
|
65
|
+
Each pixel is represented with a number from 0 (white pixel) to 10
|
|
66
|
+
(black pixel). The output of this network if a 3 vector of dimension 3,
|
|
67
|
+
where ideally:
|
|
68
|
+
</p>
|
|
69
|
+
<ul>
|
|
70
|
+
<li>(1, 0, 0) for triangles</li>
|
|
71
|
+
<li>(0, 1, 0) for squares</li>
|
|
72
|
+
<li>(0, 0, 1) for crosses</li>
|
|
73
|
+
</ul>
|
|
74
|
+
<p>We train our backpropagation neural network using the following examples:</p>
|
|
75
|
+
<table>
|
|
76
|
+
<caption>Training patterns</caption>
|
|
77
|
+
<tr>
|
|
78
|
+
<td><img alt="Triangule training example" src="/images/t.png" /></td>
|
|
79
|
+
<td><img alt="Square training example" src="/images/s.png" /></td>
|
|
80
|
+
<td><img alt="Cross training example" src="/images/c.png" /></td>
|
|
81
|
+
</tr>
|
|
82
|
+
</table>
|
|
83
|
+
</section>
|
|
84
|
+
<section id="nn2-example">
|
|
85
|
+
<title>Implementing a basic OCR application using ruby and AI4R</title>
|
|
86
|
+
<p>The code bellow shows the basic steps to use Backpropagation Neural
|
|
87
|
+
Networks in AI4R:</p>
|
|
88
|
+
<source>
|
|
89
|
+
<![CDATA[
|
|
90
|
+
# Create the network with:
|
|
91
|
+
# 4 inputs
|
|
92
|
+
# 1 hidden layer with 3 neurons
|
|
93
|
+
# 2 outputs
|
|
94
|
+
net = Ai4r::NeuralNetwork::Backpropagation.new([4, 3, 2])
|
|
95
|
+
|
|
96
|
+
# Train the network
|
|
97
|
+
100.times do |i|
|
|
98
|
+
net.train(example[i], result[i])
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Use it: Evaluate data with the trained network
|
|
102
|
+
net.eval([12, 48, 12, 25]) # => [0.89, 0.04]
|
|
103
|
+
]]>
|
|
104
|
+
</source>
|
|
105
|
+
<p>This is the source code used to elaborate this simple OCR application
|
|
106
|
+
(You can find it inside the AI4R zip file release):</p>
|
|
107
|
+
<source>
|
|
108
|
+
<![CDATA[
|
|
109
|
+
require "rubygems"
|
|
110
|
+
require "ai4r"
|
|
111
|
+
require File.dirname(__FILE__) + '/training_patterns'
|
|
112
|
+
require File.dirname(__FILE__) + '/patterns_with_noise'
|
|
113
|
+
require File.dirname(__FILE__) + '/patterns_with_base_noise'
|
|
114
|
+
|
|
115
|
+
# Create a network with 256 inputs, and 3 outputs
|
|
116
|
+
net = Ai4r::NeuralNetwork::Backpropagation.new([256, 3])
|
|
117
|
+
|
|
118
|
+
# Load training data
|
|
119
|
+
tr_input = TRIANGLE.flatten.collect { |input| input.to_f / 10}
|
|
120
|
+
sq_input = SQUARE.flatten.collect { |input| input.to_f / 10}
|
|
121
|
+
cr_input = CROSS.flatten.collect { |input| input.to_f / 10}
|
|
122
|
+
# Train the network
|
|
123
|
+
puts "Training the network, please wait."
|
|
124
|
+
100.times do
|
|
125
|
+
net.train(tr_input, [1,0,0])
|
|
126
|
+
net.train(sq_input, [0,1,0])
|
|
127
|
+
net.train(cr_input, [0,0,1])
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Load test data with noise
|
|
131
|
+
tr_with_noise = TRIANGLE_WITH_NOISE.flatten.collect { |input| input.to_f / 10}
|
|
132
|
+
sq_with_noise = SQUARE_WITH_NOISE.flatten.collect { |input| input.to_f / 10}
|
|
133
|
+
cr_with_noise = CROSS_WITH_NOISE.flatten.collect { |input| input.to_f / 10}
|
|
134
|
+
|
|
135
|
+
tr_with_base_noise = TRIANGLE_WITH_BASE_NOISE.flatten.collect { |input| input.to_f / 10}
|
|
136
|
+
sq_with_base_noise = SQUARE_WITH_BASE_NOISE.flatten.collect { |input| input.to_f / 10}
|
|
137
|
+
cr_with_base_noise = CROSS_WITH_BASE_NOISE.flatten.collect { |input| input.to_f / 10}
|
|
138
|
+
|
|
139
|
+
# Print the evaluation results
|
|
140
|
+
|
|
141
|
+
def result_label(result)
|
|
142
|
+
if result[0] > result[1] && result[0] > result[2]
|
|
143
|
+
"TRIANGLE"
|
|
144
|
+
elsif result[1] > result[2]
|
|
145
|
+
"SQUARE"
|
|
146
|
+
else
|
|
147
|
+
"CROSS"
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
puts "Training Examples"
|
|
152
|
+
puts "#{net.eval(tr_input).inspect} => #{result_label(net.eval(tr_input))}"
|
|
153
|
+
puts "#{net.eval(sq_input).inspect} => #{result_label(net.eval(sq_input))}"
|
|
154
|
+
puts "#{net.eval(cr_input).inspect} => #{result_label(net.eval(cr_input))}"
|
|
155
|
+
puts "Examples with noise"
|
|
156
|
+
puts "#{net.eval(tr_with_noise).inspect} => #{result_label(net.eval(tr_with_noise))}"
|
|
157
|
+
puts "#{net.eval(sq_with_noise).inspect} => #{result_label(net.eval(sq_with_noise))}"
|
|
158
|
+
puts "#{net.eval(cr_with_noise).inspect} => #{result_label(net.eval(cr_with_noise))}"
|
|
159
|
+
puts "Examples with base noise"
|
|
160
|
+
puts "#{net.eval(tr_with_base_noise).inspect} => #{result_label(net.eval(tr_with_base_noise))}"
|
|
161
|
+
puts "#{net.eval(sq_with_base_noise).inspect} => #{result_label(net.eval(sq_with_base_noise))}"
|
|
162
|
+
puts "#{net.eval(cr_with_base_noise).inspect} => #{result_label(net.eval(cr_with_base_noise))}"
|
|
163
|
+
]]>
|
|
164
|
+
</source>
|
|
165
|
+
</section>
|
|
166
|
+
<section id="nn3-example">
|
|
167
|
+
<title>Results obtained with the AI4R OCR algorithm</title>
|
|
168
|
+
<p>
|
|
169
|
+
The results we got when we evaluate patterns with our trained network are:
|
|
170
|
+
</p>
|
|
171
|
+
<ul>
|
|
172
|
+
<li>Evaluating the training patterns with the trained network:
|
|
173
|
+
<ol>
|
|
174
|
+
<li> <img alt="Triangule training example" src="/images/t.png" />
|
|
175
|
+
[0.98, 0.03, 0.01] => TRIANGLE </li>
|
|
176
|
+
<li> <img alt="Square training example" src="/images/s.png" />
|
|
177
|
+
[0.00, 0.96, 0.03] => SQUARE </li>
|
|
178
|
+
<li> <img alt="Cross training example" src="/images/c.png" />
|
|
179
|
+
[0.00, 0.00, 0.99] => CROSS </li>
|
|
180
|
+
</ol>
|
|
181
|
+
</li>
|
|
182
|
+
<li>Evaluating the patterns with random noise with the trained network:
|
|
183
|
+
<ol>
|
|
184
|
+
<li> <img alt="Triangule pattern with random noise" src="/images/t_wn.png" /> [0.98, 0.01, 0.01] => TRIANGLE </li>
|
|
185
|
+
<li> <img alt="Square pattern with random noise" src="/images/s_wn.png" /> [0.00, 0.96, 0.02] => SQUARE </li>
|
|
186
|
+
<li> <img alt="Cross pattern with random noise" src="/images/c_wn.png" /> [0.00, 0.00, 0.98] => CROSS </li>
|
|
187
|
+
</ol>
|
|
188
|
+
</li>
|
|
189
|
+
<li>Evaluating the patterns with line noise with the trained network:
|
|
190
|
+
<ol>
|
|
191
|
+
<li> <img alt="Triangule pattern with line noise" src="/images/t_wbn.png" /> [0.62, 0.00, 0.02] => TRIANGLE </li>
|
|
192
|
+
<li> <img alt="Square pattern with line noise" src="/images/s_wbn.png" /> [0.00, 0.75, 0.01] => SQUARE </li>
|
|
193
|
+
<li> <img alt="Cross pattern with line noise" src="/images/c_wbn.png" /> [0.00, 0.00, 0.98] => CROSS </li>
|
|
194
|
+
</ol>
|
|
195
|
+
</li>
|
|
196
|
+
</ul>
|
|
197
|
+
<p>These results are satisfactory. The network could sucessfully identify
|
|
198
|
+
the patterns despite the noise introduced to them.</p>
|
|
199
|
+
</section>
|
|
200
|
+
|
|
201
|
+
<section id="nn-custom">
|
|
202
|
+
<title>Customizing your neural network in ai4r</title>
|
|
203
|
+
<p>Sometime for a given problem, you will have to "play around" with some parameters to
|
|
204
|
+
get to a solution. This parameters are:</p>
|
|
205
|
+
|
|
206
|
+
<p>
|
|
207
|
+
<strong>Learning Rate</strong>: a real number, usually between 0.05
|
|
208
|
+
and 0.25.
|
|
209
|
+
</p>
|
|
210
|
+
<p>
|
|
211
|
+
<strong>Momentum</strong>: A momentum will avoid oscillations during
|
|
212
|
+
learning, converging to a solution in less iterations.
|
|
213
|
+
</p>
|
|
214
|
+
<p><strong>Propagation function</strong>: By default, f(x) = 1/(1 + e^(-x)).
|
|
215
|
+
This function is called
|
|
216
|
+
<a href="http://en.wikipedia.org/wiki/Sigmoid_function" title="wikipedia article on Sigmoid function">
|
|
217
|
+
Sigmoid function
|
|
218
|
+
</a>. You can see it like a "smoothed" version of the
|
|
219
|
+
<a href="http://en.wikipedia.org/wiki/Heaviside_step_function" title="Heaviside step function wikipedia article">
|
|
220
|
+
Heaviside step function
|
|
221
|
+
</a>. It will always provide a
|
|
222
|
+
value between 0 and 1. </p>
|
|
223
|
+
<p><img src="images/sigmoid.png" alt="Sigmoid function" /></p>
|
|
224
|
+
<p>
|
|
225
|
+
Sometimes you will have better results with f(x) = tanh(x), or even with
|
|
226
|
+
f(x) = x. If you modify the propagation function, you have to supply the
|
|
227
|
+
derivative function too (in terms of the propagation function result).
|
|
228
|
+
</p>
|
|
229
|
+
<p>To customize these parameters in AI4R, you can user the "set_parameters"
|
|
230
|
+
method:</p>
|
|
231
|
+
<source><![CDATA[
|
|
232
|
+
net.set_parameters(
|
|
233
|
+
:momentum => 0.15,
|
|
234
|
+
:learning_rate => 0.5,
|
|
235
|
+
:propagation_function => lambda { |x| Math.tanh(x) },
|
|
236
|
+
:derivative_propagation_function => lambda { |y| 1.0 - y**2 }
|
|
237
|
+
)
|
|
238
|
+
]]></source>
|
|
239
|
+
<p>You can also use the attribute accesors:</p>
|
|
240
|
+
<source><![CDATA[
|
|
241
|
+
net.momentum = 0.15
|
|
242
|
+
net.learning_rate = 0.5
|
|
243
|
+
net.propagation_function = lambda { |x| Math.tanh(x) }
|
|
244
|
+
net.derivative_propagation_function = lambda { |y| 1.0 - y**2 }
|
|
245
|
+
]]></source>
|
|
246
|
+
</section>
|
|
247
|
+
<note>Remember to set the custom parameters BEFORE training the network</note>
|
|
248
|
+
<section id="nn-more">
|
|
249
|
+
<title>More about Neural Networks and Backpropagation</title>
|
|
250
|
+
|
|
251
|
+
<ul>
|
|
252
|
+
<li>
|
|
253
|
+
<a href="http://en.wikipedia.org/wiki/Artificial_neural_network">Wikipedia article on Artificial Neural Networks</a>
|
|
254
|
+
</li>
|
|
255
|
+
<li>
|
|
256
|
+
<a href="http://en.wikipedia.org/wiki/Backpropagation">Wikipedia article on Backpropagation Algorithm</a>
|
|
257
|
+
</li>
|
|
258
|
+
<li>
|
|
259
|
+
<a href="http://www.tek271.com/articles/neuralNet/IntoToNeuralNets.html">Neural Networks - An Introduction by Abdul Habra</a>
|
|
260
|
+
</li>
|
|
261
|
+
<li>
|
|
262
|
+
<a href="http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html">A graphical explanation of the
|
|
263
|
+
backpropagation algorithm by Mariusz Bernacki and Przemysław Włodarczyk</a>
|
|
264
|
+
</li>
|
|
265
|
+
</ul>
|
|
266
|
+
|
|
267
|
+
</section>
|
|
268
|
+
|
|
269
|
+
</body>
|
|
270
|
+
</document>
|