├── README.md └── facebook_gaph_sentiment_analysis.py /README.md: -------------------------------------------------------------------------------- 1 | # sentiment_analysis_graph 2 | a sentiment analysis of comments in a facebook page using python 3.5 facebook graph api and NLTK 3 | -------------------------------------------------------------------------------- /facebook_gaph_sentiment_analysis.py: -------------------------------------------------------------------------------- 1 | #translator to translate comments from others languages to english 2 | from translate import Translator 3 | 4 | import requests 5 | import signal 6 | import sys 7 | import pprint 8 | graph_api_version = 'v2.9' 9 | 10 | # add your token instead 11 | access_token = access_token 12 | translator= Translator(to_lang="fr") 13 | 14 | # the user id for me the facebook page of GOAL ENGLISH 15 | user_id = '25427813597' 16 | limit = 200 17 | posts = [] 18 | url_profile = 'https://graph.facebook.com/{}/{}?fields=feed'.format(graph_api_version,user_id) 19 | 20 | r_profile = requests.get(url_profile, params={'access_token': access_token}) 21 | while True: 22 | data = r_profile.json() 23 | feed = data['feed'] 24 | for post in feed['data']: 25 | posts.append(post['id']) 26 | if 0 < limit <= len(posts): 27 | break 28 | if 'paging' in data and 'next' in data['paging']: 29 | r_profile = requests.get(data['paging']['next']) 30 | else: 31 | break 32 | 33 | comments = [] 34 | 35 | 36 | post_index = 0 37 | for post in posts : 38 | url = 'https://graph.facebook.com/{}/{}/comments'.format(graph_api_version,post) 39 | r = requests.get(url, params={'access_token': access_token}) 40 | print('post Number :',post_index=+1) 41 | while True: 42 | data = r.json() 43 | 44 | # catch errors returned by the Graph API 45 | if 'error' in data: 46 | raise Exception(data['error']['message']) 47 | 48 | # append the text of each comment into the comments list 49 | for comment in data['data']: 50 | # remove line breaks in each comment 51 | text = comment['message'].replace('\n', ' ') 52 | 53 | #translate the comments to english before add them 54 | text = translator.translate(text) 55 | comments.append(text) 56 | 57 | print('Got {} comments, total: {}'.format(len(data['data']), len(comments))) 58 | 59 | # check if we have enough comments 60 | if 0 < limit <= len(comments): 61 | break 62 | 63 | # check if there are more comments 64 | if 'paging' in data and 'next' in data['paging']: 65 | r = requests.get(data['paging']['next']) 66 | else: 67 | break 68 | 69 | 70 | #sentiment analysis part 71 | from nltk.sentiment import vader 72 | sid = vader.SentimentIntensityAnalyzer() 73 | 74 | output = [{ 'sentence' :sentence , 'scores' : sid.polarity_scores(sentence) } for sentence in comments ] 75 | import json 76 | sentiment_analysis = open('sentiment_analysis_'+user_id+'_en.json','w') 77 | json_out = json.dump(output,sentiment_analysis) 78 | pprint.pprint(json_out) 79 | 80 | import pandas as pd 81 | import numpy as np 82 | df = pd.read_json('sentiment_analysis_'+user_id+'_en.json').fillna(' ') 83 | 84 | # the mean of sentiment in a dataframe contains comments 85 | def mean_senti(df) : 86 | neg = [] 87 | pos = [] 88 | neutre = [] 89 | for e in df["scores"] : 90 | neg.append(e["neg"]) 91 | pos.append(e["pos"]) 92 | neutre.append(e["neu"]) 93 | neg = np.array(neg) 94 | pos = np.array(pos) 95 | neut = np.array(neutre) 96 | neutre = np.mean(neut, axis=0) 97 | positive = np.mean(pos, axis=0) 98 | negative = np.mean(neg, axis=0) 99 | return(negative,positive,neutre) 100 | 101 | #make a sub dataframe of comments contains the term "zidan" 102 | sub_def = df[df['sentence'].str.contains("zidan")] 103 | 104 | (neg_c,pos_c,neutre_c) = mean_senti(sub_def) 105 | print('negative :',neg_c,'positive :',pos_c,'neutre :',neutre_c) 106 | --------------------------------------------------------------------------------