tsentiment 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- metadata +2 -11
- data/lib/composite_pattern.rb +0 -35
- data/lib/findSentiment.rb +0 -118
- data/lib/median.rb +0 -19
- data/lib/negated.rb +0 -137
- data/lib/negativity.rb +0 -59
- data/lib/positivity.rb +0 -58
- data/lib/task.rb +0 -11
- data/lib/total_sentiment.rb +0 -24
- data/source/adjectives.json +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 298293e735de9476582ab0ea0f99fa137ca9c1c4ef274b43e4c3a816406a0b62
|
4
|
+
data.tar.gz: 3586edcb2bdacbc505b5c6b45b79940fd1f8cf01650c38596466f1ea6317f7f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa425cb2c1e1e53ba258374b0302de687bbdf0cd99d2f6568722297ab976f8f09701623fd45d08fb684d4ea6c63daaa89322d064e8086009f809a6386030fa79
|
7
|
+
data.tar.gz: d905dcd3134d287417c4123c70fc2c90bd4abb9ee53575189a30e7447ce09d163cdcb02b41db0c3a315e312bbdc4277dbe14189512328430af60144a7a8dd34a
|
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:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Surya Kumar Govindan
|
@@ -16,16 +16,7 @@ email: suryajapan@gmail.com
|
|
16
16
|
executables: []
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_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
|
19
|
+
files: []
|
29
20
|
homepage: http://rubygems.org/gems/tsentiment
|
30
21
|
licenses: []
|
31
22
|
metadata: {}
|
data/lib/composite_pattern.rb
DELETED
@@ -1,35 +0,0 @@
|
|
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
|
data/lib/findSentiment.rb
DELETED
@@ -1,118 +0,0 @@
|
|
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
|
-
|
111
|
-
string[0] = 'This product is not bad, it is good'
|
112
|
-
#string[1] = 'This product is. This product is good'
|
113
|
-
#string[2] = 'This product is good'
|
114
|
-
#string[3] = 'This is a rotten product'
|
115
|
-
#string[4] = 'This is a goodcp product'
|
116
|
-
|
117
|
-
weight = FindSentiment.value(string, 3)
|
118
|
-
puts weight
|
data/lib/median.rb
DELETED
data/lib/negated.rb
DELETED
@@ -1,137 +0,0 @@
|
|
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
|
-
|
data/lib/negativity.rb
DELETED
@@ -1,59 +0,0 @@
|
|
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
|
-
|
data/lib/positivity.rb
DELETED
@@ -1,58 +0,0 @@
|
|
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
|
-
|
data/lib/task.rb
DELETED
data/lib/total_sentiment.rb
DELETED
@@ -1,24 +0,0 @@
|
|
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
|
data/source/adjectives.json
DELETED
@@ -1,36 +0,0 @@
|
|
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
|
-
}
|