Links
Comment on page

Get sentiment analysis from post comments

Tags: #linkedin #sentimentanalysis #api #python #nlp #textanalysis
Author: Florent Ravenel
Last update: 2023-08-10 (Created: 2023-08-10)
Description: This notebook provides a sentiment analysis of comments from LinkedIn post. This is useful to understand the sentiment of their posts and the reactions of their followers. The five adjectives that will be used to analyze comment sentiment on LinkedIn are the following:
  • "Praise" - This is for highly positive comments that express admiration or approval. These comments often include compliments or positive feedback.
  • "Supportive" - This is for positive comments that may not necessarily contain high praise but show agreement, support, or encouragement.
  • "Neutral" - This is for comments that are neither positive nor negative, often factual statements or questions without any clear positive or negative connotations.
  • "Constructive" - This is for comments that may seem negative but are intended to provide constructive feedback or suggest improvements.
  • "Disapproving" - This is for comments that express disagreement, criticism, or negative feedback.
Disclaimer: This code is in no way affiliated with, authorized, maintained, sponsored or endorsed by Linkedin or any of its affiliates or subsidiaries. It uses an independent and unofficial API. Use at your own risk.
This project violates Linkedin's User Agreement Section 8.2, and because of this, Linkedin may (and will) temporarily or permanently ban your account. We are not responsible for your account being banned.

Input

Import libraries

from naas_drivers import linkedin
try:
import openai
except:
!pip install openai --user
import openai
import pandas as pd
from datetime import datetime
import naas
import plotly.express as px

Setup variables

Mandatory
  • li_at: Cookie used to authenticate Members and API clients
  • JSESSIONID: Cookie used for Cross Site Request Forgery (CSRF) protection and URL signature validation
  • post_url: This variable represents the post URL from LinkedIn
  • openai_api_key: OpenAI API key.
Optional
  • prompt: This is the text prompt that you want to send to the OpenAI API.
  • model: ID of the model to use. You can find a list of available models and their IDs on the OpenAI API documentation.
  • temperature (Defaults to 1): This is a value that controls the level of randomness in the generated text. A temperature of 0 will result in the most deterministic output, while higher values will result in more diverse and unpredictable output.
  • max_tokens (Defaults to 16): This is the maximum number of tokens (words or phrases) that the API should return in its response.
# Mandatory
li_at = naas.secret.get("LINKEDIN_LI_AT") or "YOUR_LINKEDIN_LI_AT" #example: AQFAzQN_PLPR4wAAAXc-FCKmgiMit5FLdY1af3-2
JSESSIONID = naas.secret.get("LINKEDIN_JSESSIONID") or "YOUR_LINKEDIN_JSESSIONID" #example: ajax:8379907400220387585
post_url = "https://www.linkedin.com/xxxx"
openai_api_key = naas.secret.get(name="OPENAI_API_KEY") or "ENTER_YOUR_OPENAI_API_KEY"
# Optional
prompt = f"""
In this task, you are required to analyze the sentiment of a comment made on a LinkedIn post.
Your role is to determine whether the sentiment of the comment is "Praise", "Supportive", "Neutral", "Constructive", or "Disapproving".
Here is the comment that you need to analyze: "[COMMENT]"
Your response should strictly be one of the following: "Praise", "Supportive", "Neutral", "Constructive", or "Disapproving".
"""
model = "text-davinci-003"
temperature = 0.2
max_tokens = 100

Model

Get post comments

df_comments = linkedin.connect(li_at, JSESSIONID).post.get_comments(post_url)
print("Comments fetched:", len(df_comments))
df_comments.head(1)

Analyze sentiment

This function uses the TextBlob library to analyze the sentiment of a comment. It takes a comment as an argument and returns the sentiment score.
def get_sentiment(
prompt,
model,
temperature,
max_tokens,
):
# Create completion
response = openai.Completion.create(
model=model,
prompt=prompt,
temperature=temperature,
max_tokens=max_tokens,
)
# Extract the generated text
result = response["choices"][0]["text"].replace("Answer:", "").strip()
return result
# Connect with OpenAI API key
openai.api_key = openai_api_key
# Loop on comments
for index, row in df_comments.iterrows():
# Init
comment = row["TEXT"].strip()
fullname = row["FULLNAME"]
occupation = row["OCCUPATION"]
comment_likes = row["LIKES"]
print("Comment:", comment, f"({comment_likes} likes)")
print(f"Made by: {fullname} - {occupation}")
# Get sentiment
comment_prompt = prompt.replace("[COMMENT]", comment)
sentiment = get_sentiment(comment_prompt, model, temperature, max_tokens)
print("Sentiment:", sentiment)
print()
df_comments.loc[index, "SENTIMENT"] = sentiment

Save dataframe in CSV

def save_df(df, file_name=None):
if not file_name:
activity_id = df.loc[0, "POST_URL"].split(":activity:")[-1]
file_name = f"{datetime.now().strftime('%Y%m%d%H%M%S')}_comments_post_{activity_id}.csv"
df.to_csv(file_name, index=False)
save_df(df_comments)

Output

Analyze result

def analyze_sentiment(df_init):
# Init
df = df_init.copy()
# Groupby
to_group = ["SENTIMENT"]
to_agg = {
"POST_URL": "count",
"LIKES": "sum",
}
to_rename = {
"POST_URL": "SENTIMENT_COUNT",
"LIKES": "COMMENT_LIKES",
}
df = df.groupby(to_group, as_index=False).agg(to_agg).rename(columns=to_rename)
# Order result
categories = ["Praise", "Supportive", "Neutral", "Constructive", "Disapproving"]
df['SENTIMENT'] = pd.Categorical(df['SENTIMENT'], categories=categories, ordered=True)
df = df.sort_values('SENTIMENT')
# Calculate score by adding comment likes
df["SCORE"] = df["SENTIMENT_COUNT"] + df["COMMENT_LIKES"]
return df.reset_index(drop=True)
df_sentiment = analyze_sentiment(df_comments)
df_sentiment

Create Pie chart by sentiment distribution

def create_pie_chart(df, labels_column, values_column, title):
"""
Create a pie chart using Plotly.
Parameters:
df (pandas.DataFrame): The DataFrame containing the data.
labels_column (str): The name of the column to use as labels.
values_column (str): The name of the column to use as values.
title (str): The title of the chart.
"""
# Define color map
color_map = {
'Praise': 'green',
'Supportive': 'lime',
'Neutral': 'gray',
'Constructive': 'orange',
'Disapproving': 'red',
}
# Define the order of the categories
category_order = ['Praise', 'Supportive', 'Neutral', 'Constructive', 'Disapproving']
fig = px.pie(
df,
names=labels_column,
values=values_column,
title=title,
color=labels_column,
color_discrete_map=color_map,
category_orders={labels_column: category_order},
hole=.3
)
fig.update_traces(textinfo='value+percent')
fig.show()
create_pie_chart(df_sentiment, 'SENTIMENT', 'SENTIMENT_COUNT', 'Sentiment Distribution')
create_pie_chart(df_sentiment, 'SENTIMENT', 'SCORE', 'True Sentiment Distribution')