ai-nlp 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c966d762ba275e10544c946f454d9dad7334edb6
4
+ data.tar.gz: 10cab1a81834a14716bb4c187b14af1ec54c27f5
5
+ SHA512:
6
+ metadata.gz: a6ec561914777c59f0e8d44ed4ade7cde89ff409ba1bae3efca1816161fbb01ee82bf102ed4a4c0530eb500ba8737c07f00ae6752862b58f21586e68fa0b00b5
7
+ data.tar.gz: cf2080d53cae13af26a85d9b9bd6961f1ce703d749f2d5ede844bed9adc363bfd60b582d5f3309e514a6309c98c0b4ccb1bae05eea663780d8213681e30c4da8
@@ -0,0 +1,20 @@
1
+ Copyright 2017 Alain ANDRE
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,114 @@
1
+ [![pipeline status](https://gitlab.com/al1_andre/ai-nlp/badges/master/build.svg)](https://gitlab.com/al1_andre/ai-nlp/commits/master)
2
+ [![Coverage report](https://gitlab.com/al1_andre/ai-nlp/badges/master/coverage.svg?job=rspec)](http://al1_andre.gitlab.io/ai-nlp)
3
+ [![Gem Version](https://badge.fury.io/rb/ai-nlp.svg)](https://badge.fury.io/rb/ai-nlp)
4
+
5
+ # Objet
6
+ J'entends de plus en plus parler de l'**intelligence artificielle** et des avancées sidérantes des **GAFA** et autres **NATU** dans ce domaine et ça m’intéresse beaucoup. Je souhaite en **apprendre** plus mais si l'Internet est plein d'informations, il faut tout de même savoir la chercher. Il y a de nombreux articles en **Anglais**, peu en **Français** et les concepts ne sont pas simple de prime abord. Je souhaite donc apporter ma pierre à l'édifice en **partageant** ce que j'apprends. C'est un projet à but non lucratif, ouvert à tous sous licence MIT dont le seul but est l'**apprentissage** par l'**expérience**. Le répertoire d'exercices se trouve [ici](exercices/)
7
+
8
+ # Description
9
+ > On regroupe habituellement sous le terme d'intelligence artificielle un ensemble de notions s'inspirant de la cognition humaine ou du cerveau biologique, et destiné s à assister ou suppléer l'individu dans le traitement des informations massives.
10
+
11
+ En janvier **2017**, le **secrétaire d’État chargé de l'Industrie, du Numérique et de l'Innovation** et le **secrétaire d’État chargé de l'Enseignement supérieur et de la Recherche** ont lancé la démarche **#franceIA** qui avait pour objectif d'étudier les opportunités de l'**IA**. Cette étude se structure autour de **trois piliers** qui ont été déclinés en **dix thèmes** clés et traités par dix **groupes de travail** et sept sous-groupes. Leur rapport de synthèse est disponible [ici](https://www.economie.gouv.fr/files/files/PDF/2017/Rapport_synthese_France_IA_.pdf).
12
+
13
+ L'intelligence artificielle traite les sujets suivants :
14
+ - La résolution des problèmes
15
+ - La [représentation des connaissances](https://fr.wikipedia.org/wiki/Repr%C3%A9sentation_des_connaissances)
16
+ - L'[organisation](https://fr.wikipedia.org/wiki/Planification_(intelligence_artificielle))
17
+ - L'[apprentissage](https://fr.wikipedia.org/wiki/Apprentissage_automatique)
18
+ - La [compréhension du langage humain (NLP/TALN)](https://fr.wikipedia.org/wiki/Traitement_automatique_du_langage_naturel)
19
+ - La[perception machine](https://fr.wikipedia.org/wiki/Machine_perception)
20
+ - La [robotique](https://fr.wikipedia.org/wiki/Robotique)
21
+ - L'[information affective](https://fr.wikipedia.org/wiki/Informatique_affective)
22
+ - La [créativité](https://en.wikipedia.org/wiki/Computational_creativity)
23
+ - La [conscience de soi](https://fr.wikipedia.org/wiki/Intelligence_artificielle#Intelligence_artificielle_forte)
24
+
25
+ ## Pourquoi un tutoriel en français ?
26
+ Il ne faut pas se **mentir**, la langue **universelle** de la **technique** est bel et bien l'**anglais** aujourd'hui. Mon code est en anglais ainsi que ses commentaires. C'est une **obligation** si l'on veut pouvoir **partager** avec le plus grand monde possible ; étant un grand défenseur de l'**open-source**, le partage du code est ce qui le rend plus fort, plus **sûr**.
27
+
28
+ Si les **Français** se trouvent assez **bien représentés** en ce qui touche à l'**I**ntelligence **A**rtificielle comme le dit le rapport du gouvernement, les **articles** en Français sur Internet sont vieux, vide de sens des fois, trop **compliqués** souvent ; mais surtout **jamais sexy** ! L'IA semble, pour le commun des mortels, **intouchable**, **stratosphérique** et même considéré à surtout éviter ! Hors il y a un **enjeu** national de taille. Nous avons **raté** le passage à l'**Internet** parce que nous pensions être les **maitres du monde** avec notre **minitel** ; il s'agit là de ne pas loupé la marche !
29
+
30
+ Si les **infrastructures** françaises sont à la ramasse (quasi **inaccessibles**), nos **ingénieurs** se **vendent** bien ; mais pas chez nous ! Si nous étudions l'IA, en parlons ; si nous écrivons des articles dessus, c'est en **anglais** ! Hors dans les enjeux de l'IA, on compte l'**économie**, la **santé**, l'**industrie** qui ont des dimensions **humaines** fortes ; si on **alimente** les IA avec seulement des **données** et des **concepts** en **anglais**, on peut oublier le mode de **pensée à la française** qui pourtant historiquement a une bonne réputation.
31
+
32
+ Et l'IA va rapidement **devenir** un outil d'**aide** à la prise de décision dans les **entreprises** et dans la **société**. C'est **déjà** le cas pour vos **recherches** sur Internet, vos **itinéraires** en voitures, la gestion de **vos données** sur les **clouds** etc. Lorsque **vous** répondez à un captcha afin de savoir si vous êtes bien un **humain**, vous pensez vraiment que **Google** ne vous **utilise** pas pour **former** une IA ? Si **Skynet** vous dit quelque chose, je vous laisse comprendre l'**importance** d'une **indépendance** de l'IA ou tout du moins d'une IA **alliée** (française ou européenne).
33
+
34
+ # Mon idée
35
+ Comme le soulève le **rapport de synthèse de France IA** de 2017, la France **manque** cruellement de **tutoriels** et de cours abordables en ce qui concerne l'IA ; mon **idée** est d'en **créer** un qui soit **reproduisible**, **accessible**, **ludique** et **agréable**.
36
+
37
+ Si j'ai appris une chose au fil de mes années d’**expériences** de développeur, c'est qu'il ne faut pas **réinventer** la roue ! Si on a une idée, quelqu'un dans le monde l'a très probablement **déjà eu**, et il vaut mieux **réutiliser** son travail. La **difficulté** est de le trouver et d'en avoir les **droits**. Par exemple, **Facebook** met à disposition des outils pour jouer avec son IA [wit](https://wit.ai/) qui permet, entre autre, de créer des chat-bot mais l'**IA** et ses **données** se trouve **chez eux**. Autrement dit, pendant que **vous entrainez** votre bot, vous entrainez surtout **le leur**. Il n'y a à ma connaissance que l'[OpenIA](https://openai.com/) d'[Elon Musk](https://fr.wikipedia.org/wiki/Elon_Musk) qui se veut universelle et pour l'**humanité** plus que pour l'entreprise et le **profit**. Si le profit est bon, il ne doit être qu'un **résultat** et non un **objectif** !
38
+
39
+ Je pense donc me baser sur des **concepts**, rechercher du code les gérants plus ou moins et tenter de recréer une IA **disponible** pour **tous** (disponible sous la gem [ai-nlp](https://rubygems.org/gems/ai-nlp)).
40
+
41
+ Je dois faire un choix sur le type d'IA que je souhaite créer. Je suis un **littéraire**, et la plupart des cours et informations que je trouve sur l'IA sont basés sur des **mathématiques** ; alors j'ai décidé d'accer mon IA sur les éléments suivants :
42
+
43
+ - L'[apprentissage](https://fr.wikipedia.org/wiki/Apprentissage_automatique)
44
+ - La [compréhension du langage humain (NLP/TALN)](https://fr.wikipedia.org/wiki/Traitement_automatique_du_langage_naturel)
45
+
46
+ Cette IA doit donc **apprendre** à **comprendre** un **texte humain**. Une interface web doit **afficher** de manière **graphique** la somme de **connaissances** qu'elle acquière, contenir une zone permettant à l'humain de **communiquer** avec l'IA et une zone dans laquelle elle **répond**.
47
+
48
+ # Technologies et concepts
49
+ Au tout début, mon IA ne **comprendra** rien à rien ! Il va falloir mettre en place un système d'**apprentissage** !
50
+
51
+ Mais qu'est-ce que l'apprentissage ? Il s'agit d'**analyser**, du **regrouper**, de **stocker** l'information afin de pouvoir l'**exploiter**.
52
+
53
+ ## L'Analyse
54
+ > L’analyse sémantique représente l’ensemble des procédés visant à analyser le sens des mots et des phrases, elle est le plus souvent utilisée comme préambule au traitement automatique des langues.
55
+
56
+ Si je veux que l'IA comprenne le langage humain, je dois tout d'abord trouver comment réaliser les actions suivantes :
57
+ - Déterminer la langue (cf [N-gramme](https://fr.wikipedia.org/wiki/N-gramme))
58
+ - Déterminer la [syntaxe](https://fr.wikipedia.org/wiki/Analyse_syntaxique)
59
+ - Découper les éléments de la phrase [entités lexicales](https://fr.wikipedia.org/wiki/Analyse_lexicale) (ou tokens en anglais)
60
+
61
+ ### Le langage informatique
62
+ Je suis un grand fan de [Ruby](https://www.ruby-lang.org/fr/), c'est un langage dont la philosophie est basée sur le [paradigme objet](https://fr.wikipedia.org/wiki/Smalltalk) ; il est donc réflexif et dynamiquement typé. je pense qu'il est capable d'apporter des avantages à mon projet grâce à sa [réflexivité](https://fr.wikipedia.org/wiki/R%C3%A9flexion_(informatique)) ; c'est à dire qu'un programme Ruby est capable d'examiner, et éventuellement modifier, ses propres structures internes de haut niveau lors de son exécution !
63
+
64
+ Il y a, à mon avis, une belle opportunité à **exploiter** pour tout ce qui concerne les [lemmes](https://fr.wikipedia.org/wiki/Lemme_(linguistique)).
65
+
66
+ ## Le Regroupement
67
+ > Le clustering : Il s'agit, pour un logiciel, de diviser un groupe hétérogène de données, en sous-groupes de manière que les données considérées comme les plus similaires soient associées au sein d'un groupe homogène et qu'au contraire les données considérées comme différentes se retrouvent dans d'autres groupes distincts ; l'objectif étant de permettre une extraction de connaissance organisée à partir de ces données.
68
+
69
+ Une fois mes éléments de phrase correctement **identifiés**, je dois réussir à les **regrouper**. Il est possible de les regrouper par sens (homonymes, synonymes, racines, préfixes, suffixes, lemmes) par type (nom, verbe, adjectif, etc.)
70
+
71
+ Ce regroupement est donc **crucial**, c'est lui qui va me permettre de **stocker** au bon **endroit** mes données. Je dois être capable de faire ces regroupements de façon **non supervisés** dans certains cas et **supervisé** dans d'autres.
72
+
73
+ ### Non supervisés
74
+ Je peux donc automatiquement regrouper, classifier des éléments que j'ai découpé à l'aide de ma base de données. Mais si par exemple aucune donnée ne me permet de faire un regroupement non supervisé, je dois interagir avec l'utilisateur ; je dois lui demander de m'aider à classer cet élément.
75
+
76
+ ### Supervisés
77
+ L'IA doit être en mesure d’interagir avec l'utilisateur et de lui demander de l'aide pour classifier les éléments qu'il aura découpé.
78
+
79
+ L'utilisateur doit permettre de préciser :
80
+ - le type
81
+ - le sens
82
+ - l'origine (lemme)
83
+
84
+ ## Le stockage
85
+ Le stockage doit permettre une récupération des données qui permette une bonne exploitation de ces dernières.
86
+
87
+ ## L'exploitation
88
+ Tout ceci est magnifique, mais si l'IA arrive maintenant à **découper** et faire des **regroupements** d'information, il lui faut pourvoir les **exploiter**. L'avantage d'un **moteur de recherche** comme **QWANT** ou **Google**, par exemple, c'est qu'il sait que sa seule **action** est de **fournir des données** qu'il a collecté et regroupé à la **demande** ; il n'a pas vraiment besoin de **comprendre** ce qu'il stocke.
89
+
90
+ Une IA plus évoluée comme **SIRI** par contre, est censée **répondre** à diverses **actions** comme **ajouter** un évènements à l'agenda, **donner** le temps qu'il fera **demain** ou encore **trouver** le **chemin** d'un magasin **proche** de notre position. Il faut donc qu'il **comprenne** le **type de demande** qui est faite.
91
+
92
+ # Références
93
+ - [Rapport France-IA](https://www.economie.gouv.fr/France-IA-intelligence-artificielle#L%27IA)
94
+
95
+ ## Deep Learning
96
+ - [wiki](https://fr.wikipedia.org/wiki/Apprentissage_profond)
97
+ - [Le monde](http://www.lemonde.fr/pixels/article/2015/07/24/comment-le-deep-learning-revolutionne-l-intelligence-artificielle_4695929_4408996.html)
98
+ - [ruby introduction](https://speakerdeck.com/geoffreylitt/deep-learning-an-introduction-for-ruby-developers)
99
+
100
+ ## NLP
101
+ - [TAL](http://blog.onyme.com/traitement-automatique-des-langues-tal-intelligence-artificielle-ia-analyse-semantique-et-clusterings/)
102
+ - [Lemmatisation](http://blog.onyme.com/lemmatisation-et-racinisation-en-francais-flexion-lemme-et-racine-dun-mot/)
103
+ - [wiki](https://en.wikipedia.org/wiki/Natural_language_processing)
104
+ - [Structure de la phrase en Français](http://la-conjugaison.nouvelobs.com/regles/grammaire/les-structures-de-phrases-167.php)
105
+ - [lemmatizer](https://github.com/yohasebe/lemmatizer)
106
+
107
+ ## Programmes/API
108
+ - [Facebook wit](https://wit.ai/)
109
+ - [Deeptext](https://humanoides.fr/deeptext-la-nouvelle-intelligence-artificielle-de-facebook-pour-decortiquer-la-semantique/)
110
+
111
+ ## Ruby
112
+ - [AI4R](https://github.com/SergioFierens/ai4r/)
113
+ - [rubynlp](http://rubynlp.org/)
114
+
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ begin
4
+ require "bundler/setup"
5
+ rescue LoadError
6
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
7
+ end
8
+
9
+ require "rdoc/task"
10
+
11
+ RDoc::Task.new(:rdoc) do |rdoc|
12
+ rdoc.rdoc_dir = "rdoc"
13
+ rdoc.title = "Ai::Nlp"
14
+ rdoc.options << "--line-numbers"
15
+ rdoc.rdoc_files.include("README.md")
16
+ rdoc.rdoc_files.include("lib/**/*.rb")
17
+ end
18
+
19
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
20
+ load "rails/tasks/engine.rake"
21
+
22
+
23
+ load "rails/tasks/statistics.rake"
24
+
25
+
26
+
27
+ require "bundler/gem_tasks"
28
+
29
+ require "rake/testtask"
30
+
31
+ Rake::TestTask.new(:test) do |t|
32
+ t.libs << "test"
33
+ t.pattern = "test/**/*_test.rb"
34
+ t.verbose = false
35
+ end
36
+
37
+
38
+ task default: :test
@@ -0,0 +1,2 @@
1
+ //= link_directory ../javascripts/ai/nlp .js
2
+ //= link_directory ../stylesheets/ai/nlp .css
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module containing artificial intelligence tools
4
+ module Ai
5
+ # Module containing automatic natural language processing tools
6
+ module Nlp
7
+ # Main controller
8
+ class ApplicationController < ActionController::Base
9
+ protect_from_forgery with: :exception
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module containing artificial intelligence tools
4
+ module Ai
5
+ # Module containing automatic natural language processing tools
6
+ module Nlp
7
+ # Main Helper
8
+ module ApplicationHelper
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module containing artificial intelligence tools
4
+ module Ai
5
+ # Module containing automatic natural language processing tools
6
+ module Nlp
7
+ # Main Job
8
+ class ApplicationJob < ActiveJob::Base
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module containing artificial intelligence tools
4
+ module Ai
5
+ # Module containing automatic natural language processing tools
6
+ module Nlp
7
+ # Main mailer
8
+ class ApplicationMailer < ActionMailer::Base
9
+ default from: "from@example.com"
10
+ layout "mailer"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module containing artificial intelligence tools
4
+ module Ai
5
+ # Module containing automatic natural language processing tools
6
+ module Nlp
7
+ # Classe mère
8
+ class ApplicationRecord < ActiveRecord::Base
9
+ self.abstract_class = true
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module containing artificial intelligence tools
4
+ module Ai
5
+ # Module containing automatic natural language processing tools
6
+ module Nlp
7
+ # Manages a language
8
+ class Language < ApplicationRecord
9
+ validates_presence_of :name
10
+ serialize :map, Hash
11
+
12
+ ##
13
+ # Add n-grams to the language
14
+ # @param array given_array The array of [gram, frequancy]
15
+ def add_grams(given_array)
16
+ given_array.to_h.each do |key, freq|
17
+ map[key] = map[key] ? letters + freq : freq
18
+ end
19
+ update
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Ia taln</title>
5
+ <%= stylesheet_link_tag "ai/nlp/application", media: "all" %>
6
+ <%= javascript_include_tag "ai/nlp/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ai::Nlp::Engine.routes.draw do
4
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateIaTalnLanguages < ActiveRecord::Migration[5.1]
4
+ def change
5
+ create_table :ai_nlp_languages do |t|
6
+ t.string :name
7
+ t.text :map
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ai/nlp/engine"
4
+ require "ai/nlp/n_gram/n_gram"
5
+ require "ai/nlp/languages"
6
+
7
+ # Module containing artificial intelligence tools
8
+ module Ai
9
+ # Module containing automatic natural language processing tools
10
+ module Nlp
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Module containing artificial intelligence tools
4
+ module Ai
5
+ # Module containing automatic natural language processing tools
6
+ module Nlp
7
+ # Engine and isolation namespace
8
+ class Engine < ::Rails::Engine
9
+ isolate_namespace Ai::Nlp
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,95 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "ai/nlp/n_gram/n_gram"
5
+
6
+ # Module containing artificial intelligence tools
7
+ module Ai
8
+ # Module containing automatic natural language processing tools
9
+ module Nlp
10
+ # Class to handle multiple languages
11
+ class Languages
12
+ ##
13
+ # Initialisation
14
+ def initialize
15
+ @n_gram = NGram.new
16
+ end
17
+
18
+ ##
19
+ # Returns the currently known languages
20
+ # @return An array of Language
21
+ def all
22
+ @languages = Language.all
23
+ end
24
+
25
+ ##
26
+ # Offers among the available languages the closest one to the datasets
27
+ # @param string input The data set.
28
+ def guess(input)
29
+ all
30
+ return [] if @languages.empty?
31
+ hash = @languages.map { |language| [language, score(input, language)] }.to_h
32
+ sort(hash)
33
+ end
34
+
35
+ ##
36
+ # Create a new language.
37
+ # @param string name The language name.
38
+ # @param string input The initial data set.
39
+ # @return La langue créée.
40
+ def create_one(name, input)
41
+ language = Language.new(name: name)
42
+ language.update(map: @n_gram.calculate(input).to_h)
43
+ end
44
+
45
+ private
46
+
47
+ ##
48
+ # Sort the language hash
49
+ # @param hash hash The language hash
50
+ # @return the sorted list of languages
51
+ def sort(hash)
52
+ sorted_languages = @languages.sort_by { |language| hash[language] }
53
+ reject(sorted_languages, hash)
54
+ end
55
+
56
+ def reject(sorted_languages, hash)
57
+ sorted_languages.reject { |language| hash[language].zero? }
58
+ end
59
+
60
+ ##
61
+ # Compare a string of characters against a language based on, at most,
62
+ # the 400 most commonly used groups of letters.
63
+ # @param string input The data set to compare
64
+ # @param Language language The Language to compare to
65
+ def score(input, language)
66
+ input_gram = @n_gram.calculate(input)
67
+ ngram = language.map
68
+ calculate_point([input_gram.size, 400].min, ngram, input_gram)
69
+ end
70
+
71
+ ##
72
+ # Calculates the new frequency
73
+ # @return le score (point)
74
+ def calculate_point(max_compare, ngram, input_gram)
75
+ point = 0
76
+ (0..max_compare).each do |pos|
77
+ position = input_gram[pos]
78
+ next unless position
79
+ point = add_frequency(ngram[position[0]], pos, point)
80
+ end
81
+ point
82
+ end
83
+
84
+ ##
85
+ # Add frequency if needed
86
+ # @param integer input_gram_freq The input gram frequency
87
+ # @param integer pos The position in the max_compare
88
+ # @param integer point The current calculated points
89
+ def add_frequency(input_gram_freq, pos, point)
90
+ point += (input_gram_freq - pos).abs if input_gram_freq
91
+ point
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,118 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "sanitize"
5
+ require "cgi"
6
+ require "unicode"
7
+ require "byebug"
8
+
9
+ # Module containing artificial intelligence tools
10
+ module Ai
11
+ # Module containing automatic natural language processing tools
12
+ module Nlp
13
+ # Class managing an n-gram hash
14
+ class Hasher
15
+ ##
16
+ # Initialisation
17
+ # @param string input The string to treat
18
+ def initialize(input)
19
+ @input = input
20
+ @hash = {}
21
+ clean
22
+ end
23
+
24
+ ##
25
+ # Calculates n-gram frequencies for the dataset
26
+ # @return Frequencies of ngram or sorted array
27
+ def calculate
28
+ @input.split(/[\d\s\[\]]/).each do |word|
29
+ calculate_word_gram("_#{word}_")
30
+ end
31
+ drop_unwanted_keys
32
+ @hash.sort { |one, other| other[1] <=> one[1] }
33
+ end
34
+
35
+ private
36
+
37
+ ##
38
+ # Enriched hash representing the n-gram of a word
39
+ # @param string word The word to calculate
40
+ def calculate_word_gram(word)
41
+ length = word.size
42
+ (0..length).each do |letter_position|
43
+ parameters = { letter_position: letter_position, word: word, length: length }
44
+ calculate_letter_gram(parameters)
45
+ length -= 1
46
+ end
47
+ end
48
+
49
+ ##
50
+ # Deletes a key if its value is less than or equal to zero
51
+ def drop_unwanted_keys
52
+ @hash.each_key do |key|
53
+ @hash.delete(key) if key.size <= 0
54
+ end
55
+ end
56
+
57
+ ##
58
+ # Stores the mono-gram, bi-gram and tri-gram in the hash
59
+ # @param hash parameters The list of necessary parameters :
60
+ # - letter_position The position of the letter to be processed
61
+ # - word The word treated
62
+ # - length Current word size
63
+ def calculate_letter_gram(parameters)
64
+ (1..3).each do |nth|
65
+ letters = parameters[:word][parameters[:letter_position], nth]
66
+ next unless letters
67
+ init_key(letters)
68
+ @hash[letters] += 1 if parameters[:length] > (nth - 1)
69
+ end
70
+ end
71
+
72
+ ##
73
+ # Initialize key if necessary
74
+ # @param string letters The group of letters
75
+ def init_key(letters)
76
+ @hash[letters] ||= 0
77
+ end
78
+
79
+ ##
80
+ # Cleans the string passed as argument
81
+ def clean
82
+ safe_clean
83
+ specific_clean
84
+ clean_latin
85
+ @input = @input.strip.split(" ").join(" ")
86
+ end
87
+
88
+ ##
89
+ # Cleans the string from Latin characters if more than half of the string is not Latin.
90
+ def clean_latin
91
+ latin = @input.scan(/[a-z]/)
92
+ nonlatin = @input.scan(/[\p{L}&&[^a-z]]/)
93
+ nonlatin_ratio = nonlatin.size / (latin.size * 1.0)
94
+ return if nonlatin_ratio < 0.5
95
+ @input.gsub!(/[a-zA-Z]/, "") if !latin.empty? && !nonlatin.empty?
96
+ end
97
+
98
+ ##
99
+ # Removes polluting web addresses, mails and characters
100
+ def specific_clean
101
+ uri_regex = %r/(?:http|https):\/\/[a-z0-9]+(?:[\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(?:(?::[0-9]{1,5})?\/[^\s]*)?/
102
+ @input.gsub!(uri_regex, "")
103
+ # Remove mails
104
+ @input.gsub!(/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}/, "")
105
+ # Repleace polluting non-alphabetical characters, punctuation included by a space
106
+ @input.gsub!(%r/[\*\^><!\"#\$%&\'\(\)\*\+:;,\._\/=\?@\{\}\[\]|\-\n\r0-9]/, " ")
107
+ end
108
+
109
+ ##
110
+ # Cleaning via existing tools
111
+ def safe_clean
112
+ @input = Sanitize.clean(@input)
113
+ @input = CGI.unescapeHTML(@input)
114
+ @input = Unicode.downcase(@input)
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require "ai/nlp/n_gram/hasher"
5
+
6
+ # Module containing artificial intelligence tools
7
+ module Ai
8
+ # Module containing automatic natural language processing tools
9
+ module Nlp
10
+ # Class for calculating n-grams, storing and exploiting them
11
+ class NGram
12
+ ##
13
+ # Cuts the data set into a grouping of letters
14
+ # @param string input The dataset
15
+ def hash(input)
16
+ calculate(input).map { |letters, _gram| letters }
17
+ end
18
+
19
+ ##
20
+ # Calculates the n-gram frequencies for the data set passed as an argument
21
+ # @param string input The dataset
22
+ # @return Frequencies of ngram or sorted array
23
+ def calculate(input)
24
+ hash = Hasher.new(input)
25
+ hash.calculate
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,178 @@
1
+ The stemming algorithm
2
+
3
+ In French the verb endings **ent** and **ons** cannot be removed without unacceptable overstemming.
4
+
5
+ The **ons** form is rarer, but **ent** forms are quite common, and will appear regularly throughout a stemmed vocabulary.
6
+
7
+ Letters in French include the following accented forms,
8
+
9
+ â à ç ë é ê è ï î ô û ù
10
+
11
+ The following letters are vowels:
12
+
13
+ a e i o u y â à ë é ê è ï î ô û ù
14
+
15
+ Assume the word is in lower case. Then put into upper case u or i preceded and followed by a vowel, and y preceded or followed by a vowel. u after q is also put into upper case. For example,
16
+
17
+ jouer -> joUer
18
+ ennuie -> ennuIe
19
+ yeux -> Yeux
20
+ quand -> qUand
21
+
22
+ (The upper case forms are not then classed as vowels — see note on vowel marking.)
23
+
24
+ If the word begins with two vowels, RV is the region after the third letter, otherwise the region after the first vowel not at the beginning of the word, or the end of the word if these positions cannot be found. (Exceptionally, par, col or tap, at the begining of a word is also taken to define RV as the region to their right.)
25
+
26
+ For example,
27
+
28
+ a i m e r a d o r e r v o l e r t a p i s
29
+ |...| |.....| |.....| |...|
30
+
31
+ R1 is the region after the first non-vowel following a vowel, or the end of the word if there is no such non-vowel. R2 is the region after the first non-vowel following a vowel in R1, or the end of the word if there is no such non-vowel. (See note on R1 and R2.)
32
+
33
+ For example:
34
+
35
+ f a m e u s e m e n t
36
+ |......R1.......|
37
+ |...R2....|
38
+
39
+ Note that R1 can contain RV (adorer), and RV can contain R1 (voler).
40
+
41
+ Below, ‘delete if in R2’ means that a found suffix should be removed if it lies entirely in R2, but not if it overlaps R2 and the rest of the word. ‘delete if in R1 and preceded by X’ means that X itself does not have to come in R1, while ‘delete if preceded by X in R1’ means that X, like the suffix, must be entirely in R1.
42
+
43
+ Start with step 1
44
+
45
+ Step 1: Standard suffix removal
46
+
47
+ Search for the longest among the following suffixes, and perform the action indicated.
48
+
49
+ ance iqUe isme able iste eux ances iqUes ismes ables istes
50
+ delete if in R2
51
+
52
+ atrice ateur ation atrices ateurs ations
53
+ delete if in R2
54
+ if preceded by ic, delete if in R2, else replace by iqU
55
+
56
+ logie logies
57
+ replace with log if in R2
58
+
59
+ usion ution usions utions
60
+ replace with u if in R2
61
+
62
+ ence ences
63
+ replace with ent if in R2
64
+
65
+ ement ements
66
+ delete if in RV
67
+ if preceded by iv, delete if in R2 (and if further preceded by at, delete if in R2), otherwise,
68
+ if preceded by eus, delete if in R2, else replace by eux if in R1, otherwise,
69
+ if preceded by abl or iqU, delete if in R2, otherwise,
70
+ if preceded by ièr or Ièr, replace by i if in RV
71
+
72
+ ité ités
73
+ delete if in R2
74
+ if preceded by abil, delete if in R2, else replace by abl, otherwise,
75
+ if preceded by ic, delete if in R2, else replace by iqU, otherwise,
76
+ if preceded by iv, delete if in R2
77
+
78
+ if ive ifs ives
79
+ delete if in R2
80
+ if preceded by at, delete if in R2 (and if further preceded by ic, delete if in R2, else replace by iqU)
81
+
82
+ eaux
83
+ replace with eau
84
+
85
+ aux
86
+ replace with al if in R1
87
+
88
+ euse euses
89
+ delete if in R2, else replace by eux if in R1
90
+
91
+ issement issements
92
+ delete if in R1 and preceded by a non-vowel
93
+
94
+ amment
95
+ replace with ant if in RV
96
+
97
+ emment
98
+ replace with ent if in RV
99
+
100
+ ment ments
101
+ delete if preceded by a vowel in RV
102
+
103
+ In steps 2a and 2b all tests are confined to the RV region.
104
+
105
+ Do step 2a if either no ending was removed by step 1, or if one of endings amment, emment, ment, ments was found.
106
+
107
+ Step 2a: Verb suffixes beginning i
108
+
109
+ Search for the longest among the following suffixes and if found, delete if preceded by a non-vowel.
110
+
111
+ îmes ît îtes i ie ies ir ira irai iraIent irais irait iras irent irez iriez irions irons iront is issaIent issais issait issant issante issantes issants isse issent isses issez issiez issions issons it
112
+
113
+
114
+ (Note that the non-vowel itself must also be in RV.)
115
+
116
+ Do step 2b if step 2a was done, but failed to remove a suffix.
117
+
118
+ Step 2b: Other verb suffixes
119
+
120
+ Search for the longest among the following suffixes, and perform the action indicated.
121
+
122
+ ions
123
+ delete if in R2
124
+
125
+ é ée ées és èrent er era erai eraIent erais erait eras erez eriez erions erons eront ez iez
126
+ delete
127
+
128
+ âmes ât âtes a ai aIent ais ait ant ante antes ants as asse assent asses assiez assions
129
+ delete
130
+ if preceded by e, delete
131
+
132
+
133
+ (Note that the e that may be deleted in this last step must also be in RV.)
134
+
135
+ If the last step to be obeyed — either step 1, 2a or 2b — altered the word, do step 3
136
+
137
+ Step 3
138
+
139
+ Replace final Y with i or final ç with c
140
+
141
+ Alternatively, if the last step to be obeyed did not alter the word, do step 4
142
+
143
+ Step 4: Residual suffix
144
+
145
+ If the word ends s, not preceded by a, i, o, u, è or s, delete it.
146
+
147
+ In the rest of step 4, all tests are confined to the RV region.
148
+
149
+ Search for the longest among the following suffixes, and perform the action indicated.
150
+
151
+ ion
152
+ delete if in R2 and preceded by s or t
153
+
154
+ ier ière Ier Ière
155
+ replace with i
156
+
157
+ e
158
+ delete
159
+
160
+ ë
161
+ if preceded by gu, delete
162
+
163
+
164
+ (So note that ion is removed only when it is in R2 — as well as being in RV — and preceded by s or t which must be in RV.)
165
+
166
+ Always do steps 5 and 6.
167
+
168
+ Step 5: Undouble
169
+
170
+ If the word ends enn, onn, ett, ell or eill, delete the last letter
171
+
172
+ Step 6: Un-accent
173
+
174
+ If the words ends é or è followed by at least one non-vowel, remove the accent from the e.
175
+
176
+ And finally:
177
+
178
+ Turn any remaining I, U and Y letters in the word back into lower case.
File without changes
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ai
4
+ module Nlp
5
+ VERSION = "0.1.0".freeze
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ # desc "Explaining what the task does"
3
+ # task :ai_nlp do
4
+ # # Task goes here
5
+ # end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ai-nlp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alain ANDRE
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.1.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.1.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: sanitize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: unicode
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.4.4.4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.4.4.4
55
+ description: |2
56
+ This gem contains a grouping of ruby tools related to Artificial Intelligence
57
+ and Automatic Natural Language Processing
58
+ email:
59
+ - dev@alain-andre.fr
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - MIT-LICENSE
65
+ - README.md
66
+ - Rakefile
67
+ - app/assets/config/ai_nlp_manifest.js
68
+ - app/assets/javascripts/ai/nlp/application.js
69
+ - app/assets/stylesheets/ai/nlp/application.css
70
+ - app/controllers/ai/nlp/application_controller.rb
71
+ - app/helpers/ai/nlp/application_helper.rb
72
+ - app/jobs/ai/nlp/application_job.rb
73
+ - app/mailers/ai/nlp/application_mailer.rb
74
+ - app/models/ai/nlp/application_record.rb
75
+ - app/models/ai/nlp/language.rb
76
+ - app/views/layouts/ai/nlp/application.html.erb
77
+ - config/routes.rb
78
+ - db/migrate/20170907142959_create_ia_taln_languages.rb
79
+ - lib/ai/nlp.rb
80
+ - lib/ai/nlp/engine.rb
81
+ - lib/ai/nlp/languages.rb
82
+ - lib/ai/nlp/n_gram/hasher.rb
83
+ - lib/ai/nlp/n_gram/n_gram.rb
84
+ - lib/ai/nlp/stem/fr.md
85
+ - lib/ai/nlp/stem/stem.rb
86
+ - lib/ai/nlp/version.rb
87
+ - lib/tasks/ai/nlp_tasks.rake
88
+ homepage: https://gitlab.com/al1_andre/ai-nlp
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '2.3'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.5.1
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Artificial Intelligence and Automatic Natural Language Processing
112
+ test_files: []