sentimental 1.0.4 → 1.1.0

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZGEzZGRjMmQ3NDk2Y2NlMzYwNWRkZWU2OTZmNzI1YTlmNmRiMGFiOQ==
4
+ NTM5MTBkMzdiNWY0NzdiYzliOWJlZWNmZDIyMzVjMDM1ZWJjNDYxYw==
5
5
  data.tar.gz: !binary |-
6
- NDAxMDFmNzZlMTQ3M2RmZGMzN2U4MjQwOGIzYTYyNDg0NzYzZWNjYQ==
6
+ NTVlYWNhNDIxZmE3ZDUyZjQ4N2ZlMGYxYWY0NzYxYmIxYWY2ZDZjNg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MjgzZDQ0MTFjOGM0Y2ZjZjAwYjg1NTlhOTRjMTZlZTM2ODkwMjY2MDFjYWU0
10
- ZjNlNDA4NGM3NThiZmEwNjRkYWQ5YWZiZDE1YjM2OGZjYzJiMTM2NDMxZmNl
11
- OTdmNGNhOTBjMjFmZjkxNmRhYjc4MDg5YWZmZjY1YjdjMDczOGI=
9
+ YjM0OTc1MzYyMDdlMmYyMWIyOTgwNmYyYThiMDhjZjkzMDFkYmFiNGNjYjBl
10
+ OWY3Zjg1NmFkZTgxY2YzY2I2OGMxZjBhNzhlZjEwNjkzNDQxNTRhNTQxYzFj
11
+ Yjc2NDBmZjk0OWZkYTc3ODMyMjFjN2RlY2FjMDFlNWMzMjRhM2M=
12
12
  data.tar.gz: !binary |-
13
- YjRhNzA3ZmJhOTdmMzIzMTU1MzcyM2ZlYThhOTM4MzdmYThhYzc0NDUxNTNm
14
- ZjM4MzBjMmE3Y2E2YTlmOTgyZjc3N2E2MTcxOTgxOWQ5ZmE4MTlhNTkwYzI5
15
- NTI0ZmVjNGY3MTFhNmFjMmUyYmQwOWVkZjcwYzg0NGM2NWQwNWU=
13
+ Nzg5YzMwMjM3MjU3YzJhOTU4NGIzN2NkZTY4ZjhkMGVmOWY5ZjcyNmMxYzdm
14
+ YzlkOGM5MDNhMzBiMjhkMmIyZThiMzAxYzA3Y2UxYTc2N2JlYmMzODE3MDFk
15
+ MDhhZjkwYTNmMGU1NDE1MTY0ZDUzNGZkYmRmM2JkMzVjM2M3Y2Y=
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ *.DS_Store
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sentimental (1.0.4)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rake (10.5.0)
11
+ rspec (3.4.0)
12
+ rspec-core (~> 3.4.0)
13
+ rspec-expectations (~> 3.4.0)
14
+ rspec-mocks (~> 3.4.0)
15
+ rspec-core (3.4.1)
16
+ rspec-support (~> 3.4.0)
17
+ rspec-expectations (3.4.0)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.4.0)
20
+ rspec-mocks (3.4.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.4.0)
23
+ rspec-support (3.4.1)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.3)
30
+ rake
31
+ rspec (>= 3.0.0)
32
+ sentimental!
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+
2
+ The MIT License (MIT)
3
+ Copyright © 2015 Jeff Emminger <jeff@7compass.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the “Software”), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -73,6 +73,10 @@ scores and tokens, e.g.:
73
73
 
74
74
  gem install sentimental
75
75
 
76
+ ## License
77
+
78
+ MIT License
79
+
76
80
  ## Credits
77
81
 
78
82
  Based largely on Christopher MacLellan's script:
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
File without changes
File without changes
data/lib/sentimental.rb CHANGED
@@ -1,116 +1,52 @@
1
-
2
- # Based on code from https://github.com/cmaclell/Basic-Tweet-Sentiment-Analyzer
3
-
4
-
5
- #############################################################################
6
- # Copyright: Christopher MacLellan 2010
7
- # Description: This code adds functions to the string class for calculating
8
- # the sentivalue of strings. It is not called directly by the
9
- # tweet-search-sentiment.rb program but is included for possible
10
- # future use.
11
- #
12
- # This program is free software: you can redistribute it and/or modify
13
- # it under the terms of the GNU General Public License as published by
14
- # the Free Software Foundation, either version 3 of the License, or
15
- # (at your option) any later version.
16
- #
17
- # This program is distributed in the hope that it will be useful,
18
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- # GNU General Public License for more details.
21
- #
22
- # You should have received a copy of the GNU General Public License
23
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
24
- #############################################################################
25
-
26
- #
27
- # In an initializer, you can initialize some global defaults:
28
- #
29
- # Sentimental.load_defaults
30
- # Sentimental.threshold = 0.1
31
- #
32
- # Then create an instance for usage:
33
- #
34
- # analyzer = Sentimental.new
35
- # analyzer.get_sentiment('I love your service')
36
- # => :positive
37
- #
38
- # You can make new analyzers with individual thresholds:
39
- #
40
- # analyzer = Sentimental.new(0.9)
41
- # analyzer.get_sentiment('I love your service')
42
- # => :positive
43
- # analyzer.get_sentiment('I like your service')
44
- # => :neutral
45
- #
46
1
  class Sentimental
47
- @@sentihash = Hash.new(0.0)
48
- @@threshold = 0.0
2
+ attr_accessor :threshold, :word_scores, :neutral_regexps
49
3
 
50
- def initialize(threshold = nil)
51
- @threshold = threshold || @@threshold
4
+ def initialize(threshold: 0, word_scores: nil, neutral_regexps: [])
5
+ @word_scores = Hash.new(0.0) || word_scores
6
+ @threshold = threshold
7
+ @neutral_regexps = neutral_regexps
52
8
  end
53
9
 
54
- #####################################################################
55
- # Function that returns the sentiment value for a given string.
56
- # This value is the sum of the sentiment values of each of the words.
57
- # Stop words are NOT removed.
58
- #
59
- # return:float -- sentiment value of the current string
60
- #####################################################################
61
- def get_score(string)
62
- sentiment_total = 0.0
10
+ def score(string)
11
+ return 0 if neutral_regexps.any? {|regexp| string =~ regexp}
63
12
 
64
- #tokenize the string, also throw away some punctuation
65
- tokens = string.to_s.downcase.split(/\W*\s+\W*|^\W+|\W+$/)
66
-
67
- tokens.each do |token|
68
- sentiment_total += @@sentihash[token]
13
+ extract_words(string).inject(0) do |score, token|
14
+ score += word_scores[token]
69
15
  end
70
- sentiment_total
71
16
  end
72
17
 
73
- def get_sentiment(string)
74
- score = get_score(string)
18
+ def sentiment(string)
19
+ score = score(string)
75
20
 
76
- # if less then the negative threshold classify negative
77
- if score < (-1 * @threshold)
21
+ if score < (-1 * threshold)
78
22
  :negative
79
- # if greater then the positive threshold classify positive
80
- elsif score > @threshold
23
+ elsif score > threshold
81
24
  :positive
82
25
  else
83
26
  :neutral
84
27
  end
85
28
  end
86
29
 
87
- # Loads the default sentiment files
88
- def self.load_defaults
89
- load_senti_file(File.dirname(__FILE__) + '/sentiwords.txt')
90
- load_senti_file(File.dirname(__FILE__) + '/sentislang.txt')
30
+ def load_defaults
31
+ ['sentiwords', 'sentislang'].each do |filename|
32
+ load_senti_file(File.dirname(__FILE__) + "/../data/#{filename}.txt")
33
+ end
91
34
  end
92
35
 
93
- #####################################################################
94
- # load the specified sentiment file into a hash
95
- #
96
- # filename:string -- name of file to load
97
- # sentihash:hash -- hash to load data into
98
- # return:hash -- hash with data loaded
99
- #####################################################################
100
- def self.load_senti_file(filename)
101
- # load the word file
102
- file = File.new(filename)
103
- while (line = file.gets)
104
- parsedline = line.chomp.split(/\s/)
105
- sentiscore = parsedline[0]
106
- text = parsedline[1]
107
- @@sentihash[text] = sentiscore.to_f
36
+ def load_senti_file(filename)
37
+ File.open(filename) do |file|
38
+ file.each_line do |line|
39
+ parsed_line = line.chomp.split(/\s+/)
40
+ sentiscore = parsed_line[0]
41
+ text = parsed_line[1]
42
+ word_scores[text] = sentiscore.to_f
43
+ end
108
44
  end
109
- file.close
110
45
  end
111
46
 
112
- def self.threshold=(threshold)
113
- @@threshold = threshold
114
- end
47
+ private
115
48
 
49
+ def extract_words(string)
50
+ string.to_s.downcase.scan(/([\w']+|\S{2,})/).flatten
51
+ end
116
52
  end
@@ -0,0 +1,19 @@
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'sentimental'
3
+ spec.version = '1.1.0'
4
+ spec.summary = 'Simple sentiment analysis'
5
+ spec.description = 'A simple sentiment analysis gem'
6
+ spec.authors = ['Jeff Emminger', 'Christopher MacLellan', 'Denis Pasin']
7
+ spec.email = ['jeff@7compass.com', 'denis@hellojam.fr']
8
+ spec.homepage = 'https://github.com/7compass/sentimental'
9
+ spec.license = 'MIT'
10
+
11
+ spec.files = `git ls-files`.split($/)
12
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
13
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
+ spec.require_paths = ['lib']
15
+
16
+ spec.add_development_dependency "bundler", "~> 1.3"
17
+ spec.add_development_dependency "rake"
18
+ spec.add_development_dependency "rspec", ">= 3.0.0"
19
+ end
@@ -0,0 +1,72 @@
1
+ require_relative "../lib/sentimental"
2
+
3
+ describe Sentimental do
4
+
5
+ before :each do
6
+ analyzer.load_defaults
7
+ end
8
+
9
+ let(:analyzer) { Sentimental.new(threshold: 0.1) }
10
+
11
+ describe "#score" do
12
+ subject do
13
+ analyzer.score(text)
14
+ end
15
+
16
+ context "when the text is postive" do
17
+ let(:text) {'I love ruby'}
18
+
19
+ it 'returns a positive score' do
20
+ expect(subject).to be > 0
21
+ end
22
+ end
23
+
24
+ context "when the text is neutral" do
25
+ let(:text) {'I like ruby'}
26
+
27
+ it 'returns a neutral score' do
28
+ expect(subject).to eq 0
29
+ end
30
+ end
31
+
32
+ context "when the text is negative" do
33
+ let(:text) {'I hate ruby'}
34
+
35
+ it 'returns a negative score' do
36
+ expect(subject).to be < 0
37
+ end
38
+ end
39
+
40
+ context "when the text has smiley" do
41
+ let(:text) {'I love ruby'}
42
+ let(:text_with_smiley) {'I love ruby :-)'}
43
+
44
+ it 'scores it' do
45
+ expect(analyzer.score(text_with_smiley)).to be > analyzer.score(text)
46
+ end
47
+ end
48
+
49
+ context "when the text has punctuation" do
50
+ let(:text) {'I love ruby'}
51
+ let(:text_with_punctuation) {'I love, ruby'}
52
+
53
+ it 'removes it' do
54
+ expect(analyzer.score(text_with_punctuation)).to eq analyzer.score(text)
55
+ end
56
+ end
57
+
58
+ context "when there is some neutral regexp" do
59
+ let(:text_neutral) {"Do you love ruby?"}
60
+ let(:text) {"I love ruby"}
61
+
62
+ before do
63
+ analyzer.neutral_regexps << /\?\s*$/
64
+ end
65
+
66
+ it "scores it to 0" do
67
+ expect(analyzer.score(text_neutral)).to eq 0
68
+ expect(analyzer.score(text)).not_to eq 0
69
+ end
70
+ end
71
+ end
72
+ end
metadata CHANGED
@@ -1,26 +1,78 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentimental
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Emminger
8
8
  - Christopher MacLellan
9
+ - Denis Pasin
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2015-11-12 00:00:00.000000000 Z
13
- dependencies: []
13
+ date: 2016-03-10 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ version: '1.3'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: rspec
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: 3.0.0
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: 3.0.0
14
57
  description: A simple sentiment analysis gem
15
- email: jeff@7compass.com
58
+ email:
59
+ - jeff@7compass.com
60
+ - denis@hellojam.fr
16
61
  executables: []
17
62
  extensions: []
18
63
  extra_rdoc_files: []
19
64
  files:
65
+ - .gitignore
66
+ - Gemfile
67
+ - Gemfile.lock
68
+ - LICENSE.txt
20
69
  - README.md
70
+ - Rakefile
71
+ - data/sentislang.txt
72
+ - data/sentiwords.txt
21
73
  - lib/sentimental.rb
22
- - lib/sentislang.txt
23
- - lib/sentiwords.txt
74
+ - sentimental.gemspec
75
+ - spec/sentimental_spec.rb
24
76
  homepage: https://github.com/7compass/sentimental
25
77
  licenses:
26
78
  - MIT
@@ -28,7 +80,6 @@ metadata: {}
28
80
  post_install_message:
29
81
  rdoc_options: []
30
82
  require_paths:
31
- - .
32
83
  - lib
33
84
  required_ruby_version: !ruby/object:Gem::Requirement
34
85
  requirements:
@@ -46,4 +97,5 @@ rubygems_version: 2.4.8
46
97
  signing_key:
47
98
  specification_version: 4
48
99
  summary: Simple sentiment analysis
49
- test_files: []
100
+ test_files:
101
+ - spec/sentimental_spec.rb