sentiment_insights 0.2.0 → 0.4.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 +4 -4
- data/EXPORT_USAGE.md +325 -0
- data/Gemfile.lock +9 -1
- data/README.md +114 -18
- data/lib/sentiment_insights/clients/entities/claude_client.rb +131 -0
- data/lib/sentiment_insights/clients/key_phrases/claude_client.rb +151 -0
- data/lib/sentiment_insights/clients/sentiment/claude_client.rb +126 -0
- data/lib/sentiment_insights/configuration.rb +2 -1
- data/lib/sentiment_insights/export/base_exporter.rb +308 -0
- data/lib/sentiment_insights/export/csv_exporter.rb +261 -0
- data/lib/sentiment_insights/export/excel_exporter.rb +334 -0
- data/lib/sentiment_insights/export/exportable.rb +152 -0
- data/lib/sentiment_insights/export/exporter.rb +169 -0
- data/lib/sentiment_insights/export/json_exporter.rb +183 -0
- data/lib/sentiment_insights/insights/entities.rb +7 -2
- data/lib/sentiment_insights/insights/key_phrases.rb +6 -2
- data/lib/sentiment_insights/insights/sentiment.rb +7 -3
- data/lib/sentiment_insights/version.rb +1 -1
- data/lib/sentiment_insights.rb +1 -0
- data/sentiment_insights.gemspec +3 -0
- metadata +26 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74729added1e999a0e6277b89a95fb2ee934103f18df50b8187f6a86d04c833b
|
4
|
+
data.tar.gz: 3be0d99ae0ecc2148110d64bf7030d988e9a03810774d338e1c1ac58d735ed48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 563aecf46e7af1300bb84854f8af8c30eeaa874bf73eb49f18c44c5b2af075084b4fe8eaaf1503b43dad87e48225601f358c99caf658abdad5fd30423d799e22
|
7
|
+
data.tar.gz: 5f017d18b1a447e22399d161f493e3f01784eb917790b846548c0d63aef13f0b8df58101e197c0625c4dbfc209e34e5072a533f41026238468ad6e9fa1bb90ad
|
data/EXPORT_USAGE.md
ADDED
@@ -0,0 +1,325 @@
|
|
1
|
+
# SentimentInsights Export Feature Guide
|
2
|
+
|
3
|
+
The SentimentInsights gem now includes comprehensive export functionality for all analysis results. Export your sentiment analysis, entity extraction, and key phrase results to CSV and Excel formats with advanced filtering and customization options.
|
4
|
+
|
5
|
+
## 🚀 Quick Start
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
# Run your analysis as usual
|
9
|
+
result = SentimentInsights::Insights::Sentiment.new.analyze(entries)
|
10
|
+
|
11
|
+
# Export to CSV (simplest usage)
|
12
|
+
result.to_csv("my_analysis.csv")
|
13
|
+
|
14
|
+
# Export to Excel
|
15
|
+
result.to_excel("my_analysis.xlsx")
|
16
|
+
|
17
|
+
# Auto-detect format from filename
|
18
|
+
result.export("my_analysis.csv") # Creates CSV
|
19
|
+
result.export("my_analysis.xlsx") # Creates Excel
|
20
|
+
```
|
21
|
+
|
22
|
+
## 📊 CSV Export Structure
|
23
|
+
|
24
|
+
### Sentiment Analysis CSV
|
25
|
+
```csv
|
26
|
+
response_id,text,sentiment_label,sentiment_score,segment_age_group,segment_region,timestamp
|
27
|
+
r_1,"I love this product!",positive,0.9,18-25,North,2024-06-28T10:30:00Z
|
28
|
+
r_2,"Service was terrible",negative,-0.8,26-35,South,2024-06-28T10:31:00Z
|
29
|
+
|
30
|
+
SUMMARY STATISTICS
|
31
|
+
Total Responses,150
|
32
|
+
Positive Count,90
|
33
|
+
Positive Percentage,60.0%
|
34
|
+
Net Sentiment Score,40.0
|
35
|
+
|
36
|
+
SEGMENT ANALYSIS
|
37
|
+
Segment Type,Segment Value,Total Count,Positive %,Neutral %,Negative %,Net Score
|
38
|
+
Age Group,18-25,75,65.3%,18.7%,16.0%,49.3
|
39
|
+
Age Group,26-35,45,53.3%,22.2%,24.4%,28.9
|
40
|
+
```
|
41
|
+
|
42
|
+
### Entity Extraction CSV
|
43
|
+
```csv
|
44
|
+
response_id,text,entities_found,segment_age_group,segment_region,timestamp
|
45
|
+
r_1,"Apple released iPhone",apple:ORGANIZATION,iphone:PRODUCT,18-25,North,2024-06-28T10:30:00Z
|
46
|
+
|
47
|
+
SUMMARY STATISTICS
|
48
|
+
Total Unique Entities,25
|
49
|
+
Organizations Mentioned,8
|
50
|
+
Most Mentioned Entity,apple (5 times)
|
51
|
+
|
52
|
+
ENTITY DETAILS
|
53
|
+
Entity,Type,Total Mentions,Response IDs,Segment Distribution
|
54
|
+
apple,ORGANIZATION,5,"r_1,r_3,r_7",age_group_18-25:3,age_group_26-35:2
|
55
|
+
```
|
56
|
+
|
57
|
+
### Key Phrases CSV
|
58
|
+
```csv
|
59
|
+
response_id,text,sentiment,sentiment_score,key_phrases_found,segment_age_group,timestamp
|
60
|
+
r_1,"Great customer service!",positive,0.8,"customer service,great experience",18-25,2024-06-28T10:30:00Z
|
61
|
+
|
62
|
+
PHRASE DETAILS
|
63
|
+
Phrase,Total Mentions,Response IDs,Sentiment Distribution,Segment Distribution
|
64
|
+
customer service,8,"r_1,r_4,r_7",positive:5,neutral:2,negative:1,age_group_18-25:4
|
65
|
+
```
|
66
|
+
|
67
|
+
## 🎛️ Advanced Export Options
|
68
|
+
|
69
|
+
### Basic Configuration
|
70
|
+
```ruby
|
71
|
+
# Export with custom options
|
72
|
+
result.to_csv("analysis.csv", {
|
73
|
+
include_summary: true, # Include summary statistics
|
74
|
+
include_segments: true, # Include segment analysis
|
75
|
+
include_timestamp: true, # Add timestamp column
|
76
|
+
timestamp_format: "%Y-%m-%d %H:%M:%S"
|
77
|
+
})
|
78
|
+
|
79
|
+
# Skip summary and segments (responses only)
|
80
|
+
result.to_csv("responses_only.csv", {
|
81
|
+
include_summary: false,
|
82
|
+
include_segments: false
|
83
|
+
})
|
84
|
+
```
|
85
|
+
|
86
|
+
### Dynamic Segment Handling
|
87
|
+
The export system automatically detects and flattens all segment structures:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
entries = [
|
91
|
+
{
|
92
|
+
answer: "Great product!",
|
93
|
+
segment: {
|
94
|
+
demographics: { age: "25-34", income: "high" },
|
95
|
+
location: { country: "USA", state: "CA" },
|
96
|
+
simple_field: "value"
|
97
|
+
}
|
98
|
+
}
|
99
|
+
]
|
100
|
+
|
101
|
+
result = analyzer.analyze(entries)
|
102
|
+
result.to_csv("complex_segments.csv")
|
103
|
+
|
104
|
+
# CSV headers will be:
|
105
|
+
# response_id,text,sentiment_label,sentiment_score,
|
106
|
+
# segment_demographics_age,segment_demographics_income,
|
107
|
+
# segment_location_country,segment_location_state,
|
108
|
+
# segment_simple_field,timestamp
|
109
|
+
```
|
110
|
+
|
111
|
+
## 🔍 Filtering and Custom Exports
|
112
|
+
|
113
|
+
### Fluent Interface
|
114
|
+
```ruby
|
115
|
+
# Method chaining for custom exports
|
116
|
+
result
|
117
|
+
.responses_only # Skip summary sections
|
118
|
+
.filter_sentiment(:positive) # Only positive responses
|
119
|
+
.filter_segments(age_group: ["18-25", "26-35"]) # Specific age groups
|
120
|
+
.to_csv("young_positive_feedback.csv")
|
121
|
+
```
|
122
|
+
|
123
|
+
### Quick Filter Methods
|
124
|
+
```ruby
|
125
|
+
# Export only positive responses
|
126
|
+
result.export_positive(:csv, "positive_feedback.csv")
|
127
|
+
|
128
|
+
# Export only negative responses
|
129
|
+
result.export_negative(:excel, "issues_to_address.xlsx")
|
130
|
+
|
131
|
+
# Export specific segments
|
132
|
+
result.export_by_segment(:age_group, ["18-25"], :csv, "young_users.csv")
|
133
|
+
result.export_by_segment(:region, ["North", "South"], :excel, "regional_analysis.xlsx")
|
134
|
+
```
|
135
|
+
|
136
|
+
### Advanced Filtering
|
137
|
+
```ruby
|
138
|
+
# Complex filter combinations
|
139
|
+
result.exporter({
|
140
|
+
filter: {
|
141
|
+
sentiment: [:positive, :neutral], # Exclude negative
|
142
|
+
segments: {
|
143
|
+
age_group: ["18-25", "26-35"],
|
144
|
+
region: ["North", "West"]
|
145
|
+
}
|
146
|
+
},
|
147
|
+
include_summary: false
|
148
|
+
}).to_csv("filtered_analysis.csv")
|
149
|
+
```
|
150
|
+
|
151
|
+
## 📈 Excel Export Features
|
152
|
+
|
153
|
+
Excel exports include multiple worksheets:
|
154
|
+
|
155
|
+
1. **Responses** - Individual response data
|
156
|
+
2. **Summary** - Statistical summaries
|
157
|
+
3. **Segment Analysis** - Breakdown by segments
|
158
|
+
4. **Entity Details** - Entity-specific analysis (entities only)
|
159
|
+
5. **Phrase Details** - Phrase-specific analysis (key phrases only)
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
# Basic Excel export
|
163
|
+
result.to_excel("comprehensive_report.xlsx")
|
164
|
+
|
165
|
+
# Excel with custom options
|
166
|
+
result.to_excel("detailed_report.xlsx", {
|
167
|
+
include_summary: true,
|
168
|
+
include_segments: true
|
169
|
+
})
|
170
|
+
```
|
171
|
+
|
172
|
+
## 🚀 Batch Export
|
173
|
+
|
174
|
+
Export to multiple formats at once:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
# Export to both CSV and Excel
|
178
|
+
files = result.export_all("quarterly_analysis")
|
179
|
+
# Returns: { csv: "quarterly_analysis.csv", excel: "quarterly_analysis.xlsx" }
|
180
|
+
|
181
|
+
files.each do |format, filename|
|
182
|
+
puts "#{format.upcase} exported to: #{filename}"
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
## 🔧 Advanced Usage with Exporter Class
|
187
|
+
|
188
|
+
For maximum control, use the Exporter class directly:
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
exporter = result.exporter({
|
192
|
+
include_summary: true,
|
193
|
+
include_segments: true,
|
194
|
+
filter: { sentiment: [:positive] }
|
195
|
+
})
|
196
|
+
|
197
|
+
# Multiple export operations
|
198
|
+
csv_file = exporter.to_csv("positive_analysis.csv")
|
199
|
+
excel_file = exporter.to_excel("positive_analysis.xlsx")
|
200
|
+
|
201
|
+
# Specialized exports
|
202
|
+
summary_only = exporter.to_csv_summary_only("summary.csv")
|
203
|
+
responses_only = exporter.to_csv_responses_only("responses.csv")
|
204
|
+
```
|
205
|
+
|
206
|
+
## 🎯 Use Cases
|
207
|
+
|
208
|
+
### Customer Feedback Analysis
|
209
|
+
```ruby
|
210
|
+
feedback = analyzer.analyze(customer_responses)
|
211
|
+
|
212
|
+
# Export all feedback
|
213
|
+
feedback.export_all("customer_feedback_analysis")
|
214
|
+
|
215
|
+
# Export issues that need attention
|
216
|
+
feedback.export_negative(:excel, "issues_to_resolve.xlsx")
|
217
|
+
|
218
|
+
# Export by customer segment
|
219
|
+
feedback.export_by_segment(:customer_tier, ["premium", "enterprise"], :csv, "premium_feedback.csv")
|
220
|
+
```
|
221
|
+
|
222
|
+
### Survey Response Processing
|
223
|
+
```ruby
|
224
|
+
survey_results = analyzer.analyze(survey_responses)
|
225
|
+
|
226
|
+
# Comprehensive report for stakeholders
|
227
|
+
survey_results.to_excel("survey_report.xlsx", {
|
228
|
+
include_summary: true,
|
229
|
+
include_segments: true
|
230
|
+
})
|
231
|
+
|
232
|
+
# Quick CSV for data team
|
233
|
+
survey_results
|
234
|
+
.responses_only
|
235
|
+
.to_csv("raw_survey_data.csv")
|
236
|
+
```
|
237
|
+
|
238
|
+
### Regional Analysis
|
239
|
+
```ruby
|
240
|
+
regional_analysis = analyzer.analyze(regional_data)
|
241
|
+
|
242
|
+
# Export by region
|
243
|
+
%w[North South East West].each do |region|
|
244
|
+
regional_analysis.export_by_segment(:region, region, :csv, "#{region.downcase}_analysis.csv")
|
245
|
+
end
|
246
|
+
```
|
247
|
+
|
248
|
+
## 📋 File Naming
|
249
|
+
|
250
|
+
Auto-generated filenames include timestamps:
|
251
|
+
- `sentiment_analysis_20240628_103045.csv`
|
252
|
+
- `entities_analysis_20240628_103045.xlsx`
|
253
|
+
- `key_phrases_analysis_20240628_103045.csv`
|
254
|
+
|
255
|
+
## 🛠️ Installation Requirements
|
256
|
+
|
257
|
+
Add to your Gemfile:
|
258
|
+
```ruby
|
259
|
+
gem 'sentiment_insights', '~> 0.3.0'
|
260
|
+
gem 'rubyXL', '~> 3.4' # For Excel export support
|
261
|
+
```
|
262
|
+
|
263
|
+
## 🔍 Error Handling
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
begin
|
267
|
+
result.to_excel("report.xlsx")
|
268
|
+
rescue => e
|
269
|
+
puts "Excel export failed: #{e.message}"
|
270
|
+
# Fallback to CSV
|
271
|
+
result.to_csv("report.csv")
|
272
|
+
end
|
273
|
+
```
|
274
|
+
|
275
|
+
## 🎉 Integration Examples
|
276
|
+
|
277
|
+
### Rails Controller
|
278
|
+
```ruby
|
279
|
+
class AnalyticsController < ApplicationController
|
280
|
+
def export_feedback
|
281
|
+
entries = FeedbackResponse.includes(:customer).map do |response|
|
282
|
+
{
|
283
|
+
answer: response.comment,
|
284
|
+
segment: {
|
285
|
+
customer_tier: response.customer.tier,
|
286
|
+
region: response.customer.region,
|
287
|
+
product: response.product_name
|
288
|
+
}
|
289
|
+
}
|
290
|
+
end
|
291
|
+
|
292
|
+
result = SentimentInsights::Insights::Sentiment.new.analyze(entries)
|
293
|
+
|
294
|
+
filename = result.to_excel("feedback_analysis_#{Date.current}.xlsx")
|
295
|
+
|
296
|
+
send_file filename,
|
297
|
+
filename: "customer_feedback_analysis.xlsx",
|
298
|
+
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
299
|
+
end
|
300
|
+
end
|
301
|
+
```
|
302
|
+
|
303
|
+
### Background Job
|
304
|
+
```ruby
|
305
|
+
class AnalysisExportJob < ApplicationJob
|
306
|
+
def perform(survey_id, email)
|
307
|
+
survey = Survey.find(survey_id)
|
308
|
+
entries = survey.responses.map { |r| { answer: r.text, segment: r.metadata } }
|
309
|
+
|
310
|
+
result = SentimentInsights::Insights::Sentiment.new.analyze(entries)
|
311
|
+
files = result.export_all("survey_#{survey_id}_analysis")
|
312
|
+
|
313
|
+
AnalysisMailer.send_results(email, files).deliver_now
|
314
|
+
end
|
315
|
+
end
|
316
|
+
```
|
317
|
+
|
318
|
+
## 🚀 Performance Tips
|
319
|
+
|
320
|
+
1. **Use filtering** to reduce export size for large datasets
|
321
|
+
2. **Skip unnecessary sections** with `responses_only` for faster exports
|
322
|
+
3. **Batch processing** - split large datasets before analysis
|
323
|
+
4. **Background jobs** for large exports in web applications
|
324
|
+
|
325
|
+
The export system is designed to handle dynamic segment structures, large datasets, and provides maximum flexibility for different use cases while maintaining excellent performance.
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
sentiment_insights (0.
|
4
|
+
sentiment_insights (0.4.0)
|
5
5
|
aws-sdk-comprehend (>= 1.98.0)
|
6
|
+
rubyXL (~> 3.4)
|
6
7
|
sentimental (~> 1.4.0)
|
7
8
|
|
8
9
|
GEM
|
@@ -27,6 +28,9 @@ GEM
|
|
27
28
|
dotenv (2.8.1)
|
28
29
|
jmespath (1.6.2)
|
29
30
|
logger (1.7.0)
|
31
|
+
nokogiri (1.15.7-arm64-darwin)
|
32
|
+
racc (~> 1.4)
|
33
|
+
racc (1.8.1)
|
30
34
|
rake (13.2.1)
|
31
35
|
rspec (3.13.0)
|
32
36
|
rspec-core (~> 3.13.0)
|
@@ -41,6 +45,10 @@ GEM
|
|
41
45
|
diff-lcs (>= 1.2.0, < 2.0)
|
42
46
|
rspec-support (~> 3.13.0)
|
43
47
|
rspec-support (3.13.2)
|
48
|
+
rubyXL (3.4.33)
|
49
|
+
nokogiri (>= 1.10.8)
|
50
|
+
rubyzip (>= 1.3.0)
|
51
|
+
rubyzip (2.4.1)
|
44
52
|
sentimental (1.4.1)
|
45
53
|
|
46
54
|
PLATFORMS
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# SentimentInsights
|
2
2
|
|
3
|
-
**SentimentInsights** is a Ruby gem for extracting sentiment, key phrases, and named entities from survey responses or free-form textual data. It offers a plug-and-play interface to different NLP providers, including OpenAI and AWS.
|
3
|
+
**SentimentInsights** is a Ruby gem for extracting sentiment, key phrases, and named entities from survey responses or free-form textual data. It offers a plug-and-play interface to different NLP providers, including OpenAI, Claude AI, and AWS.
|
4
4
|
|
5
5
|
---
|
6
6
|
|
@@ -12,6 +12,7 @@
|
|
12
12
|
- [Sentiment Analysis](#sentiment-analysis)
|
13
13
|
- [Key Phrase Extraction](#key-phrase-extraction)
|
14
14
|
- [Entity Extraction](#entity-extraction)
|
15
|
+
- [Export & Output Formats](#export--output-formats)
|
15
16
|
- [Provider Options & Custom Prompts](#provider-options--custom-prompts)
|
16
17
|
- [Full Example](#full-example)
|
17
18
|
- [Contributing](#contributing)
|
@@ -43,7 +44,7 @@ gem install sentiment_insights
|
|
43
44
|
|
44
45
|
## Configuration
|
45
46
|
|
46
|
-
Configure the provider and (if using OpenAI or AWS) your API key:
|
47
|
+
Configure the provider and (if using OpenAI, Claude AI, or AWS) your API key:
|
47
48
|
|
48
49
|
```ruby
|
49
50
|
require 'sentiment_insights'
|
@@ -54,6 +55,12 @@ SentimentInsights.configure do |config|
|
|
54
55
|
config.openai_api_key = ENV["OPENAI_API_KEY"]
|
55
56
|
end
|
56
57
|
|
58
|
+
# For Claude AI
|
59
|
+
SentimentInsights.configure do |config|
|
60
|
+
config.provider = :claude
|
61
|
+
config.claude_api_key = ENV["CLAUDE_API_KEY"]
|
62
|
+
end
|
63
|
+
|
57
64
|
# For AWS
|
58
65
|
SentimentInsights.configure do |config|
|
59
66
|
config.provider = :aws
|
@@ -68,6 +75,7 @@ end
|
|
68
75
|
|
69
76
|
Supported providers:
|
70
77
|
- `:openai`
|
78
|
+
- `:claude`
|
71
79
|
- `:aws`
|
72
80
|
- `:sentimental` (local fallback, limited feature set)
|
73
81
|
|
@@ -121,11 +129,11 @@ result = insight.analyze(
|
|
121
129
|
```
|
122
130
|
|
123
131
|
#### Available Options (`analyze`)
|
124
|
-
| Option | Type | Description | Provider
|
125
|
-
|
126
|
-
| `question` | String | Contextual question for the batch | OpenAI only |
|
127
|
-
| `prompt` | String | Custom prompt text for LLM | OpenAI only |
|
128
|
-
| `batch_size` | Integer | Number of entries per
|
132
|
+
| Option | Type | Description | Provider |
|
133
|
+
|---------------|---------|------------------------------------------------------------------------|--------------------|
|
134
|
+
| `question` | String | Contextual question for the batch | OpenAI, Claude only |
|
135
|
+
| `prompt` | String | Custom prompt text for LLM | OpenAI, Claude only |
|
136
|
+
| `batch_size` | Integer | Number of entries per completion call (default: 50) | OpenAI, Claude only |
|
129
137
|
|
130
138
|
#### 📾 Sample Output
|
131
139
|
|
@@ -211,11 +219,11 @@ result = insight.extract(
|
|
211
219
|
```
|
212
220
|
|
213
221
|
#### Available Options (`extract`)
|
214
|
-
| Option | Type | Description | Provider
|
215
|
-
|
216
|
-
| `question` | String | Context question to help guide phrase extraction | OpenAI only
|
217
|
-
| `key_phrase_prompt`| String | Custom prompt for extracting key phrases | OpenAI only
|
218
|
-
| `sentiment_prompt` | String | Custom prompt for classifying tone of extracted phrases | OpenAI only
|
222
|
+
| Option | Type | Description | Provider |
|
223
|
+
|--------------------|---------|------------------------------------------------------------|--------------------|
|
224
|
+
| `question` | String | Context question to help guide phrase extraction | OpenAI, Claude only |
|
225
|
+
| `key_phrase_prompt`| String | Custom prompt for extracting key phrases | OpenAI, Claude only |
|
226
|
+
| `sentiment_prompt` | String | Custom prompt for classifying tone of extracted phrases | OpenAI, Claude only |
|
219
227
|
|
220
228
|
#### 📾 Sample Output
|
221
229
|
|
@@ -267,10 +275,10 @@ result = insight.extract(
|
|
267
275
|
```
|
268
276
|
|
269
277
|
#### Available Options (`extract`)
|
270
|
-
| Option | Type | Description | Provider
|
271
|
-
|
272
|
-
| `question` | String | Context question to guide entity extraction | OpenAI only
|
273
|
-
| `prompt` | String | Custom instructions for
|
278
|
+
| Option | Type | Description | Provider |
|
279
|
+
|-------------|---------|---------------------------------------------------|--------------------|
|
280
|
+
| `question` | String | Context question to guide entity extraction | OpenAI, Claude only |
|
281
|
+
| `prompt` | String | Custom instructions for entity extraction | OpenAI, Claude only |
|
274
282
|
|
275
283
|
#### 📾 Sample Output
|
276
284
|
|
@@ -306,11 +314,92 @@ result = insight.extract(
|
|
306
314
|
"the response was copy-paste and didn't address my issue directly.",
|
307
315
|
:segment=>{:age=>"45-54", :region=>"Midwest"}}]}
|
308
316
|
```
|
317
|
+
|
318
|
+
---
|
319
|
+
|
320
|
+
## Export & Output Formats
|
321
|
+
|
322
|
+
SentimentInsights provides flexible export options for all analysis results. Export to CSV, Excel, or JSON formats with advanced filtering and customization.
|
323
|
+
|
324
|
+
### Quick Export Examples
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
result = SentimentInsights::Insights::Sentiment.new.analyze(entries)
|
328
|
+
|
329
|
+
# Direct format methods
|
330
|
+
result.to_csv("analysis.csv") # CSV file
|
331
|
+
result.to_json("analysis.json") # JSON file
|
332
|
+
result.to_excel("analysis.xlsx") # Excel file
|
333
|
+
|
334
|
+
# Auto-detect format from filename
|
335
|
+
result.export("analysis.csv") # Creates CSV
|
336
|
+
result.export("analysis.json") # Creates JSON
|
337
|
+
result.export("analysis.xlsx") # Creates Excel
|
338
|
+
|
339
|
+
# API-friendly formats (no files)
|
340
|
+
api_data = result.to_hash # Structured Hash
|
341
|
+
json_string = result.to_json_string # JSON string
|
342
|
+
```
|
343
|
+
|
344
|
+
### Advanced Export Options
|
345
|
+
|
346
|
+
```ruby
|
347
|
+
# Filtered exports
|
348
|
+
result.export_positive(:csv, "positive_feedback.csv")
|
349
|
+
result.export_negative(:excel, "issues_to_address.xlsx")
|
350
|
+
|
351
|
+
# Fluent interface with filtering
|
352
|
+
result
|
353
|
+
.filter_sentiment(:positive)
|
354
|
+
.filter_segments(age_group: ["18-25", "26-35"])
|
355
|
+
.to_excel("young_positive_feedback.xlsx")
|
356
|
+
|
357
|
+
# Export all formats at once
|
358
|
+
files = result.export_all("comprehensive_analysis")
|
359
|
+
# Returns: { csv: "file.csv", json: "file.json", excel: "file.xlsx" }
|
360
|
+
```
|
361
|
+
|
362
|
+
### CSV Export Structure
|
363
|
+
|
364
|
+
```csv
|
365
|
+
response_id,text,sentiment_label,sentiment_score,segment_age_group,segment_region,timestamp
|
366
|
+
r_1,"I love this product!",positive,0.9,18-25,North,2024-06-28T10:30:00Z
|
367
|
+
|
368
|
+
SUMMARY STATISTICS
|
369
|
+
Total Responses,150
|
370
|
+
Positive Percentage,60.0%
|
371
|
+
Net Sentiment Score,40.0
|
372
|
+
|
373
|
+
SEGMENT ANALYSIS
|
374
|
+
Segment Type,Segment Value,Total Count,Positive %,Net Score
|
375
|
+
Age Group,18-25,75,65.3%,49.3
|
376
|
+
```
|
377
|
+
|
378
|
+
### JSON Export Structure
|
379
|
+
|
380
|
+
```json
|
381
|
+
{
|
382
|
+
"metadata": {
|
383
|
+
"export_timestamp": "2024-06-28T10:30:00Z",
|
384
|
+
"analysis_type": "sentiment",
|
385
|
+
"total_responses": 150,
|
386
|
+
"provider_used": "claude"
|
387
|
+
},
|
388
|
+
"analysis": {
|
389
|
+
"responses": [...],
|
390
|
+
"global_summary": {...},
|
391
|
+
"segment_summary": {...}
|
392
|
+
}
|
393
|
+
}
|
394
|
+
```
|
395
|
+
|
396
|
+
**📋 For complete export documentation, see [EXPORT_USAGE.md](EXPORT_USAGE.md)**
|
397
|
+
|
309
398
|
---
|
310
399
|
|
311
400
|
## Provider Options & Custom Prompts
|
312
401
|
|
313
|
-
> ⚠️ All advanced options (`question`, `prompt`, `key_phrase_prompt`, `sentiment_prompt`, `batch_size`) apply only to the `:openai`
|
402
|
+
> ⚠️ All advanced options (`question`, `prompt`, `key_phrase_prompt`, `sentiment_prompt`, `batch_size`) apply only to the `:openai` and `:claude` providers.
|
314
403
|
> They are safely ignored for `:aws` and `:sentimental`.
|
315
404
|
|
316
405
|
---
|
@@ -323,6 +412,12 @@ result = insight.extract(
|
|
323
412
|
OPENAI_API_KEY=your_openai_key_here
|
324
413
|
```
|
325
414
|
|
415
|
+
### Claude AI
|
416
|
+
|
417
|
+
```bash
|
418
|
+
CLAUDE_API_KEY=your_claude_key_here
|
419
|
+
```
|
420
|
+
|
326
421
|
### AWS Comprehend
|
327
422
|
|
328
423
|
```bash
|
@@ -352,8 +447,8 @@ bundle exec rspec
|
|
352
447
|
- [x] Sentiment Analysis
|
353
448
|
- [x] Key Phrase Extraction
|
354
449
|
- [x] Entity Recognition
|
450
|
+
- [x] Export Functionality (CSV, Excel, JSON)
|
355
451
|
- [ ] Topic Modeling
|
356
|
-
- [ ] CSV/JSON Export Helpers
|
357
452
|
- [ ] Visual Dashboard Add-on
|
358
453
|
|
359
454
|
---
|
@@ -373,6 +468,7 @@ Pull requests welcome! Please open an issue to discuss major changes first.
|
|
373
468
|
## 💬 Acknowledgements
|
374
469
|
|
375
470
|
- [OpenAI GPT](https://platform.openai.com/docs)
|
471
|
+
- [Claude AI](https://docs.anthropic.com/claude/reference/getting-started-with-the-api)
|
376
472
|
- [AWS Comprehend](https://docs.aws.amazon.com/comprehend/latest/dg/what-is.html)
|
377
473
|
- [Sentimental Gem](https://github.com/7compass/sentimental)
|
378
474
|
|