tsentiment 2.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: {}