Page Rank ile Twitter Kullanıcı Analizi: Veri Tabanlı İncelemeyle Gelişmiş Bakış

Emeltemakcay
riseconsulting
Published in
8 min readAug 29, 2023

By Furkan Gülenç, İfakat Yurt, Meltem Ballıeker

Herkese merhaba,

Bu hafta web sayfalarının önemini belirlemede kullanılan Page Rank algoritması ile ilgili bir Twitter analizi yapacağız. Öncesinde biraz Page Rank Algortimasını tanıyalım.

PageRank algoritması, Google’ın kurucularından Larry Page tarafından geliştirilen ve web sayfalarının önemini ve popülaritesini belirlemek için kullanılan bir algoritmadır. Algoritmanın temel kullanım amacı, bir web sayfasının diğer sayfalardan ne kadar önemli olduğunu belirlemek ve bu sayede arama sonuçlarını sıralamaktır.

PageRank algoritması, web sayfaları arasındaki bağlantıları kullanarak bir sayfanın önemini tahmin etmeye çalışır. Algoritma, bir sayfanın diğer sayfalar tarafından ne kadar çok bağlandığına ve bağlanan sayfaların ne kadar önemli olduğuna dayalı bir hesaplama yapar. Bunu yaparken her sayfayı bir düğüm (node) olarak düşünür ve sayfalar arası bağlantılar yönleriyle beraber düğümler arasındaki oklarla temsil edilir.

Bu algoritmada her sayfa, üzerine gelen bağlantıları sayısına göre bir ağırlık veya puan alır. Bir sayfanın önemi, ona bağlı olan sayfaların önemine göre hesaplanır. Yani, önemli sayfalardan gelen bağlantılar, sayfanın kendi önemini artırır.

Bu işlem iteratif olarak yapılır, yani sayfa önemleri birbirine bağlı olarak güncellenir ve hesaplamalar belirli bir istikrar seviyesine ulaşıncaya kadar devam eder.

Page Rank Algoritmasının Matematiği

Yukarıda bahsedildiği gibi her bir sayfa node olarak temsil edilir ve bağlantılara belirli ağırlıklar verilerek lineer cebir, matris hesapları ve graf teorisine dayanan oldukça karmaşık bir matematiksel formüle dayanır.

PR(A), sayfa A’nın PageRank değeri

d, damping faktörüdür (genellikle 0.85 olarak kullanılır) ve kullanıcıların rastgele sayfalara geçiş olasılığı

PR(Tn), sayfa Tn’nin PageRank değeri

C(Tn), sayfa Tn’nin çıkış bağlantı sayısını (outbound) ifade eder.

N tane sayfanın diğer sayfalara olan bağlantılarına göre yukarıdaki hesaplamayı Hesaplama Matrisi ve Bağlantı Matrisi olarak adlandırılan matrislerle ifade edebiliriz. PageRank değerleri, bu matrislerin çarpımı ile hesaplanır. İlk başlangıçta her sayfa eşit bir PageRank değeri (1/n) ile başlar. Daha sonra yukarıdaki formül ve matris çarpımı işlemi iteratif olarak tekrarlanarak PageRank değerleri güncellenir ve iterasyonlar, değerler tutarlı hale gelene kadar devam eder.

İterasyon formülü;

PRt+1(Pi): incelediğimiz sayfanın yeni iterasyonu

Pj: incelediğimiz sayfaya bağlantılı diğer sayfaların önceki iterasyon değeri

C(Pj): sayfanın bağlantılı olduğu link sayısını ifade eder.

Yukarıdaki örneğe bir daha bakalım ve B sayfasını ele alalım;

iterasyon 0: 4 tane web sayfamız olduğu için başlangıçta hepsinin PageRank değeri 1/4 olacaktır.

iterasyon 1:

adım 1: B sayfasına A ve C üzerinden erişilebilir

adım 2: A ve C’nin önceki iterasyondaki değerleri: 1/4, 1/4

adım 3: A için 0.25/2, C için 0.25/3

adım 4:

Gelelim bağlantı matrisine; herbir sayfayı temsil eden matrisler;

Bunlara göre bağlantı matrisi;

Geçiş iterasyon matrisi;

Yeni iterasyon matrisi;

O zaman matristen görülen C>D>B>A

Bu hesaplara bir de python ile bakalım;


class Node:
def __init__(self, name, edges, max_iteration) -> None:
self.name = name
self.edges:list[str] = edges # outbound links
self.iterations:dict[str,int]={f"Iteration {i}": 0 for i in range(max_iteration)} # iterasyon değerleri
def __repr__(self) -> str:
return f"Node: {self.name}, Iterations: {(self.iterations)}"
def __str__(self) -> str:
return f"Node: {self.name}, Iterations: {(self.iterations)}"

# iteraston sayısı
max_iteration = 5

# nodelar ve bağlantıları
pages = {
"A": Node("A", ["B", "C"], max_iteration),
"B": Node("B", ["D"], max_iteration),
"C": Node("C", ["A", "B", "D"], max_iteration),
"D": Node("D", ["C"], max_iteration),
}
for _, page in pages.items():

# Başlangıç iterasyonu 1/n
page.iterations[f"Iteration 0"] = 1/len(pages)
for i in range(1,max_iteration):
prev_iter = i-1
for name, page in pages.items():
temp = pages.copy()

# kendine bakmasını engellemek için
temp.pop(name)
total_value = 0
for sub_name, sub_page in temp.items():

# inbound kontrolü
if(name in sub_page.edges):

# inbound olan sayfaların önceki pagerank değerlerinin toplanması
total_value += sub_page.iterations[f"Iteration {prev_iter}"]/len(sub_page.edges)
page.iterations[f"Iteration {i}"] = total_value

# Bulduğumuz PageRank değerleri (son iterasyon)
last_iter = f'Iteration {max_iteration-1}'
for _, page in pages.items():
print(f"{_}: {round(page.iterations[last_iter], 4)}")
Sonuçlar:
A: 0.1319
B: 0.1944
C: 0.3542
D: 0.3194
değeri en fazla olandan en küçüğe doğru sıralar.

Şimdi damping factor’e bakalım;

# Geçiş matrisi
T_matrix = [
[0, 0, 1/3, 0], # A
[1/2, 0, 1/3, 0], # B
[1/2, 0, 0, 1], # C
[0, 1, 1/3, 0] # D
]

# Matrisi Numpy dizisine çevirme
M = np.array(T_matrix)
# Toplam düğüm sayısı
N = M.shape[0]
# Her düğümün başlangıçtaki PageRank değeri
v_current = np.ones(N) / N
# Damping faktörü
damping_factor = 0.85
# Iterasyon sayısı
iterations = 50

# PageRank hesaplama
for _ in range(iterations):
v_new = (1 - damping_factor) / N + damping_factor * np.dot(M, v_current)
v_current = v_new

# Bulduğumuz PageRank değerleri (son iterasyon)
pages = ["A", "B", "C", "D"]
for i, value in enumerate(v_current):
print(f"Page {pages[i]}: {value:.4f}")
Sonuçlar: 
Page A: 0.1387
Page B: 0.1976
Page C: 0.3571
Page D: 0.3066
değeri en fazla olandan en küçüğe doğru sıralar.

Sayfa önemleri, bağlantıların niceliğine ve niteliğine göre hesaplandı. Bir sayfanın önemi, ona bağlantı yapan sayfaların önemine bağlıdır. Önemli sayfalardan gelen bağlantılar, sayfanın kendi önemini artırır. Bu bağlamda yukarıdaki örnekte C en önemli sayfayken rank değeri en düşük olan sayfa A oldu.

Şimdi PageRank algoritmasını twitter’da kullanıcı analizi yapmak için nasıl kullanabileceğimizden bahsedelim.

Öncelikle bu uygulama için https://developer.twitter.com/ adresinden bir developer hesabı açarak bir proje oluşturuyoruz ve oluşturduğumuz projenin Keys and tokens kısmından API Key, API Secret Key, Access Token ve Access Token Secret bilgilerini alıyoruz.

Aldığımız bu Key ve Tokenları Python tweepy kütüphanesini kullanarak Twitter kullanıcımızın bilgilerini çekip PageRank algoritmasını uygulayabileceğimiz bir csv dosyası oluşturmak için kullanacağız. Bu CSV dosyası incelediğimiz twitter kullanıcısının listesinde bulunan her kullanıcının, user_id, last_tweet_date ve friends özelliklerinden oluşmaktadır.

  1. Twitter API’sini kullanarak hedeflenen kullanıcının takip listesine erişip ve listeyi CSV dosyasına dönüştürüyoruz
import tweepy 

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth)

Not: Twitter bazı key ve tokenlar’da kullanabileceğimiz tweepy requestlerine sınırlandırma getirir. Eğer permission hatası alırsanız twitter developer hesabınızı yükseltmeniz gerekebilir.

friends = api.get_friends_ids(user_id=user_id)

self.user_id = user_id
self.friends = friends

last_tweet = api.user_timeline(user_id=user_id, count=1)[0]


def analyse_user(user_id='None'):
try:
friends = api.friends_ids(user_id=user_id)
try:
last_tweet = api.user_timeline(user_id=user_id, count=1)[0]
return friends, last_tweet.created_at
except IndexError:
return friends, False
except tweepy.error.TweepError:
return [], False

Bu fonksiyonda kullanıcının arkadaş listesini ve en son tweet tarihini alıyoruz. Eğer user_id yoksa veya kullanıcının herhangi bir tweet’i yoksa False döndürüyoruz.

class Friend(object):
def __init__(self, user_id, friends, last_tweet_date):
self.user_id = user_id
self.friends = friends
self.last_tweet_date = last_tweet_date

def write_to_csv(self, file="friends.csv"):
with open(file, 'a') as f:
writer = csv.writer(f)
row = [self.user_id, self.last_tweet_date,
len(self.friends)] + self.friends
writer.writerow(row)

Burda kullanıcımızın listesindekilerde bulunan kullanıcılardan oluşan bir csv dosyası oluşturduk. PageRank Algoritmasında görmüş olduğumuz node’lar bu kısımda kullanıcılara denk olmaktadır yani her kullanıcı bir node olarak görüntülenmektedir.

2. Listede yer alan kullanıcılar arasındaki ilişkiyi grafiğe dönüştürüyoruz

Aşağıdaki kodla csv dosyamızı okuyor ve Friend nesnelerinden oluşan bir liste oluşturuyoruz, daha sonra network_nodes listesinde bulunan her kullanıcı için arkadaş sayısının histogramını oluşturuyor ve son olarak network_nodes listesinde bulunan ve networks_ids listesinde bulunan arkadaş sayısının bir histogramını oluşturuyoruz.

with open("friends.csv", "r") as f:
network_nodes = [Friend(row[0], row[1], row[2:])for row in csv.reader(f)][1:]
network_ids = [n.user_id for n in network_nodes]plt.hist([len(f.friend_ids) for f in network_nodes], bins=50)for friend in network_nodes:
friend.friend_ids_in_network = friend.friend_ids_in_network(network_ids)
plt.hist([len(f.friend_ids_in_network) for f in network_nodes], bins=50)
plt.title("Takip ettiklerimin takip sayısı");

Daha sonra kullanıcının twitter ağını temsil eden bir ağ grafiği oluşturmak ağdan rastgele 100 düğüm (Kullanıcı) örneklemek ve grafiği bir dosyaya kaydetmek için aşağıdaki kod bloğunu kullanıyoruz.

network_map = {f.user_id:f.friend_ids_in_network for f in network_nodes}



import random

from networkx.drawing.nx_agraph import write_dot
random.seed(0)

number_of_nodes = 100

sampled_nodes = random.sample(network_map.keys(), number_of_nodes)

sampled_sub_network_map = {key: [node for node in network_map[key] if node in sampled_nodes]

for key in sampled_nodes}G = nx.Graph(sampled_sub_network_map)

plt.figure(figsize=(18,18))

nx.draw(G)

plt.show(G)

plt.savefig("plot.png", dpi=1000)

Yukarıdaki grafikte her bir düğüm bir kullanıcıyı temsil eder. Her düğüm birbirleriyle inbound veya outbound linkler ile bağlanır ve aralarındaki etkileşimi ifade eder. Örneğin; 1 userID’li bir kullanıcı 2 userID’li bir kullanıcıyı takip ederse 1 userID’li node dan 2 userID’li node’a outbound link ile bağlanır. Bu nedenle grafiğin merkezinde bulunan nodelar birçok kullanıcının aralarındaki etkileşimi ifade ettiği için daha yoğun olarak gözlenir.

3. Grafikteki düğümleri PageRank değerine göre tekrar listeliyoruz

Bir kullanıcının ağının merkezinde bulunan bağlantı yoğunluğu kişinin ilgi alanlarını daha yoğun bir şekilde ifade edecektir. Merkezden uzakta yer alan düğümleri dışlamak ve yeni bir liste oluşturmak için aşağıdaki kodu kullanıyoruz.

G = nx.Graph({anahtar:anahtar için değer, network_map.items'deki değer(), anahtar bileşenlerdeyse[0]})

4. En yüksek PageRank Değerine sahip 10 hesabı listeliyoruz

Son olarak oluşturduğumuz yeni listenin içerisinde yer alan userID’leri PageRank değerlerine göre listeliyoruz ve main kullanıcımızın ağında ilgi alanlarına göre en popüler 10 kullanıcıyı elde ediyoruz.

pr = nx.pagerank(G) 

sorted_nodes = sorted([(node, pagerank) for node, pagerank in pr.items()], key=lambda x:pr[x[0]]) users = api.lookup_users(user_ids


) =[pair[0] for pair in sorted_nodes[:10]])
kullanıcılarda u için:
print(u.screen_name)

Sonuç

Bu yazıda Twitter Kullanıcı Analizi yapmak için PageRank algoritmasını nasıl kullanacağımızdan bahsettik. Önce Twitter API’sini kullanarak kullanıcının arkadaş listesini alıp, bunlardan bir csv dosyası oluşturduk. Daha sonra oluşturduğumuz csv dosyasındaki her sütunu (Kullanıcıyı) bir node olarak gördüğümüz ve nodelar arasındaki arkadaşlık bağlantılarına (outbound link) göre ilişkilendirdiğimiz bir ağ grafiği çıkardık. Elde ettiğimiz bu grafiği PageRank Algoritması kullanarak en bağlantılı 10 kullanıcıyı listeledik.

Bir kullanıcının bağlantı ağı ne kadar büyük olursa, o kullanıcının Twitter ağındaki önemi de o kadar büyük olur. Bu yazıda, Twitter kullanıcı analizi için PageRank algoritmasını nasıl kullanacağımızı gösterdik. Bu algoritmayı kullanarak, Twitter ağındaki en bağlantılı kullanıcıları listeleyebilir ve bu kullanıcıların önemini ölçebilirsiniz.

Umarız faydalı bir yazı olmuştur.

Bu yazı Rise technology AIchievers ekibi tarafından hazırlanmıştır.

Referanslar

1- https://docs.tweepy.org/en/stable/api.html

2- https://www.youtube.com/watch?v=RVIr8Y5isek

3- https://medium.com/web-mining-is688-spring-2021/graph-analysis-using-pagerank-and-networkx-for-twitter-account-beb7e239a71f

--

--