svm_helper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +3 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +9 -0
  6. data/.versions.conf +4 -0
  7. data/.yardopts +3 -0
  8. data/Gemfile +24 -0
  9. data/Guardfile +17 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +41 -0
  12. data/Rakefile +7 -0
  13. data/lib/svm_helper.rb +8 -0
  14. data/lib/svm_helper/feature_vector.rb +17 -0
  15. data/lib/svm_helper/interface_helper.rb +57 -0
  16. data/lib/svm_helper/preprocessed_data.rb +17 -0
  17. data/lib/svm_helper/preprocessors.rb +2 -0
  18. data/lib/svm_helper/preprocessors/simple.rb +111 -0
  19. data/lib/svm_helper/preprocessors/with_industry_map.rb +40 -0
  20. data/lib/svm_helper/selectors.rb +3 -0
  21. data/lib/svm_helper/selectors/n_gram.rb +31 -0
  22. data/lib/svm_helper/selectors/simple.rb +163 -0
  23. data/lib/svm_helper/selectors/with_binary_encoding.rb +42 -0
  24. data/lib/svm_helper/stopwords/de +127 -0
  25. data/lib/svm_helper/stopwords/en +119 -0
  26. data/lib/svm_helper/version.rb +3 -0
  27. data/spec/factories.rb +35 -0
  28. data/spec/factories/jobs/tmp.html +42 -0
  29. data/spec/factories/jobs/tmp2.html +20 -0
  30. data/spec/factories/jobs/tmp3.html +34 -0
  31. data/spec/factories/jobs_with_description.rb +20 -0
  32. data/spec/factories/jobs_with_title.rb +72 -0
  33. data/spec/preprocessors/simple_spec.rb +138 -0
  34. data/spec/preprocessors/with_industry_map_spec.rb +16 -0
  35. data/spec/selectors/n_gram_spec.rb +21 -0
  36. data/spec/selectors/simple_spec.rb +121 -0
  37. data/spec/selectors/with_binary_encoding_spec.rb +39 -0
  38. data/spec/spec_helper.rb +14 -0
  39. data/spec/support/preprocessor_spec.rb +21 -0
  40. data/spec/support/selector_spec.rb +21 -0
  41. data/svm_helper.gemspec +21 -0
  42. metadata +112 -0
@@ -0,0 +1,3 @@
1
+ module SvmHelper
2
+ VERSION = "0.1.0"
3
+ end
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