svm_helper 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/.versions.conf +4 -0
- data/.yardopts +3 -0
- data/Gemfile +24 -0
- data/Guardfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +41 -0
- data/Rakefile +7 -0
- data/lib/svm_helper.rb +8 -0
- data/lib/svm_helper/feature_vector.rb +17 -0
- data/lib/svm_helper/interface_helper.rb +57 -0
- data/lib/svm_helper/preprocessed_data.rb +17 -0
- data/lib/svm_helper/preprocessors.rb +2 -0
- data/lib/svm_helper/preprocessors/simple.rb +111 -0
- data/lib/svm_helper/preprocessors/with_industry_map.rb +40 -0
- data/lib/svm_helper/selectors.rb +3 -0
- data/lib/svm_helper/selectors/n_gram.rb +31 -0
- data/lib/svm_helper/selectors/simple.rb +163 -0
- data/lib/svm_helper/selectors/with_binary_encoding.rb +42 -0
- data/lib/svm_helper/stopwords/de +127 -0
- data/lib/svm_helper/stopwords/en +119 -0
- data/lib/svm_helper/version.rb +3 -0
- data/spec/factories.rb +35 -0
- data/spec/factories/jobs/tmp.html +42 -0
- data/spec/factories/jobs/tmp2.html +20 -0
- data/spec/factories/jobs/tmp3.html +34 -0
- data/spec/factories/jobs_with_description.rb +20 -0
- data/spec/factories/jobs_with_title.rb +72 -0
- data/spec/preprocessors/simple_spec.rb +138 -0
- data/spec/preprocessors/with_industry_map_spec.rb +16 -0
- data/spec/selectors/n_gram_spec.rb +21 -0
- data/spec/selectors/simple_spec.rb +121 -0
- data/spec/selectors/with_binary_encoding_spec.rb +39 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/preprocessor_spec.rb +21 -0
- data/spec/support/selector_spec.rb +21 -0
- data/svm_helper.gemspec +21 -0
- metadata +112 -0
data/spec/factories.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'factory_girl'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
FactoryGirl.define do
|
5
|
+
factory :qc_job_check, class: OpenStruct do
|
6
|
+
wrong_industry_id nil
|
7
|
+
wrong_function_id 4
|
8
|
+
wrong_career_level nil
|
9
|
+
end
|
10
|
+
factory :job, class: OpenStruct do
|
11
|
+
title "Meh"
|
12
|
+
description "Foo Bar"
|
13
|
+
summary "Really lot of work to do"
|
14
|
+
qc_job_check
|
15
|
+
end
|
16
|
+
|
17
|
+
factory :job_without_job_check, class: OpenStruct do
|
18
|
+
title "Meh"
|
19
|
+
description "Foo Bar"
|
20
|
+
summary "Really lot of work to do"
|
21
|
+
original_industry_id 1423
|
22
|
+
end
|
23
|
+
|
24
|
+
factory :data, class: PreprocessedData do
|
25
|
+
data ["haus fooo garten baaz pferd fooo"]
|
26
|
+
ids {{function: 3, industry: 43, career_level: 7}}
|
27
|
+
labels {{function: true, industry: false, career_level: true}}
|
28
|
+
end
|
29
|
+
factory :data_w_short_words, parent: :data do
|
30
|
+
data ["auto foo pferd bz gooo fooo 2"]
|
31
|
+
end
|
32
|
+
factory :data_w_multiple_sections, parent: :data do
|
33
|
+
data ["meeh foo auto","bz baaz fooo 2"]
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<p><strong><strong>Unternehmen</strong></strong></p>
|
2
|
+
<p>Unser Auftraggeber ist ein technologieführender Hersteller Präzisionswerkzeugen und Werkzeugsystemen in Süddeutschland. Das Unternehmen verfügt über weltweit über Produktionsstätten, sowie zahlreiche Vertriebs- und Servicegesellschaften, wo sich bedeutende Standorte einschlägiger Industrien konzentrieren oder neu etablieren. Im Rahmen der strategischen Weiterentwicklung des Unternehmens suchen wir führungserfahrenen und unternehmerisch geprägten Global Account Manager/Koordinator m/w (ID:3154).</p>
|
3
|
+
<p> </p>
|
4
|
+
<p> </p>
|
5
|
+
<p><strong>Aufgaben</strong></p>
|
6
|
+
<ul>
|
7
|
+
<li>Koordination der weltweiten Vertriebsaktivitäten gemeinsam mit der Vertriebsleitung.</li>
|
8
|
+
<li>Ansprechpartner für Großkunden Kunden wie Continental, BMW sowie Entwicklungspartnern</li>
|
9
|
+
<li>Koordination und Optimierung kundenspezifischer Prozesse von der Produktion bis zur Auslieferung</li>
|
10
|
+
<li>Unterstützung der weltweiten Vertriebsgesellschaften</li>
|
11
|
+
<li>Einführung und Umsetzung eines globalen Preissystems unter Berücksichtigung kundenspezifischer Gegebenheiten</li>
|
12
|
+
<li>Unterstützung bei der strategischen Planung und Ausrichtung des Vertriebs</li>
|
13
|
+
<li>Sie unterstützen und gestalten die Schnittstellenfunktion zwischen unseren Kunden, des Vertriebs sowie der Produktion</li>
|
14
|
+
</ul>
|
15
|
+
<p> </p>
|
16
|
+
<p><strong>Anforderungen</strong></p>
|
17
|
+
<ul>
|
18
|
+
<li>Ausbildung als Dipl.-Wirtschafts.- Ing. (FH) oder vergleichbare Ausbildung oder Erfahrung</li>
|
19
|
+
<li>Sie konnten mindestens eine dreijährige Erfahrung in der Metallverarbeitung sammeln</li>
|
20
|
+
<li>Sie sind vertriebsorientiert, idealerweise haben sie sogar bereit in der Automobilindustrie bzw. in der Metallverarbeitung interessante Vertriebserfahrung gesammelt.</li>
|
21
|
+
<li>Verantwortungsbewusstsein, kundenorientiertes Auftreten, Einfühlungsvermögen, Begeisterungsfähigkeit und Überzeugungskraft</li>
|
22
|
+
<li>Interesse sich in komplexen Projekten auf nationaler oder internationaler Ebene einzuarbeiten</li>
|
23
|
+
<li>Flexibilität und Mobilität</li>
|
24
|
+
<li>Gute Englischkenntnisse</li>
|
25
|
+
</ul>
|
26
|
+
<p> </p>
|
27
|
+
<p><strong>Kontakt</strong></p>
|
28
|
+
<p>Wir bieten Ihnen einen sicheren Arbeitsplatz mit Aufstiegsmöglichkeiten an strategisch verantwortungsvoller Stelle innerhalb eines profitabel wachsenden, international tätigen Unternehmens. Sie erwartet ein attraktives, der Verantwortung der Position angemessenes Leistungspaket mit einem Firmenwagen</p>
|
29
|
+
<p> </p>
|
30
|
+
<p><strong>Sie können sich direkt über unsere Webeseite bewerben unter:</strong></p>
|
31
|
+
<p><strong>http://fimad.avature.net/stellenangebote#ViewJob/263. (Bitte den Link in den Browser einfach kopieren und einfügen)!</strong></p>
|
32
|
+
<p> </p>
|
33
|
+
<p>Alternativ können Sie uns Ihre Unterlagen an <a href="mailto:bewerbung@fimad.de">bewerbung@fimad.de</a> zusenden.</p>
|
34
|
+
<p><strong>Für Ihre Rückfragen steht Ihnen unser Berater Herr Miroslav Krampl unter der Telefonnummer 06404-2052240 oder 0160-905 612 64 zur Verfügung.</strong></p>
|
35
|
+
<p> </p>
|
36
|
+
<p> </p>
|
37
|
+
<p><strong>FIMAD GmbH Personal Deutschland</strong></p>
|
38
|
+
<p>Executive Search</p>
|
39
|
+
<p>Neuwiesenweg 1b</p>
|
40
|
+
<p>D-35423 LICH - Germany</p>
|
41
|
+
<p>Internet: www.fimad-personal.de</p>
|
42
|
+
<p></p>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<p>Sie haben fundierte Berufserfahrung im Bereich Drug Safety / Pharmacovigilance? Sie haben bereits erste Führungserfahrung gesammelt? Sie möchten gerne in einem Dienstleistungsunternehmen der pharmazeutischen Industrie arbeiten? Dann bewerben Sie sich noch heute! Für unseren Kunden suchen wir einen Abteilungsleiter Drug Safety (m/w). Ihre Aufgaben:</p>
|
2
|
+
<ul>
|
3
|
+
<li>Verantwortung für die Abteilungs- und Arbeitsorganisation, die Projektzuteilung und die Aufgabenzuordnung in Ihrem Team</li>
|
4
|
+
<li>Steuern und Überwachen der Projekte der Abteilung</li>
|
5
|
+
<li>Festlegen der SOPs Ihrer Abteilung</li>
|
6
|
+
<li>Leiten und Führen Ihrer Mitarbeiter und deren Weiterentwicklung</li>
|
7
|
+
<li>Repräsentieren Ihrer Firma und Abteilung vor externen Behörden, Kunden und Verbänden</li>
|
8
|
+
<li>Akquirieren neuer Kunden</li>
|
9
|
+
<li>Sie sind verantwortlich für die Machbarkeit, Planung und Abwicklung von Projekten gemeinsam mit dem Head of PV</li>
|
10
|
+
<li>Sie sind der Stellvertreter des Abteilungsleiters PV</li>
|
11
|
+
</ul>
|
12
|
+
<ul>
|
13
|
+
<li>Studienabschluss in Medizin, Pharmazie oder Naturwissenschaften, idealerweise mit Promotion</li>
|
14
|
+
<li>Profunde Berufserfahrung im Bereich Pharmacovigilance</li>
|
15
|
+
<li>Umfassendes Wissen aus medizinischer, pharmazeutischer und klinischer Praxis sowie detailliertes Wissen hinsichtlich der zugehörigen SOPs (global und lokal) und der entsprechenden Gesetze</li>
|
16
|
+
<li>Idealerweise Erfahrung in der Führung von Mitarbeitern</li>
|
17
|
+
<li>Sicheres persönliches Auftreten</li>
|
18
|
+
<li>Sehr gute Sprachkenntnisse in Deutsch und Englisch (Wort und Schrift)</li>
|
19
|
+
</ul>
|
20
|
+
<p>Bei Interesse an weiterführenden Informationen wenden Sie sich bitte an:<br />Patrick Brehm<br />T: + 49 621 1788 1607<br />E: patrick.brehm@hays.de</p>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<p>Für unseren Kunden, ein renommiertes IT Beratungsunternehmen, suchen wir einen</p>
|
2
|
+
<p> </p>
|
3
|
+
<p> </p>
|
4
|
+
<p><strong><strong>Oracle Consultant</strong></strong></p>
|
5
|
+
<p> </p>
|
6
|
+
<p><span style="text-decoration: underline;">Ihre Aufgaben: </span></p>
|
7
|
+
<p> </p>
|
8
|
+
<p>· Verantwortung für die Konzeption, das Design und die Implementierung von Oracle Lösungen in unterschiedlichen Projekten</p>
|
9
|
+
<p> </p>
|
10
|
+
<p>· Mithilfe bei Migrationsprojekten, Performance Analysen und Monitoring Themen</p>
|
11
|
+
<p> </p>
|
12
|
+
<p>· Definition von hochverfügbaren DB-Umgebungen</p>
|
13
|
+
<p> </p>
|
14
|
+
<p>· klassische Administrationsaufgaben (Backup, Recovery, Setup, etc.)</p>
|
15
|
+
<p> </p>
|
16
|
+
<p> </p>
|
17
|
+
<p> </p>
|
18
|
+
<p> <span style="text-decoration: underline;">Ihr Profil:</span></p>
|
19
|
+
<p> </p>
|
20
|
+
<p>· erfolgreich abgeschlossenes Informatik Studium und mehrjährige praktische Erfahrung im Oracle Umfeld</p>
|
21
|
+
<p> </p>
|
22
|
+
<p>· sehr gutes Know-How in der Oracle Administration</p>
|
23
|
+
<p> </p>
|
24
|
+
<p>· Erfahrung in der Entwicklung von Scripten</p>
|
25
|
+
<p> </p>
|
26
|
+
<p>· gute Kenntnisse in der Konzeption und dem Design von Oracle Lösungen</p>
|
27
|
+
<p> </p>
|
28
|
+
<p>· stilsichere Deutschkenntnisse werden vorausgesetzt</p>
|
29
|
+
<p> </p>
|
30
|
+
<p>· kommunikative, selbständige und serviceorientierte Persönlichkeit</p>
|
31
|
+
<p> </p>
|
32
|
+
<p>· Reisebereitschaft innerhalb der Schweiz</p>
|
33
|
+
<p> </p>
|
34
|
+
<p> Es erwartet Sie eine abwechslungsreiche, verantwortungsvolle Position in einem dynamischen und hochprofessionellen Umfeld.</p>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# jobs with description
|
3
|
+
FactoryGirl.define do
|
4
|
+
factory :job_description_w_adress, parent: :job do
|
5
|
+
description IO.read('spec/factories/jobs/tmp.html')
|
6
|
+
end
|
7
|
+
factory :job_description_w_tags, parent: :job do
|
8
|
+
description IO.read('spec/factories/jobs/tmp2.html')
|
9
|
+
end
|
10
|
+
factory :job_description_w_special, parent: :job do
|
11
|
+
description IO.read('spec/factories/jobs/tmp3.html')
|
12
|
+
end
|
13
|
+
|
14
|
+
factory :job_description_w_code_token, parent: :job do
|
15
|
+
description IO.read('spec/factories/jobs/tmp.html')
|
16
|
+
end
|
17
|
+
factory :job_description_w_gender, parent: :job do
|
18
|
+
description IO.read('spec/factories/jobs/tmp.html')
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# job with title
|
3
|
+
FactoryGirl.define do
|
4
|
+
factory :job_title_w_gender, parent: :job do
|
5
|
+
title "Berater m/w Citrix"
|
6
|
+
clean_title "berater citrix"
|
7
|
+
end
|
8
|
+
factory :job_title_w_gender_brackets, parent: :job do
|
9
|
+
title "SAP BW Senior Consultant (w/m)"
|
10
|
+
clean_title "sap bw senior consultant"
|
11
|
+
end
|
12
|
+
factory :job_title_w_gender_pipe, parent: :job do
|
13
|
+
title 'Key Account Manager m|w'
|
14
|
+
clean_title 'key account manager'
|
15
|
+
end
|
16
|
+
factory :job_title_w_gender_pipe_brackets, parent: :job do
|
17
|
+
title 'Key Account Manager (m|w)'
|
18
|
+
clean_title 'key account manager'
|
19
|
+
end
|
20
|
+
factory :job_title_w_gender2, parent: :job do
|
21
|
+
title 'Projektleiter/in Kundenprojekte'
|
22
|
+
clean_title 'projektleiter kundenprojekte'
|
23
|
+
end
|
24
|
+
factory :job_title_w_gender2_dash, parent: :job do
|
25
|
+
title 'Projektleiter/-in Kundenprojekte'
|
26
|
+
clean_title 'projektleiter kundenprojekte'
|
27
|
+
end
|
28
|
+
factory :job_title_w_gender2_brackets, parent: :job do
|
29
|
+
title "Senior JEE Entwickler(in)"
|
30
|
+
clean_title "senior jee entwickler"
|
31
|
+
end
|
32
|
+
factory :job_title_w_code, parent: :job do
|
33
|
+
title 'Hardware Engineer Digital 10344jr'
|
34
|
+
clean_title 'hardware engineer digital'
|
35
|
+
end
|
36
|
+
factory :job_title_w_code2, parent: :job do
|
37
|
+
title 'Hardware Engineer Digital [SNr. 11739]'
|
38
|
+
clean_title 'hardware engineer digital'
|
39
|
+
end
|
40
|
+
factory :job_title_w_code3, parent: :job do
|
41
|
+
title 'Hardware Engineer Digital (fimad:3154)'
|
42
|
+
clean_title 'hardware engineer digital'
|
43
|
+
end
|
44
|
+
factory :job_title_w_dash, parent: :job do
|
45
|
+
title 'Leiter Packmittelentwicklung - Kunststoffverpackungen für Medizin'
|
46
|
+
clean_title 'leiter packmittelentwicklung kunststoffverpackungen für medizin'
|
47
|
+
end
|
48
|
+
factory :job_title_w_slash, parent: :job do
|
49
|
+
title 'MS Sharepoint Developer / Senior Developer'
|
50
|
+
clean_title 'ms sharepoint developer senior developer'
|
51
|
+
end
|
52
|
+
factory :job_title_w_senior_brackets, parent: :job do
|
53
|
+
title '(Senior) Developer'
|
54
|
+
clean_title 'senior developer'
|
55
|
+
end
|
56
|
+
factory :job_title_var_0, parent: :job do
|
57
|
+
title 'Baustellenleiter / Baustellenkoordinator (m/w) – Arbeiten weltweit!'
|
58
|
+
clean_title 'baustellenleiter baustellenkoordinator arbeiten weltweit'
|
59
|
+
end
|
60
|
+
factory :job_title_w_special, parent: :job do
|
61
|
+
title '++ Sharepoint Developer: Senior Developer!'
|
62
|
+
clean_title 'sharepoint developer senior developer'
|
63
|
+
end
|
64
|
+
factory :job_title_w_percent, parent: :job do
|
65
|
+
title 'Sharepoint Developer (100%)'
|
66
|
+
clean_title 'sharepoint developer'
|
67
|
+
end
|
68
|
+
factory :job_title_downcasing, parent: :job do
|
69
|
+
title 'Sharepoint Developer'
|
70
|
+
clean_title 'sharepoint developer'
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Preprocessor::Simple do
|
5
|
+
it_behaves_like 'a preprocessor'
|
6
|
+
|
7
|
+
let(:simple) { Preprocessor::Simple.new }
|
8
|
+
it "should have process implemented" do
|
9
|
+
-> { simple.process([]) }.should_not raise_error
|
10
|
+
end
|
11
|
+
context do
|
12
|
+
before(:each) do
|
13
|
+
@jobs = FactoryGirl.build_list :job, 3
|
14
|
+
@jobs.each{|e| e.stubs(:classification_id)}
|
15
|
+
@jobs.each{|e| e.stubs(:label)}
|
16
|
+
end
|
17
|
+
it "should work with jobs with quality check" do
|
18
|
+
-> {simple.process(@jobs) }.should_not raise_error
|
19
|
+
end
|
20
|
+
# it "should set labels to true if quality check exists and no wrong_ label set" do
|
21
|
+
# simple.process(@jobs).each{|e| e.career_level!; e.label.should be_true}
|
22
|
+
# end
|
23
|
+
it "should set labels to false if quality check exists and wrong_ label is set" do
|
24
|
+
simple.process(@jobs).each{|e| e.function!; e.label.should be_false}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should work with jobs without quality check" do
|
29
|
+
jobs = FactoryGirl.build_list :job_without_job_check, 3
|
30
|
+
jobs.each{|e| e.stubs(:classification_id)}
|
31
|
+
jobs.each{|e| e.stubs(:label)}
|
32
|
+
-> {simple.process(jobs) }.should_not raise_error
|
33
|
+
end
|
34
|
+
it "should set labels to false if no quality check" do
|
35
|
+
jobs = FactoryGirl.build_list :job_without_job_check, 3
|
36
|
+
jobs.each{|e| e.stubs(:classification_id)}
|
37
|
+
jobs.each{|e| e.stubs(:label)}
|
38
|
+
simple.process(jobs).each{|e| e.career_level!; e.label.should be_false}
|
39
|
+
end
|
40
|
+
|
41
|
+
context "processing" do
|
42
|
+
let(:jobs) { FactoryGirl.build_list(:job,3) }
|
43
|
+
before(:each) do
|
44
|
+
simple.stubs(:clean_title)
|
45
|
+
simple.stubs(:clean_description)
|
46
|
+
jobs.each{|e| e.stubs(:classification_id)}
|
47
|
+
jobs.each{|e| e.stubs(:label)}
|
48
|
+
end
|
49
|
+
it "should call clean_title on each job" do
|
50
|
+
simple.expects(:clean_title).times(3)
|
51
|
+
simple.process(jobs)
|
52
|
+
end
|
53
|
+
it "should call clean_description on each job" do
|
54
|
+
simple.expects(:clean_description).times(3)
|
55
|
+
simple.process(jobs)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "#clean_title" do
|
60
|
+
it "should be downcased" do
|
61
|
+
job = FactoryGirl.build(:job_title_downcasing)
|
62
|
+
simple.clean_title(job.title).should eq(job.clean_title)
|
63
|
+
end
|
64
|
+
[ FactoryGirl.build(:job_title_w_gender),
|
65
|
+
FactoryGirl.build(:job_title_w_gender_brackets),
|
66
|
+
FactoryGirl.build(:job_title_w_gender_pipe),
|
67
|
+
FactoryGirl.build(:job_title_w_gender_pipe_brackets),
|
68
|
+
FactoryGirl.build(:job_title_w_gender2),
|
69
|
+
FactoryGirl.build(:job_title_w_gender2_dash),
|
70
|
+
FactoryGirl.build(:job_title_w_gender2_brackets),
|
71
|
+
FactoryGirl.build(:job_title_w_code),
|
72
|
+
FactoryGirl.build(:job_title_w_code2),
|
73
|
+
FactoryGirl.build(:job_title_w_code3),
|
74
|
+
FactoryGirl.build(:job_title_w_dash),
|
75
|
+
FactoryGirl.build(:job_title_w_slash),
|
76
|
+
FactoryGirl.build(:job_title_w_senior_brackets),
|
77
|
+
FactoryGirl.build(:job_title_var_0),
|
78
|
+
FactoryGirl.build(:job_title_w_special),
|
79
|
+
FactoryGirl.build(:job_title_w_percent)].each do |job|
|
80
|
+
it "should cleanup '#{job.title}'" do
|
81
|
+
simple.clean_title(job.title).should eq(job.clean_title)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
context "#clean_description" do
|
86
|
+
let(:jobs) {
|
87
|
+
[ FactoryGirl.build(:job_description_w_tags),
|
88
|
+
FactoryGirl.build(:job_description_w_adress),
|
89
|
+
FactoryGirl.build(:job_description_w_special),
|
90
|
+
FactoryGirl.build(:job_description_w_code_token),
|
91
|
+
FactoryGirl.build(:job_description_w_gender) ]
|
92
|
+
}
|
93
|
+
it "should remove html/xml tags" do
|
94
|
+
desc = simple.clean_description(jobs[0].description)
|
95
|
+
desc.should_not match(/<(.*?)>/)
|
96
|
+
end
|
97
|
+
it "should remove new lines" do
|
98
|
+
desc = simple.clean_description(jobs[0].description)
|
99
|
+
desc.should_not match(/\r\n|\n|\r/)
|
100
|
+
end
|
101
|
+
it "should remove all special characters" do
|
102
|
+
desc = simple.clean_description(jobs[2].description)
|
103
|
+
desc.should_not match(/[^a-z öäü]/i)
|
104
|
+
end
|
105
|
+
it "should remove gender tokens" do
|
106
|
+
desc = simple.clean_description(jobs[3].description)
|
107
|
+
desc.should_not match(%r{(\(*(m|w)(\/|\|)(w|m)\)*)|(/-*in)|\(in\)})
|
108
|
+
end
|
109
|
+
it "should remove job code token" do
|
110
|
+
desc = simple.clean_description(jobs[4].description)
|
111
|
+
desc.should_not match(/\[.*\]|\(.*\)|\{.*\}|\d+\w+/)
|
112
|
+
end
|
113
|
+
it "should be downcased" do
|
114
|
+
desc = simple.clean_description(jobs[2].description)
|
115
|
+
desc.should_not match(/[^a-z öäü]/)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
context "parallel" do
|
119
|
+
let(:parallel) { Preprocessor::Simple.new(parallel: true) }
|
120
|
+
|
121
|
+
let(:jobs) {
|
122
|
+
[ FactoryGirl.build(:job_description_w_tags),
|
123
|
+
FactoryGirl.build(:job_description_w_adress),
|
124
|
+
FactoryGirl.build(:job_description_w_special),
|
125
|
+
FactoryGirl.build(:job_description_w_code_token),
|
126
|
+
FactoryGirl.build(:job_description_w_gender) ]
|
127
|
+
}
|
128
|
+
before(:each) do
|
129
|
+
jobs.each{|e| e.stubs(:classification_id)}
|
130
|
+
jobs.each{|e| e.stubs(:label)}
|
131
|
+
end
|
132
|
+
it "should be the same parallelized" do
|
133
|
+
single = simple.process(jobs, :function)
|
134
|
+
p_data = parallel.process(jobs, :function)
|
135
|
+
single.each.with_index { |e,i| e.data.should == p_data[i].data }
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Preprocessor::WithIndustryMap do
|
4
|
+
it_behaves_like 'a preprocessor'
|
5
|
+
let(:preprocessor) { Preprocessor::WithIndustryMap.new(industry_map: {1423=>3, 523=>54}) }
|
6
|
+
let(:job) { FactoryGirl.build(:job) }
|
7
|
+
let(:jobs) { [job] }
|
8
|
+
before(:each) do
|
9
|
+
job.stubs(:classification_id)
|
10
|
+
job.stubs(:label)
|
11
|
+
end
|
12
|
+
it "should make use of a industry_map" do
|
13
|
+
preprocessor.expects(:map_industry_id)
|
14
|
+
preprocessor.process(jobs)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Selector::NGram do
|
4
|
+
it_behaves_like 'a selector'
|
5
|
+
|
6
|
+
let(:ngram) { Selector::NGram.new(gram_size: 3) }
|
7
|
+
context "#extract_words_from_data" do
|
8
|
+
it "should generate a list of words from the data" do
|
9
|
+
words = ngram.extract_words_from_data(FactoryGirl.build(:data))
|
10
|
+
words.should have(4).things
|
11
|
+
end
|
12
|
+
it "should remove words with 3 characters or less" do
|
13
|
+
words = ngram.extract_words_from_data(FactoryGirl.build(:data_w_short_words))
|
14
|
+
words.should have(2).things
|
15
|
+
end
|
16
|
+
it "should process multiple sections in the data" do
|
17
|
+
words = ngram.extract_words_from_data(FactoryGirl.build(:data_w_multiple_sections))
|
18
|
+
words.should have(2).things
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Selector::Simple do
|
4
|
+
it_behaves_like 'a selector'
|
5
|
+
|
6
|
+
let(:simple) { Selector::Simple.new }
|
7
|
+
it "should have select_feature_vector implemented" do
|
8
|
+
expect { simple.generate_vectors([]) }.to_not raise_error
|
9
|
+
end
|
10
|
+
context "#stopwords" do
|
11
|
+
it "simply loads them from a file"
|
12
|
+
end
|
13
|
+
context "#extract_words_from_data" do
|
14
|
+
it "should generate a list of words from the data" do
|
15
|
+
words = simple.extract_words_from_data(FactoryGirl.build(:data))
|
16
|
+
words.should have(6).things
|
17
|
+
end
|
18
|
+
it "should remove words with 3 characters or less" do
|
19
|
+
words = simple.extract_words_from_data(FactoryGirl.build(:data_w_short_words))
|
20
|
+
words.should have(4).things
|
21
|
+
end
|
22
|
+
it "should process multiple sections in the data" do
|
23
|
+
words = simple.extract_words_from_data(FactoryGirl.build(:data_w_multiple_sections))
|
24
|
+
words.should have(4).things
|
25
|
+
end
|
26
|
+
end
|
27
|
+
context "#extract_words" do
|
28
|
+
it "should call extract_words_from_data for each data object" do
|
29
|
+
simple.expects(:extract_words_from_data).times(4)
|
30
|
+
simple.extract_words(FactoryGirl.build_list(:data,4))
|
31
|
+
end
|
32
|
+
it "should return an array of word arrays" do
|
33
|
+
words_per_data = simple.extract_words(FactoryGirl.build_list(:data,4))
|
34
|
+
words_per_data.each do |words|
|
35
|
+
words.should eq(simple.extract_words_from_data(FactoryGirl.build(:data)))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
context "#generate_global_dictionary" do
|
40
|
+
let(:data) { [FactoryGirl.build_list(:data,1),
|
41
|
+
FactoryGirl.build_list(:data_w_short_words,2),
|
42
|
+
FactoryGirl.build_list(:data_w_multiple_sections,3)].flatten }
|
43
|
+
let(:words_per_data) { simple.extract_words(data) }
|
44
|
+
it "should return a list of n words" do
|
45
|
+
simple.generate_global_dictionary(words_per_data,2)
|
46
|
+
simple.global_dictionary.should have(2).things
|
47
|
+
end
|
48
|
+
it "should return a list of the n most used words in the data array" do
|
49
|
+
simple.generate_global_dictionary(words_per_data,3)
|
50
|
+
simple.global_dictionary.should eq(%w(fooo auto baaz))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
context "#generate_vector" do
|
54
|
+
let(:dictionary) { %w(auto pferd haus hase garten) }
|
55
|
+
let(:data) { FactoryGirl.build(:data) }
|
56
|
+
let(:vector) { simple.generate_vector(data).tap{|e| e.career_level! } }
|
57
|
+
|
58
|
+
before(:each) do
|
59
|
+
simple.stubs(:global_dictionary).returns(dictionary)
|
60
|
+
end
|
61
|
+
it "should build a feature vector for each dataset with the size of the dictionary plus classifications" do
|
62
|
+
vector.data.should have(5+8).things
|
63
|
+
end
|
64
|
+
it "should set 0 if a word from the dictionary NOT exists at the corresponding index" do
|
65
|
+
vector.data[0].should eq(0)
|
66
|
+
end
|
67
|
+
it "should set 1 if a word from the dictionary exists at the corresponding index" do
|
68
|
+
vector.data[1].should eq(1)
|
69
|
+
end
|
70
|
+
it "should set 0's and 1's for each word in the dictionary" do
|
71
|
+
vector.data.first(5).should eq([0,1,1,0,1])
|
72
|
+
end
|
73
|
+
it "should add a n-sized array of 0's and 1's to the results" do
|
74
|
+
vector.data.last(8).should eq([0,0,0,0,0,0,1,0])
|
75
|
+
end
|
76
|
+
it "should call make_vector" do
|
77
|
+
simple.expects(:make_vector).once
|
78
|
+
simple.generate_vector(data)
|
79
|
+
end
|
80
|
+
context "custom dictionary" do
|
81
|
+
it "should accept a custom dictionary" do
|
82
|
+
vector = simple.generate_vector(data, :career_level, %w(pferd flasche glas))
|
83
|
+
vector.data.should eq([[1,0,0],[0,0,0,0,0,0,1,0]].flatten)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
context "#generate_vectors" do
|
88
|
+
let(:dictionary) { %w(auto pferd haus hase garten) }
|
89
|
+
let(:data) { FactoryGirl.build_list(:data,2) }
|
90
|
+
let(:words_per_data) { [%w(pferd hase flasche),%w(flasche glas hase meer)] }
|
91
|
+
before(:each) do
|
92
|
+
simple.stubs(:global_dictionary).returns(dictionary)
|
93
|
+
end
|
94
|
+
it "should call extract words" do
|
95
|
+
simple.expects(:extract_words).returns([])
|
96
|
+
simple.generate_vectors(data)
|
97
|
+
end
|
98
|
+
it "should call generate_global_dictionary" do
|
99
|
+
simple.stubs(:extract_words).returns([])
|
100
|
+
simple.expects(:generate_global_dictionary).returns([])
|
101
|
+
simple.generate_vectors(data)
|
102
|
+
end
|
103
|
+
it "should call make_vector for each set of words" do
|
104
|
+
simple.stubs(:extract_words).returns(words_per_data)
|
105
|
+
simple.expects(:make_vector).twice
|
106
|
+
simple.generate_vectors(data)
|
107
|
+
end
|
108
|
+
context "parallel" do
|
109
|
+
let(:parallel) { Selector::Simple.new(parallel: true) }
|
110
|
+
before(:each) do
|
111
|
+
simple.stubs(:global_dictionary).returns(dictionary)
|
112
|
+
parallel.stubs(:global_dictionary).returns(dictionary)
|
113
|
+
end
|
114
|
+
it "should be equal results in processes" do
|
115
|
+
single = simple.generate_vectors(data)
|
116
|
+
p_data = parallel.generate_vectors(data)
|
117
|
+
single.each.with_index {|e,i| e.data.should == p_data[i].data}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|