<jupyter_start><jupyter_text>Ray Serve - Sentiment Analysis Example© 2019-2022, Anyscale. All Rights Reserved![Anyscale Academy](../images/AnyscaleAcademyLogo.png)  Sentiment AnalysisWe want to do sentiment analysis by using [VaderSentiment](https://github.com/cjhutto/vaderSentiment) ML framework not supported as an MLflow Flavor. The goal of sentiment analysis is to "gauge the attitude, sentiments, evaluations, attitudes and emotions of a speaker/writer based on the computational treatment of subjectivity in a text."VADER (Valence Aware Dictionary and sEntiment Reasoner) is a lexicon and rule-based sentiment analysis tool that is specifically attuned to sentiments expressed in social media.VADER has a lot of advantages over traditional methods of Sentiment Analysis, including: * It works exceedingly well on social media type text, yet readily generalizes to multiple domains * It doesn’t require any training data but is constructed from a generalizable, valence-based, human-curated gold standard sentiment lexicon * It is fast enough to be used online with streaming data, and * It does not severely suffer from a speed-performance tradeoff.        <img src="https://github.com/dmatrix/olt-mlflow/raw/master/models/images/sentiment_analysis.jpg"         alt="Sentiment Analysis with Vader" height="400 width="600">  [image source](https://medium.com/analytics-vidhya/sentiment-analysis-with-vader-label-the-unlabeled-data-8dd785225166) Need to install the package  VaderSentiment Python PackageYou can read the orignal paper by authors [here](http://comp.social.gatech.edu/papers/icwsm14.vader.hutto.pdf).<jupyter_code>from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
import pandas as pd
from ray import serve<jupyter_output><empty_output><jupyter_text>Define some input texts we going to analyse<jupyter_code>INPUT_TEXTS = [{'text': "This is a bad ass movie. You got to see it! :-)"},
               {'text': "<NAME> is smart, witty, and creative!!!!!! :D"},
               {'text': "LOL, this guy fell off a chair while sleeping and snoring in a meeting"},
               {'text': "Men shoots himself while trying to steal a dog, OMG"},
               {'text': "Ray and Ray Serve just rocks. Love the way you easily define Ray Actors. Simple APIs, and they work!"},
               {'text': "Yay!! Another good phone interview. I nailed it!!"},
               {'text': "This is INSANE! I can't believe it. How could you do such a horrible thing?"}]<jupyter_output><empty_output><jupyter_text>Start the Ray Serve. It automatically starts Ray processes on the local host<jupyter_code>serve.start()<jupyter_output>2022-03-16 16:40:56,812	INFO services.py:1412 -- View the Ray dashboard at [1m[32mhttp://127.0.0.1:8265[39m[22m
[2m[36m(ServeController pid=64718)[0m 2022-03-16 16:40:59,030	INFO checkpoint_path.py:16 -- Using RayInternalKVStore for controller checkpoint and recovery.
[2m[36m(ServeController pid=64718)[0m 2022-03-16 16:40:59,137	INFO http_state.py:98 -- Starting HTTP proxy with name 'SERVE_CONTROLLER_ACTOR:WRTcXc:SERVE_PROXY_ACTOR-node:127.0.0.1-0' on node 'node:127.0.0.1-0' listening on '127.0.0.1:8000'
2022-03-16 16:40:59,337	INFO api.py:521 -- Started Serve instance in namespace 'serve'.<jupyter_text>Define and a SocialMediaAnalyserModel<jupyter_code>@serve.deployment(route_prefix="/sentiments")
class SocialMediaAnalyserModel(object):
    def __init__(self):
      """
      Constructor for our Sentiment Analyser
      """
      # Initialize an instance of vader analyser
      self._analyser = SentimentIntensityAnalyzer()

    async def __call__(self, starlette_request):
        payload = await starlette_request.json()
        text = payload['text']
        print("Worker: received starlette request with sentimet text", text)
        scores = self._score(text)
        print(f"<{text}> --> {str(scores)}>")
        
    def _score(self, text):
        """
        Private function to analyse the scores. It invokes model's 
        param: text to analyse
        return: sentiment analyses scores
        """
        scores = self._analyser.polarity_scores(text)
        return scores<jupyter_output><empty_output><jupyter_text>Deploy the model<jupyter_code>SocialMediaAnalyserModel.deploy()<jupyter_output>[2m[36m(HTTPProxyActor pid=64719)[0m INFO:     Started server process [64719]
2022-03-16 16:40:59,358	INFO api.py:262 -- Updating deployment 'SocialMediaAnalyserModel'. component=serve deployment=SocialMediaAnalyserModel
[2m[36m(ServeController pid=64718)[0m 2022-03-16 16:40:59,362	INFO deployment_state.py:920 -- Adding 1 replicas to deployment 'SocialMediaAnalyserModel'. component=serve deployment=SocialMediaAnalyserModel
2022-03-16 16:40:59,594	INFO api.py:274 -- Deployment 'SocialMediaAnalyserModel' is ready at `http://127.0.0.1:8000/sentiments`. component=serve deployment=SocialMediaAnalyserModel<jupyter_text>We can now send HTTP requests to our route `route_prefix=/sentiments` at the default port 8000<jupyter_code>import requests  # for making web requests
for sentiment in INPUT_TEXTS:
    response = requests.get(
    "http://localhost:8000/sentiments", json=sentiment)
    print(response.text)<jupyter_output>[2m[36m(SocialMediaAnalyserModel pid=64717)[0m Worker: received starlette request with sentimet text This is a bad ass movie. You got to see it! :-)
[2m[36m(SocialMediaAnalyserModel pid=64717)[0m <This is a bad ass movie. You got to see it! :-)> --> {'neg': 0.0, 'neu': 0.542, 'pos': 0.458, 'compound': 0.7644}>
[2m[36m(SocialMediaAnalyserModel pid=64717)[0m Worker: received starlette request with sentimet text <NAME> is smart, witty, and creative!!!!!! :D
[2m[36m(SocialMediaAnalyserModel pid=64717)[0m <<NAME> is smart, witty, and creative!!!!!! :D> --> {'neg': 0.0, 'neu': 0.316, 'pos': 0.684, 'compound': 0.8957}>
[2m[36m(SocialMediaAnalyserModel pid=64717)[0m Worker: received starlette request with sentimet text LOL, this guy fell off a chair while sleeping and snoring in a meeting
[2m[36m(SocialMediaAnalyserModel pid=64717)[0m <LOL, this guy fell off a chair while sleeping and snoring in a meeting> --> {'neg': 0.0, 'neu': 0.786, 'pos': 0.214, 'com[...]<jupyter_text>Cleanup<jupyter_code>deployments = serve.list_deployments()
print(f'deployments: {deployments}')
serve.shutdown()<jupyter_output>[2m[36m(ServeController pid=64718)[0m 2022-03-16 16:41:07,832	INFO deployment_state.py:940 -- Removing 1 replicas from deployment 'SocialMediaAnalyserModel'. component=serve deployment=SocialMediaAnalyserModel
{'fraction_non_alphanumeric': 0.11334858886346301, 'fraction_numerical': 0.059496567505720827, 'mean_word_length': 4.938405797101449, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 40, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 5, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '387458', 'license': 'Apache-2.0', 'n_tokens_mistral': 2327, 'n_tokens_neox': 2024, 'n_words': 616, 'path': 'ray-serve/05-Ray-Serve-SentimentAnalysis.ipynb', 'repo_name': 'RomaKoks/academy', 'size': '6576'}