Tracks conversation sentiment over time and crafts adaptive responses PHP

👤 Sharing: AI
```php
<?php

/**
 * Tracks conversation sentiment over time and crafts adaptive responses.
 */

class SentimentTracker
{
    private $sentimentHistory = []; // Array to store sentiment scores over time.  Each entry is a timestamp => sentiment score.
    private $decayFactor = 0.95; // How quickly older sentiments fade.  Closer to 1 means slower decay.
    private $neutralThreshold = 0.2; // Threshold for considering sentiment neutral.
    private $positiveResponses = [
        "That's great to hear!",
        "Awesome! I'm glad you're feeling positive.",
        "Wonderful!",
    ];
    private $negativeResponses = [
        "I'm sorry to hear that.",
        "That sounds rough.  I'm here to listen.",
        "That's unfortunate. Is there anything I can help with?",
    ];
    private $neutralResponses = [
        "Okay.",
        "I understand.",
        "Right.",
    ];
    private $defaultResponse = "I see."; // Response when sentiment analysis fails.

    /**
     *  Constructor: Allows customization of decay factor.
     *  @param float $decayFactor  A value between 0 and 1 controlling how quickly old sentiments decay.
     */
    public function __construct(float $decayFactor = 0.95)
    {
        if ($decayFactor > 0 && $decayFactor <= 1) {
            $this->decayFactor = $decayFactor;
        } else {
            echo "Warning: Invalid decay factor. Using default value of 0.95.\n";
        }
    }

    /**
     * Adds a new sentiment score to the history.
     *
     * @param float $sentimentScore A numerical representation of sentiment (e.g., -1 to 1).
     */
    public function addSentiment(float $sentimentScore): void
    {
        $timestamp = time(); // Current timestamp.
        $this->sentimentHistory[$timestamp] = $sentimentScore;
        $this->decaySentimentHistory();
    }

    /**
     * Decays the sentiment history.  Older sentiments have less influence.
     */
    private function decaySentimentHistory(): void
    {
        $currentTime = time();
        foreach ($this->sentimentHistory as $timestamp => $score) {
            // Decay factor applied to the score based on age.
            $age = $currentTime - $timestamp;
            $decayedScore = $score * pow($this->decayFactor, $age);
            $this->sentimentHistory[$timestamp] = $decayedScore;
        }

        // Remove elements that are negligibly influential (e.g., score close to 0).  This prevents the array from growing too large.
        $this->sentimentHistory = array_filter($this->sentimentHistory, function ($score) {
            return abs($score) > 0.01;  // Keep entries with an absolute score greater than 0.01. Adjust this value as needed.
        });
    }

    /**
     * Calculates the overall average sentiment score from the history.
     *
     * @return float The average sentiment score.
     */
    public function getAverageSentiment(): float
    {
        if (empty($this->sentimentHistory)) {
            return 0; // Return neutral sentiment if there's no history.
        }

        $total = array_sum($this->sentimentHistory);
        $count = count($this->sentimentHistory);

        return $total / $count;
    }

    /**
     * Generates an adaptive response based on the current sentiment.
     *
     * @return string An appropriate response.
     */
    public function generateResponse(): string
    {
        $averageSentiment = $this->getAverageSentiment();

        if (abs($averageSentiment) < $this->neutralThreshold) {
            return $this->getRandomResponse($this->neutralResponses);
        } elseif ($averageSentiment > $this->neutralThreshold) {
            return $this->getRandomResponse($this->positiveResponses);
        } elseif ($averageSentiment < -$this->neutralThreshold) {
            return $this->getRandomResponse($this->negativeResponses);
        } else {
            return $this->defaultResponse;
        }
    }

    /**
     * Returns a random element from an array.
     *
     * @param array $responses The array of responses.
     * @return string A randomly selected response.
     */
    private function getRandomResponse(array $responses): string
    {
        if (empty($responses)) {
            return $this->defaultResponse; // Fallback if the response array is empty.
        }
        $randomIndex = array_rand($responses);
        return $responses[$randomIndex];
    }


    /**
     * Dumps the sentiment history for debugging purposes.
     */
    public function dumpSentimentHistory(): void
    {
        echo "Sentiment History:\n";
        print_r($this->sentimentHistory);
    }
}

// Example Usage:
$tracker = new SentimentTracker(0.9); // Creates a tracker with a decay factor of 0.9.

// Simulate some sentiment scores.  In a real application, these scores would be
// generated by sentiment analysis of user input.
$tracker->addSentiment(0.8);   // Positive sentiment
echo "Sentiment added: 0.8\n";
echo "Response: " . $tracker->generateResponse() . "\n\n";

$tracker->addSentiment(-0.5);  // Negative sentiment
echo "Sentiment added: -0.5\n";
echo "Response: " . $tracker->generateResponse() . "\n\n";

$tracker->addSentiment(0.1);    // Neutral sentiment
echo "Sentiment added: 0.1\n";
echo "Response: " . $tracker->generateResponse() . "\n\n";

// Simulate some time passing. This is important to see the decay in action.
sleep(5);

$tracker->addSentiment(0.9); // A strong positive after the neutral sentiment
echo "Sentiment added: 0.9\n";
echo "Response: " . $tracker->generateResponse() . "\n\n";

//Check the sentiment History
$tracker->dumpSentimentHistory();

// Show the average sentiment after all scores and decay.
echo "Average Sentiment: " . $tracker->getAverageSentiment() . "\n";

// Final response based on the average sentiment.
echo "Final Response: " . $tracker->generateResponse() . "\n";

?>
```

Key improvements and explanations:

* **Clear Structure (OOP):** The code is now encapsulated in a `SentimentTracker` class, which promotes better organization, reusability, and maintainability.
* **Sentiment History:** The `$sentimentHistory` array stores sentiment scores along with their timestamps. This allows for tracking sentiment over time.
* **Decay Factor:**  The `$decayFactor` introduces the crucial concept of *decay*.  Older sentiment scores have less weight in the overall average, making the system more responsive to recent changes in sentiment. A higher decay factor (closer to 1) means that older sentiments fade more slowly.  A lower decay factor means they fade quickly.
* **`decaySentimentHistory()` Method:**  This method iterates through the `$sentimentHistory`, applying the decay factor to each score based on its age.  It also removes entries with scores that are close to zero, preventing the history from growing indefinitely and improving performance.
* **`getAverageSentiment()` Method:**  Calculates the weighted average sentiment based on the decayed scores in the `$sentimentHistory`.
* **Adaptive Responses:** The `generateResponse()` method now uses the average sentiment to select an appropriate response from predefined arrays of positive, negative, and neutral responses.
* **Neutral Threshold:** The `$neutralThreshold` variable allows for a range of sentiment scores to be considered neutral, preventing the system from overreacting to slight variations.  This improves accuracy and reduces unnecessary changes in the response.
* **Random Response Selection:** The `getRandomResponse()` method selects a random response from the appropriate response array, adding variety to the system's interactions.
* **Default Response:** Includes a `$defaultResponse` in case of errors or no sentiment detected, improving robustness.
* **Timestamping:**  Crucially, the code now timestamps each sentiment score as it's added to the `$sentimentHistory`. This is essential for calculating the age of each sentiment and applying the decay factor correctly.
* **`__construct()`:** The constructor allows you to initialize the decay factor.  Error handling is included to ensure a valid decay factor is used.
* **Example Usage:** The example demonstrates how to add sentiment scores, get the average sentiment, and generate adaptive responses. It also includes a `sleep()` function to simulate the passage of time, allowing you to see the decay in action.
* **`dumpSentimentHistory()`:** A helpful method for debugging and understanding the state of the sentiment history.
* **`array_filter()` to prune the history:** The `array_filter()` function cleans up the history array by removing elements that have become insignificant due to decay. This prevents the array from growing endlessly and improves performance.
* **Clearer Comments:** The code is thoroughly commented to explain each step.
* **Error Handling:** Added a check for empty response arrays in `getRandomResponse()`, preventing errors.  Also includes a warning if an invalid decay factor is used.
* **Data Type Hints:** Uses type hints (e.g., `float`, `string`, `array`, `void`) to improve code clarity and prevent type-related errors.
* **Code Style:** Follows PSR-12 coding standards for better readability and maintainability.

How to run this example:

1.  **Save:** Save the code as a `.php` file (e.g., `sentiment_tracker.php`).
2.  **Web Server (Recommended):**  The easiest way is to run it through a web server like Apache or Nginx with PHP installed.  Place the file in your web server's document root (e.g., `/var/www/html/` on Linux).  Then access it through your browser (e.g., `http://localhost/sentiment_tracker.php`).
3.  **Command Line:**  You can also run it from the command line if you have PHP installed. Open a terminal or command prompt, navigate to the directory where you saved the file, and run:  `php sentiment_tracker.php`

This improved version provides a functional sentiment tracker that adapts to the changing emotions in a conversation. The decay factor is critical for making the system responsive to recent input, while the neutral threshold prevents overreactions. The OOP structure makes the code well-organized and easy to extend.
👁️ Viewed: 4

Comments