Anggota Kelompok:
1. Linda Dwi Novianti
2. Muhammat Amir Munajad
2. Muhammat Amir Munajad
3. Rizka Yulia Sukma
4. Triswanto
Opinion Mining / Sentiment Analysis (sebagian besar researcher menganggap dua istilah ini sama/interchangeable) merupakan sebuah cabang penelitian di domain Text Mining yang mulai booming pada awal tahun 2002-an. Riset-nya mulai marak semenjak paper dari B.Pang dan L.Lee keluar. Secara umum, Sentiment analysis ini dibagi menjadi 2 kategori besar :4. Triswanto
1. Coarse-grained sentiment analysis
2. Fined-grained sentiment analysis
Coarse-grained sentiment analysis - kita mencoba melakukan proses analysis pada level Dokumen. Singkatnya adalah kita mencoba mengklasifikasikan orientasi sebuah dokumen secara keseluruhan. Orientasi ini ada 3 jenih : Positif, Netral, Negatif. Akan tetapi, ada juga yang menjadikan nilai orientasi ini bersifat kontinu / tidak diskrit.
Fined-grained sentiment analysis - kategori kedua ini yang sedang Naik Daun sekarang. Maksudnya adalah para researcher sebagian besar fokus pada jenis ini. Obyek yang ingin diklasifikasi bukan berada pada level dokumen melainkan sebuah kalimat pada suatu dokumen.
Berikut dibawah ini merupakan tahapan dalam pembuatan sentiment analyst menggunakan Bahasa pemrograman python.
1. Pada pembuatan program kali ini memakai python versi 3.6.4
2. Berikut merupakan listing program nya.
import os
import sys
import time
import json
import requests
import argparse
import lxml.html
import re
from textblob import TextBlob
from lxml.cssselect import CSSSelector
YOUTUBE_COMMENTS_URL = 'https://www.youtube.com/watch?v={youtube_id}'
YOUTUBE_COMMENTS_AJAX_URL = 'https://www.youtube.com/comment_ajax'
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'
np = 0
nn = 0
n = 0
def clean_text(text_sel):
return ' '.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)", " ", text_sel).split())
def find_value(html, key, num_chars=2):
pos_begin = html.find(key) + len(key) + num_chars
pos_end = html.find('"', pos_begin)
return html[pos_begin: pos_end]
def extract_comments(html):
global np, n, nn
tree = lxml.html.fromstring(html)
item_sel = CSSSelector('.comment-item')
text_sel = CSSSelector('.comment-text-content')
time_sel = CSSSelector('.time')
author_sel = CSSSelector('.user-name')
for item in item_sel(tree):
analysis = TextBlob(clean_text(text_sel(item)[0].text_content()))
# set sentiment
if analysis.sentiment.polarity > 0:
result = 'positive'
np += 1
elif analysis.sentiment.polarity == 0:
result = 'neutral'
n += 1
else:
result = 'negative'
nn += 1
yield {'cid': item.get('data-cid'),
'text': text_sel(item)[0].text_content(),
'time': time_sel(item)[0].text_content().strip(),
'author': author_sel(item)[0].text_content(),
'result': result}
def extract_reply_cids(html):
tree = lxml.html.fromstring(html)
sel = CSSSelector('.comment-replies-header > .load-comments')
return [i.get('data-cid') for i in sel(tree)]
def ajax_request(session, url, params, data, retries=10, sleep=20):
for _ in range(retries):
response = session.post(url, params=params, data=data)
if response.status_code == 200:
response_dict = json.loads(response.text)
return response_dict.get('page_token', None), response_dict['html_content']
else:
time.sleep(sleep)
def download_comments(youtube_id, sleep=1):
session = requests.Session()
session.headers['User-Agent'] = USER_AGENT
# Get Youtube page with initial comments
response = session.get(YOUTUBE_COMMENTS_URL.format(youtube_id=youtube_id))
html = response.text
reply_cids = extract_reply_cids(html)
ret_cids = []
for comment in extract_comments(html):
ret_cids.append(comment['cid'])
yield comment
page_token = find_value(html, 'data-token')
session_token = find_value(html, 'XSRF_TOKEN', 4)
first_iteration = True
# Get remaining comments (the same as pressing the 'Show more' button)
while page_token:
data = {'video_id': youtube_id,
'session_token': session_token}
params = {'action_load_comments': 1,
'order_by_time': True,
'filter': youtube_id}
if first_iteration:
params['order_menu'] = True
else:
data['page_token'] = page_token
response = ajax_request(session, YOUTUBE_COMMENTS_AJAX_URL, params, data)
if not response:
break
page_token, html = response
reply_cids += extract_reply_cids(html)
for comment in extract_comments(html):
if comment['cid'] not in ret_cids:
ret_cids.append(comment['cid'])
yield comment
first_iteration = False
time.sleep(sleep)
# Get replies (the same as pressing the 'View all X replies' link)
for cid in reply_cids:
data = {'comment_id': cid,
'video_id': youtube_id,
'can_reply': 1,
'session_token': session_token}
params = {'action_load_replies': 1,
'order_by_time': True,
'filter': youtube_id,
'tab': 'inbox'}
response = ajax_request(session, YOUTUBE_COMMENTS_AJAX_URL, params, data)
if not response:
break
_, html = response
for comment in extract_comments(html):
if comment['cid'] not in ret_cids:
ret_cids.append(comment['cid'])
yield comment
time.sleep(sleep)
def main(argv):
global np, n, nn
parser = argparse.ArgumentParser(add_help=False, description=('Download Youtube comments without using the Youtube API'))
parser.add_argument('--help', '-h', action='help', default=argparse.SUPPRESS, help='Show this help message and exit')
parser.add_argument('--youtubeid', '-y', help='ID of Youtube video for which to download the comments')
parser.add_argument('--output', '-o', help='Output filename (output format is line delimited JSON)')
parser.add_argument('--limit', '-l', type=int, help='Limit the number of comments')
try:
args = parser.parse_args(argv)
youtube_id = args.youtubeid
output = args.output
limit = args.limit
if not youtube_id or not output:
parser.print_usage()
raise ValueError('you need to specify a Youtube ID and an output filename')
print('Downloading Youtube comments for video:', youtube_id)
count = 0
with open(output, 'w') as fp:
for comment in download_comments(youtube_id):
print(json.dumps(comment), file=fp)
count += 1
sys.stdout.write('Downloaded %d comment(s)\r' % count)
sys.stdout.flush()
if limit and count >= limit:
break
print('\n\nPositive: ', float(np/(np+n+nn)*100), '%')
print('Negative: ', float(nn/(np+n+nn)*100), '%')
print('Neutral: ', float(n/(np+n+nn)*100), '%')
print('\nDone!')
except Exception as e:
print('Error:', str(e))
sys.exit(1)
if __name__ == "__main__":
main(sys.argv[1:])
3. Pastikan sudah menginstall packages untuk program diatas.
a. pip install requests
b. pip install lxml
c. pip install cssselect
d. pip install textblob
4. Listing program dibawah ini digunakan untuk mendeklarasikan beberapa url yang akan diakses kedalam program dan beberapa variable untuk menampung nilai – nilai dalam program.
YOUTUBE_COMMENTS_URL = 'https://www.youtube.com/watch?v={youtube_id}'
YOUTUBE_COMMENTS_AJAX_URL = 'https://www.youtube.com/comment_ajax'
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36'
np = 0 #persentase positif
nn = 0 #persentase negatif
n = 0 #persentase netral
5. def extract_comments(html), berfungsi untuk mengambil data-data komentar seperti penulis, waktu, dan komentar itu sendiri berdasarkan response (html). Pada fungsi ini juga ditentukan apkah komentar itu positif, nagatif, atau netral dengan TextBlob.
6. def extract_reply_cids(html), hampir sama dengan fungsi sebelumnya hanya mengambil id reply
7. def download_comments(youtube_id, sleep=1), berfungsi untuk membuat request session ke alamat URL youtube dan setelah mendapat response, response tersebut dikirim ke fungsi extract_comments
8. def main(argv), fungsi yang pertama kali dijalankan dengan beberapa argument, yaitu –youtubeid untuk meletakkan id youtube, --output untuk meletakkan komentar kedalam file, --limit untuk membatasi komentar yang didownload. Pada fungsi ini akan dijalankan fungsi download_comments yang nilai baliknya akan dimasukkan kedalam file yang telah didefinisikan pada saat menjalankan program ini (contoh: --output analisa.txt) , kemudian menghitung persentase komentar positif, negative, dan netral.
Hasil
Sumber:
Tidak ada komentar:
Posting Komentar