tsentiment 2.0.0 → 4.0.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,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 298293e735de9476582ab0ea0f99fa137ca9c1c4ef274b43e4c3a816406a0b62
4
- data.tar.gz: 3586edcb2bdacbc505b5c6b45b79940fd1f8cf01650c38596466f1ea6317f7f2
3
+ metadata.gz: 166e9071ff25501edcd39c37c497a9c57c3de187c7f6db99f2365214793c0a90
4
+ data.tar.gz: 6c73f3d2508da10f31ef64401a126c9582536114cf90c8c92abca53111733dd1
5
5
  SHA512:
6
- metadata.gz: aa425cb2c1e1e53ba258374b0302de687bbdf0cd99d2f6568722297ab976f8f09701623fd45d08fb684d4ea6c63daaa89322d064e8086009f809a6386030fa79
7
- data.tar.gz: d905dcd3134d287417c4123c70fc2c90bd4abb9ee53575189a30e7447ce09d163cdcb02b41db0c3a315e312bbdc4277dbe14189512328430af60144a7a8dd34a
6
+ metadata.gz: e71042c1e22d9fcc53b0890cd0f70b91c71f3fd285747b8dc494cddfd8c3a3a167e1d8561fe8212e1d3cac8ebbccdf67b1cabc0f87cb6f3fe21d64768ecc23cb
7
+ data.tar.gz: dd8d13dcd701ca9b5e353389ebad541eb4acb154b08239bed6d253ea4bc7dfaf3ab378d94df6f01f38a39f1a6747e00605ba2641de9460f7a16fc12a77a53fa1
@@ -0,0 +1,35 @@
1
+ require_relative 'task'
2
+
3
+ class CompositeTask < Task
4
+
5
+ def initialize(name)
6
+ super(name)
7
+ @sub_tasks = []
8
+ end
9
+
10
+ def <<(task)
11
+ @sub_tasks << task
12
+ end
13
+
14
+ def [](index)
15
+ @sub_tasks[index]
16
+ end
17
+
18
+ def []=(index, new_value)
19
+ @sub_tasks[index] = new_value
20
+ end
21
+
22
+ def size
23
+ @sub_tasks.size
24
+ end
25
+
26
+ def remove_sub_task(task)
27
+ @sub_tasks.delete(task)
28
+ end
29
+
30
+ def sentiment_value
31
+ time=0.0
32
+ @sub_tasks.each { |task| time += task.sentiment_value}
33
+ time
34
+ end
35
+ end
@@ -0,0 +1,110 @@
1
+ #Version with median library, negated sentiment calculation and overall sentiment calculation with composite
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+ require_relative 'median'
6
+ require_relative 'negativity'
7
+ require_relative 'positivity'
8
+ require_relative 'negated'
9
+ require_relative 'composite_pattern'
10
+ require_relative 'total_sentiment'
11
+
12
+
13
+ class FindSentiment
14
+
15
+ def self.value(reviews, rating)
16
+
17
+ sentiment = Array.new
18
+ lexicon_sentiment = Array.new
19
+ review_sentiment = Array.new
20
+ overall_sentiment = Array.new
21
+ composite = CompositeTask.new('Sentiment')
22
+ negated = FindNegation.instance
23
+
24
+ i = 0
25
+
26
+ reviews.each do
27
+ string = reviews[i]
28
+
29
+ phrase_sentiment = Array.new
30
+
31
+ j = 0
32
+
33
+ sentence = string.split(".")
34
+
35
+ sentence.each do
36
+
37
+ phrase = sentence[j]
38
+
39
+ length = phrase.gsub(/\s+/, "").size
40
+
41
+ # Do not analyse the sentence if it's just an empty or just has one character
42
+
43
+ if length <= 1
44
+ j+=1
45
+ else
46
+
47
+ #Split the phrase into lexicons based on no. of negators and see if there are any
48
+
49
+ lexicon = phrase.split(/not|no|never/)
50
+ k = 0
51
+
52
+ if lexicon.count > 1 # If block handles the sentiment calculation of a phrase if the it has any negator
53
+ lexicon.each do
54
+ #lexicon_value = FindNegation.value(lexicon[k])
55
+ negated.sentiment(lexicon[k])
56
+ lexicon_value = negated.sentiment_value
57
+ lexicon_sentiment.push(lexicon_value)
58
+ k+=1
59
+ end
60
+
61
+ #sentiment value of each phrase separated by a full stop with negated sentiment calculation
62
+ sentiment_value = lexicon_sentiment.sum
63
+
64
+ else
65
+
66
+ # This block handles the sentiment calculation of a single phrase if it has no negator at all
67
+
68
+ #Finding total sentiment using composite design pattern
69
+
70
+ composite << TotalSentiment.new(phrase)
71
+
72
+
73
+
74
+ #sentiment value of each phrase separated by a full stop without negative words
75
+ sentiment_value = composite.sentiment_value
76
+
77
+ end
78
+
79
+ #stores sentiment value of each phrase of a review into the array phrase_sentiment
80
+ phrase_sentiment.push(sentiment_value)
81
+
82
+ j += 1
83
+
84
+ end
85
+ end
86
+
87
+ #Store sentiment of a single review - median of all phrases in a review
88
+
89
+ review_sentiment.push(FindMedian.value(phrase_sentiment))
90
+
91
+ i += 1
92
+
93
+ end
94
+
95
+ #Overall sentiment of all reviews - median of sentiment of all reviews
96
+
97
+ overall_sentiment = FindMedian.value(review_sentiment)
98
+
99
+ #Total sentiment of average of overall sentiment value of all user reviews + overall user rating
100
+
101
+ total_sentiment = (rating.to_f + overall_sentiment.to_f) / 2
102
+
103
+ return total_sentiment.to_f.round(2)
104
+
105
+ end
106
+
107
+ end
108
+
109
+ string = Array.new
110
+
@@ -0,0 +1,19 @@
1
+
2
+ class FindMedian
3
+
4
+ def self.value(array)
5
+
6
+ sorted = array.sort
7
+ len = sorted.length
8
+
9
+ if len != 0
10
+ median = ((sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0)
11
+ else
12
+ median = 0
13
+ end
14
+
15
+ return median
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,137 @@
1
+ require_relative 'task'
2
+ require_relative 'median'
3
+ require 'singleton'
4
+ require 'json'
5
+ require 'net/http'
6
+ require_relative 'negativity'
7
+ require_relative 'positivity'
8
+
9
+ class FindNegation < Task
10
+
11
+ include Singleton
12
+
13
+ def initialize
14
+ end
15
+
16
+ def sentiment(comment)
17
+
18
+ @phrase = comment
19
+ @sentiment
20
+
21
+ positive = FindPositivity.instance
22
+ negative = FindNegativity.instance
23
+
24
+ uri = URI('http://18.221.169.60/results')
25
+ params = { :limit => 10, :page => 3 }
26
+ uri.query = URI.encode_www_form(params)
27
+ res = Net::HTTP.get_response(uri)
28
+ adjectives = JSON.parse(res.body)
29
+
30
+ positives = adjectives[0]['positives']
31
+ negatives = adjectives[0]['negatives']
32
+
33
+ words = @phrase.split(/\W+/)
34
+
35
+ array1 = Array.new
36
+ output1 = Hash.new
37
+ array2 = Array.new
38
+ output2 = Hash.new
39
+
40
+ words.each do
41
+ |ws| ws.scan(/[\w']+/) do
42
+ |w| if positives.key?(w)
43
+ output1[ws] = positives[w]
44
+ array1.push(output1)
45
+ end
46
+
47
+ if negatives.key?(w)
48
+ output2[ws] = negatives[w]
49
+ array2.push(output2)
50
+ end
51
+ end
52
+ end
53
+
54
+ if array1.count == 0 && array2.count == 0
55
+ #puts "In case 0"
56
+ @sentiment = 0
57
+ end
58
+
59
+ if array1.count == 0 && array2.count != 0
60
+ #puts "In case 1"
61
+ positivity_sentiment = 0
62
+ negative.sentiment(@phrase)
63
+ negativity_sentiment = negative.sentiment_value
64
+ @sentiment = positivity_sentiment - negativity_sentiment
65
+ end
66
+
67
+ if array1.count != 0 && array2.count == 0
68
+ #puts "In case 2"
69
+ negativity_sentiment = 0
70
+ positive.sentiment(@phrase)
71
+ positivity_sentiment = positive.sentiment_value
72
+ @sentiment = negativity_sentiment - positivity_sentiment
73
+ end
74
+
75
+ if array1.count != 0 && array2.count != 0
76
+
77
+ #puts "In case 3"
78
+
79
+ first_positive = output1
80
+ first_negative = output2
81
+
82
+ index1 = @phrase.index("#{first_positive.keys[0]}")
83
+ index2 = @phrase.index("#{first_negative.keys[0]}")
84
+
85
+ if index1 < index2
86
+ #puts "The word #{first_positive.keys[0]} appears first"
87
+ negated_adj = first_positive
88
+ negated_sentiment = (negated_adj.values[0] * -1) # Negation only changes positive sentiment to negative
89
+ else
90
+ # puts "The word #{first_negative.keys[0]} appears first"
91
+ negated_adj = first_negative
92
+ #puts negated_adj
93
+ negated_sentiment = (negated_adj.values[0]) # Double negativity already
94
+ end
95
+
96
+ #Fetch the words after the first adjective and store it in remainder[1]
97
+
98
+ remainder = @phrase.split(/#{negated_adj.keys[0]}/)
99
+
100
+ # Find the sentiment of remainder[1]
101
+
102
+ positive.sentiment(remainder[1])
103
+ positivity_sentiment = positive.sentiment_value
104
+
105
+ negative.sentiment(remainder[1])
106
+ negativity_sentiment = negative.sentiment_value
107
+
108
+ #Now total sentiment = negated sentiment of first adjective + sentiment of the remainder[1]
109
+
110
+ if index1 < index2
111
+ #puts "I am in first positive"
112
+ fraction = Array[negated_sentiment, negativity_sentiment]
113
+ values = FindMedian.value(fraction)
114
+ @sentiment = positivity_sentiment + values
115
+ else
116
+ #puts "I am in first negative"
117
+ fraction = Array[negated_sentiment, positivity_sentiment]
118
+ values = FindMedian.value(fraction)
119
+ @sentiment = values + negativity_sentiment
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+
126
+ def sentiment_value
127
+ @sentiment
128
+ end
129
+
130
+ end
131
+
132
+ #string = "This product is bad"
133
+
134
+ #weight = FindNegation.instance
135
+ #weight.sentiment(string)
136
+ #puts weight.sentiment_value
137
+
@@ -0,0 +1,59 @@
1
+ require_relative 'task'
2
+ require_relative 'median'
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'singleton'
6
+
7
+ class FindNegativity < Task
8
+
9
+ include Singleton
10
+
11
+ def initialize
12
+ end
13
+
14
+ def sentiment(comment)
15
+
16
+ @phrase = comment
17
+ @sentiment
18
+ uri = URI('http://18.221.169.60/results')
19
+ params = { :limit => 10, :page => 3 }
20
+ uri.query = URI.encode_www_form(params)
21
+ res = Net::HTTP.get_response(uri)
22
+ adjectives = JSON.parse(res.body)
23
+
24
+ negatives = adjectives[0]['negatives']
25
+
26
+ words = @phrase.split(/\W+/)
27
+
28
+ array = Array.new
29
+ output = Hash.new
30
+
31
+ words.each do
32
+ |ws| ws.scan(/[\w']+/) do
33
+ |w| if negatives.key?(w)
34
+ output[ws] = negatives[w]
35
+ array.push(output)
36
+ end
37
+ end
38
+ end
39
+
40
+ @sentiment = FindMedian.value(output.values)
41
+ #puts negativity_sentiment
42
+
43
+ end
44
+
45
+ def sentiment_value
46
+ (@sentiment * -1)
47
+ end
48
+
49
+ end
50
+
51
+
52
+
53
+
54
+ #string = "This product is bad"
55
+
56
+ #weight = FindNegativity.instance
57
+ #weight.sentiment(string)
58
+ #puts weight.sentiment_value
59
+
@@ -0,0 +1,58 @@
1
+ require_relative 'task'
2
+ require_relative 'median'
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'singleton'
6
+
7
+ class FindPositivity < Task
8
+
9
+ include Singleton
10
+
11
+ def initialize
12
+ end
13
+
14
+ def sentiment(comment)
15
+
16
+ @phrase = comment
17
+ @sentiment
18
+ uri = URI('http://18.221.169.60/results')
19
+ params = { :limit => 10, :page => 3 }
20
+ uri.query = URI.encode_www_form(params)
21
+ res = Net::HTTP.get_response(uri)
22
+ adjectives = JSON.parse(res.body)
23
+
24
+ positives = adjectives[0]['positives']
25
+
26
+ words = @phrase.split(/\W+/)
27
+
28
+ array = Array.new
29
+ output = Hash.new
30
+
31
+ words.each do
32
+ |ws| ws.scan(/[\w']+/) do
33
+ |w| if positives.key?(w)
34
+ output[ws] = positives[w]
35
+ array.push(output)
36
+ end
37
+ end
38
+ end
39
+
40
+ @sentiment = FindMedian.value(output.values)
41
+ #puts positivity_sentiment
42
+
43
+ end
44
+
45
+ def sentiment_value
46
+ @sentiment
47
+ end
48
+
49
+ end
50
+
51
+
52
+
53
+ #string = "This product is good"
54
+
55
+ #weight = FindPositivity.instance
56
+ #weight.sentiment(string)
57
+ #puts weight.sentiment_value
58
+
@@ -0,0 +1,11 @@
1
+ class Task
2
+ attr_reader :name
3
+
4
+ def initialize(name)
5
+ @name = name
6
+ end
7
+
8
+ def sentiment_value
9
+ 0.0
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'composite_pattern'
2
+ require_relative 'positivity'
3
+ require_relative 'negativity'
4
+ require_relative 'negated'
5
+
6
+
7
+
8
+ class TotalSentiment < CompositeTask
9
+
10
+ def initialize(phrase)
11
+ super ('Find total sentiment')
12
+
13
+ positive = FindPositivity.instance
14
+ negative = FindNegativity.instance
15
+ negated = FindNegation.instance
16
+ positive.sentiment(phrase)
17
+ negative.sentiment(phrase)
18
+ #negated.sentiment(phrase)
19
+
20
+ self << positive
21
+ self << negative
22
+ #self << negated
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ {
2
+ "results": [{
3
+ "positives": {
4
+ "good": 3,
5
+ "terrific": 4,
6
+ "brilliant": 4,
7
+ "awesome": 4,
8
+ "perfect": 4,
9
+ "amazing": 4,
10
+ "tasty": 3,
11
+ "yummy": 3,
12
+ "great": 4,
13
+ "best": 5,
14
+ "marvellous": 5,
15
+ "crazy": 5,
16
+ "wonderful": 4,
17
+ "commendable": 5
18
+ },
19
+ "negatives": {
20
+ "bad": 3,
21
+ "worst": 4,
22
+ "ridiculous": 4,
23
+ "pathetic": 5,
24
+ "poor": 4,
25
+ "hopeless": 4,
26
+ "useless": 4,
27
+ "late": 4,
28
+ "rotten": 5,
29
+ "spoilt": 5,
30
+ "tasteless": 4,
31
+ "flavorless": 4
32
+
33
+ }
34
+ }]
35
+
36
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tsentiment
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Surya Kumar Govindan
@@ -16,7 +16,16 @@ email: suryajapan@gmail.com
16
16
  executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
- files: []
19
+ files:
20
+ - lib/composite_pattern.rb
21
+ - lib/findSentiment.rb
22
+ - lib/median.rb
23
+ - lib/negated.rb
24
+ - lib/negativity.rb
25
+ - lib/positivity.rb
26
+ - lib/task.rb
27
+ - lib/total_sentiment.rb
28
+ - source/adjectives.json
20
29
  homepage: http://rubygems.org/gems/tsentiment
21
30
  licenses: []
22
31
  metadata: {}