Automated Product Review Sentiment Analyzer for E-Commerce Platforms Go

👤 Sharing: AI
```go
package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"regexp"
	"strings"
)

// SentimentScore maps words to their sentiment score.  Positive scores are good, negative are bad.
type SentimentScore map[string]int

// LoadSentimentDictionary loads the sentiment dictionary from a file.  The file
// should have each word and its score on a new line, separated by a comma, for example:
//   good,1
//   bad,-1
func LoadSentimentDictionary(filename string) (SentimentScore, error) {
	dictionary := make(SentimentScore)

	file, err := os.Open(filename)
	if err != nil {
		return nil, fmt.Errorf("failed to open sentiment dictionary file: %w", err)
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		parts := strings.Split(line, ",")
		if len(parts) != 2 {
			log.Printf("Skipping invalid line in sentiment dictionary: %s\n", line)
			continue // skip line
		}

		word := strings.TrimSpace(strings.ToLower(parts[0])) // normalize to lowercase and remove whitespace
		score := 0
		_, err := fmt.Sscan(parts[1], &score) // convert string to int
		if err != nil {
			log.Printf("Skipping line, couldn't parse score '%s': %s\n", parts[1], line)
			continue // skip line
		}
		dictionary[word] = score
	}

	if err := scanner.Err(); err != nil {
		return nil, fmt.Errorf("error reading sentiment dictionary file: %w", err)
	}

	return dictionary, nil
}

// PreprocessReview cleans and normalizes the review text.
func PreprocessReview(review string) string {
	// Convert to lowercase.
	review = strings.ToLower(review)

	// Remove punctuation using regular expressions.  This is important for accurate sentiment analysis.
	reg, err := regexp.Compile("[^a-zA-Z0-9 ]+") // match everything that is not alpha-numeric or space
	if err != nil {
		log.Fatal(err)
	}
	review = reg.ReplaceAllString(review, "")

	// Remove extra whitespace.
	review = strings.Join(strings.Fields(review), " ")

	return review
}

// AnalyzeSentiment calculates the sentiment score of a review based on the sentiment dictionary.
func AnalyzeSentiment(review string, dictionary SentimentScore) int {
	words := strings.Split(review, " ")
	score := 0
	for _, word := range words {
		if sentiment, ok := dictionary[word]; ok {
			score += sentiment
		}
	}
	return score
}

// ClassifySentiment assigns a sentiment label (Positive, Negative, Neutral) based on the score.
func ClassifySentiment(score int) string {
	if score > 1 { // Tunable threshold
		return "Positive"
	} else if score < -1 { // Tunable threshold
		return "Negative"
	} else {
		return "Neutral"
	}
}

func main() {
	// Load the sentiment dictionary.  A very small example is provided below.
	// You can replace it with a larger, more comprehensive dictionary.
	dictionary, err := LoadSentimentDictionary("sentiment_dictionary.txt")
	if err != nil {
		log.Fatalf("Failed to load sentiment dictionary: %v", err)
	}

	// Example usage:
	reviews := []string{
		"This product is amazing!  I love it so much.",
		"This is terrible. I hate it.",
		"The product is okay. Not great, not bad.",
		"The quality is excellent, and the price is right.",
		"It's broken and useless. What a waste of money!",
	}

	for _, review := range reviews {
		processedReview := PreprocessReview(review)
		sentimentScore := AnalyzeSentiment(processedReview, dictionary)
		sentimentLabel := ClassifySentiment(sentimentScore)

		fmt.Printf("Review: %s\n", review)
		fmt.Printf("Sentiment Score: %d\n", sentimentScore)
		fmt.Printf("Sentiment: %s\n", sentimentLabel)
		fmt.Println("---")
	}

	// Example usage with user input
	reader := bufio.NewReader(os.Stdin)

	fmt.Println("Enter a product review (or type 'exit'):")
	for {
		fmt.Print("> ")
		review, _ := reader.ReadString('\n')
		review = strings.TrimSpace(review) // Remove leading/trailing whitespace and newline

		if review == "exit" {
			break
		}

		processedReview := PreprocessReview(review)
		sentimentScore := AnalyzeSentiment(processedReview, dictionary)
		sentimentLabel := ClassifySentiment(sentimentScore)

		fmt.Printf("Review: %s\n", review)
		fmt.Printf("Sentiment Score: %d\n", sentimentScore)
		fmt.Printf("Sentiment: %s\n", sentimentLabel)
		fmt.Println("---")
	}

	fmt.Println("Exiting...")
}
```

**Explanation:**

1. **`SentimentScore` Type:**
   - Defines a `SentimentScore` as a `map[string]int`.  This map stores words (strings) and their corresponding sentiment scores (integers).  Positive scores indicate positive sentiment, negative scores indicate negative sentiment, and zero (or close to zero) indicates neutral sentiment.

2. **`LoadSentimentDictionary(filename string) (SentimentScore, error)`:**
   - Reads a sentiment dictionary from a file.
   - **Error Handling:** Includes robust error handling for file opening and reading issues.
   - **File Format:**  Expects a comma-separated file where each line contains a word and its sentiment score (e.g., "good,1" or "bad,-1").
   - **Normalization:** Converts words to lowercase using `strings.ToLower()` to ensure case-insensitive matching.  It also trims whitespace to avoid issues caused by leading or trailing spaces.
   - **Scanner:** Uses a `bufio.Scanner` for efficient line-by-line reading.
   - **Integer Conversion:** Uses `fmt.Sscan()` to safely convert the string representation of the sentiment score to an integer.  Handles errors if the score is not a valid integer.
   - **Returns:** Returns the `SentimentScore` map and an error if any occurred.

3. **`PreprocessReview(review string) string`:**
   - Cleans and normalizes the input review text:
     - **Lowercase Conversion:** Converts the entire review to lowercase using `strings.ToLower()`.  This ensures consistent matching against the sentiment dictionary.
     - **Punctuation Removal:** Uses a regular expression (`regexp`) to remove all punctuation characters. This is crucial because punctuation can interfere with accurate sentiment analysis.
     - **Whitespace Normalization:** Uses `strings.Fields()` and `strings.Join()` to remove extra whitespace characters (multiple spaces, leading/trailing spaces, etc.) and reduce the text to single spaces between words.

4. **`AnalyzeSentiment(review string, dictionary SentimentScore) int`:**
   - Calculates the overall sentiment score of the review:
     - **Splits into Words:** Splits the preprocessed review into individual words using `strings.Split(" ")`.
     - **Iterates and Scores:** Iterates through each word in the review.
     - **Looks Up Sentiment:** For each word, it checks if the word exists as a key in the `SentimentScore` dictionary.  If the word is found (`ok` is true), it adds the corresponding sentiment score to the overall `score`.
     - **Returns Total Score:** Returns the final calculated sentiment score.

5. **`ClassifySentiment(score int) string`:**
   - Assigns a sentiment label (Positive, Negative, or Neutral) based on the numerical sentiment score.
   - **Thresholds:** Uses thresholds (`score > 1` and `score < -1`) to determine the sentiment category.  These thresholds can be adjusted to fine-tune the classification. A score close to zero is considered neutral.

6. **`main()` Function:**
   - **Loads Dictionary:** Calls `LoadSentimentDictionary()` to load the sentiment dictionary from the "sentiment_dictionary.txt" file.  Includes error handling in case the file cannot be loaded.
   - **Example Usage:** Demonstrates how to use the functions with a few example reviews.  It preprocesses the review, analyzes the sentiment, and classifies the sentiment.  The results are printed to the console.
   - **User Input Loop:**  Provides an interactive loop that allows the user to enter their own product reviews.  The program then analyzes and classifies the sentiment of the user's input.
   - **Exit Condition:**  The user can type "exit" to terminate the program.

**How to Run:**

1.  **Save the code:** Save the Go code as a file (e.g., `sentiment_analyzer.go`).
2.  **Create a sentiment dictionary:**  Create a file named `sentiment_dictionary.txt` in the same directory.  This file should contain words and their corresponding sentiment scores, one word/score pair per line, separated by a comma.  For example:

```
good,2
amazing,3
excellent,2
great,1
okay,0
bad,-2
terrible,-3
awful,-2
horrible,-3
disappointing,-1
broken,-2
useless,-3
hate,-3
love,3
fantastic,3
fine,1
decent,1
mediocre,0
```

3.  **Build and run:** Open a terminal or command prompt, navigate to the directory where you saved the files, and run the following commands:

```bash
go build sentiment_analyzer.go
./sentiment_analyzer
```

The program will then output the sentiment analysis results for the example reviews and prompt you to enter your own reviews.

**Key Improvements and Considerations:**

*   **Error Handling:** The code includes robust error handling for file operations and integer conversions. This makes the program more reliable.
*   **Normalization:** Normalizing the text by converting to lowercase and removing punctuation is essential for accurate sentiment analysis.
*   **Sentiment Dictionary:** The accuracy of the sentiment analysis heavily depends on the quality and size of the sentiment dictionary.  Using a more comprehensive dictionary will significantly improve the results.  Consider using a pre-built sentiment lexicon like VADER or AFINN if you need higher accuracy.
*   **Regular Expressions:** The regular expression `[^a-zA-Z0-9 ]+` effectively removes all non-alphanumeric characters and spaces.
*   **User Input:**  The program now accepts user input and analyzes the sentiment of the provided reviews.
*   **Tunable Thresholds:** The thresholds used in `ClassifySentiment` (1 and -1) can be adjusted to change the sensitivity of the classification.
*   **Stop Word Removal:** For more advanced analysis, consider removing stop words (common words like "the," "a," "is," etc.) from the review text, as they often don't contribute much to the sentiment.  You would need to create a stop word list and filter them out during the preprocessing stage.
*   **Stemming/Lemmatization:** Techniques like stemming (reducing words to their root form, e.g., "running" -> "run") or lemmatization (finding the dictionary form of a word) can further improve accuracy by grouping related words together.
*   **N-grams:**  Instead of just analyzing individual words, you could consider analyzing n-grams (sequences of n words). This can capture sentiment conveyed by phrases (e.g., "not good").
*   **Machine Learning:** For highly accurate sentiment analysis, consider using machine learning techniques like Naive Bayes, Support Vector Machines (SVM), or deep learning models like transformers.  These models can be trained on large datasets of labeled reviews to learn complex patterns and relationships.  However, this requires more data and more complex code.
*   **VADER or AFINN Lexicons:**  These are readily available sentiment lexicons that provide sentiment scores for a large number of words and phrases.  Using these lexicons can be much more efficient than creating your own from scratch.  You'd need to find Go libraries that support them or implement the loading logic yourself.
👁️ Viewed: 5

Comments