SON DAKİKA

Nvdia

NetworkX, Jaccard Benzerliği ve cuGraph Kullanarak Favori Filminizi Tahmin Etme

Veri miktarının dünya genelinde artmasıyla birlikte, tüketicilerin bilinçli kararlar alması giderek daha zor hale gelmektedir. Neyse ki, büyük veri setleri, çoğu zaman bunaltıcı olabilen karar verme süreçlerini kolaylaştırmak için yararlı olan öneri sistemlerinin temel bileşenlerindendir.

Verilerdeki ilişkileri modellemek için grafikler mükemmel bir seçimdir ve Python’daki NetworkX, birçok veri bilimcisinin grafik analizi için başvurduğu popüler bir seçenektir. NetworkX, öğrenmesi ve kullanması kolaydır; geniş bir grafik algoritması yelpazesine sahiptir ve geniş, dost bir topluluk tarafından desteklenmektedir. Ayrıca, dokümanlar, Stack Overflow ve favori LLM’inizde bol miktarda örnek bulunabilir. Ancak birçok geliştiricinin NetworkX ile grafik analizine girmesi, bu kütüphanenin genellikle performans açısından büyük ölçekli öneri sistemlerinin ihtiyaçlarını karşılamada yetersiz kalmasıyla hayal kırıklığına uğradığı da bir gerçektir.

Bu da şu soruyu gündeme getiriyor: Etkili bir grafik tabanlı öneri sistemi birkaç basit Python satırıyla yazılabilir mi? Daha genel olarak, geliştiriciler ve veri bilimcileri, hem kullanıcı dostu hem de yüksek performanslı grafik analitiği elde edebilir mi?

Her iki sorunun cevabı da “evet”.

Python kullanarak basit ve etkili bir öneri sistemi oluşturmanın yollarını öğrenmek için okumaya devam edin; burada 33M film izleme değerlendirmesi içeren bir veri seti, Jaccard Benzerlik algoritması ve modern büyük ölçekli grafik verileri için gerekli olan 250 kat hız artışını sağlayan NVIDIA cuGraph arka planı yer alıyor.

The MovieLens Veri Seti

Sistemin en önemli parçasıyla başlayalım: veri. MovieLens veri seti1, kamuya açık bir şekilde sunulmuştur ve daha ayrıntılı bilgiye README dosyasından ulaşabilirsiniz. Tüm set, 331k anonim kullanıcının 87k film hakkında yapmış olduğu 34M değerlendirmeden oluşmaktadır.

Image showing how the MovieLens data can be shown as a graph.
Şekil 1. MovieLens verisi, bireysel değerlendirmelerin, kullanıcı ve film düğümleri arasındaki kenarlara kolayca eşlendiği bir grafik olarak temsil edilebilir.

Verilerden Öneri Çıkarma: İkili Grafikler ve Jaccard Benzerliği

MovieLens verisinden oluşturduğumuz grafik, yalnızca iki tür düğüm olduğu için ikili bir grafik olarak adlandırılabilir: filmler ve kullanıcılar. Ayrıca, değerlendirmeler (kenarlar) yalnızca bir kullanıcı ile bir film arasında yer alır. Bu, Jaccard Benzerliği algoritmasının filmler arasındaki benzerlikleri bulmada uygulanmasını oldukça kolaylaştırır. Jaccard Benzerliği, düğümleri karşılaştırarak ilişkileri kullanarak benzerlik katsayısını hesaplar. Bu bağlamda, filmler kullanıcıların izleme ve değerlendirme tercihleri doğrultusunda birbirleriyle ilişkili hale gelir.

Image showing how the  Jaccard Similarity algorithm can be used to find similarities between movies.
Şekil 3. Jaccard Benzerliği, karşılaştırılan iki düğümün komşularının kümelerinin boyutlarını kullanarak bir benzerlik katsayısı hesaplar. Kullanıcıların izleme tercihleri doğrultusunda, m3, m2 ile m1’e göre daha fazla benzerlik gösterir.

NetworkX Küçük Grafikler İçin Kolaylık Sağlar

Beklenildiği gibi, NetworkX, yukarıda tarif edilen türde bir analizi destekler ve sadece birkaç Python satırıyla sonuç almaya başlamak oldukça kolaydır. Ancak kullanımda, NetworkX’in büyük boyutlu grafikler için performans sorunları ortaya çıkarması yaygındır; özellikle öneri sistemlerinin gerektirdiği grafik boyutları için. Aşağıda öneri sisteminin ana unsurlarına bir göz atacağız ancak tam kaynak kodunu buradan edinebilirsiniz.

Kullanacağımız Jaccard Benzerliği algoritması, kenar ağırlıklarını dikkate almadığı için tüm değerlendirmeleri eşit olarak değerlendirecektir. Düşük puanlı filmlerin önerilmesini istemediğimiz için belirli bir eşik altında kalan tüm değerlendirmelerin temizlenmesini sağlayacağız; bu da grafiğin boyutunu küçültecektir.

# "İyi" değerlendirmeler (puan >= 3) içeren ayrı bir DataFrame oluşturun.
good_ratings_df = ratings_df[ratings_df["rating"] >= 3]
good_user_ids = good_ratings_df["userId"].unique()
good_movie_ids = good_ratings_df["movieId"].unique()

Eldeki verilerin boyutlarına baktığımızda, iyi değerlendirmelere sahip grafiğimizin yaklaşık 330k düğüm ve 28M kenar içerdiğini görmekteyiz; komşuların sayısı olan ortalama derece ise 84’tür:

toplam kullanıcı sayısı: 330975
toplam değerlendirme sayısı: 33832162
ortalama değerlendirme sayısı/kullanıcı: 102.22
iyi değerlendirme yapan kullanıcı sayısı: 329127
iyi değerlendirme sayısı: 27782577
ortalama iyi değerlendirme sayısı/kullanıcı: 84.41

Daha önce de bahsettiğimiz üzere, bu boyutta grafikler çoğu zaman NetworkX için bir zorluk ortaya çıkarırken, GPU hızlandırması sayesinde cuGraph arka planı bu veri ile ilgili performans sorunlarını ortadan kaldırmaktadır. Ancak, öncelikle varsayılan performansı göstermek için sadece CPU ortamında devam edeceğiz.

Not: Aşağıdaki tüm örnekler, NetworkX 3.4.2 ve Intel(R) Xeon(R) Platinum 8480CL @ 2.0GHz 2TB RAM kullanan bir iş istasyonunda çalıştırılmıştır.

Kullanıcılar ve iyi film değerlendirmelerinden oluşturduğumuz NetworkX grafiğini kullanarak, bir kullanıcı seçip en yüksek puanını verdiği filmlerden birini bulalım ve Jaccard Benzerliği ile ona benzer filmleri belirleyelim:

# Bir kullanıcıyı ve yüksek puan verdiği bir filmi seçin
user = good_user_ids[321]
user_reviews = good_user_movie_G[user]
highest_rated_movie = max(
	user_reviews,
	key=lambda n: user_reviews[n].get("rating", 0)
)

Kullanıcı ID’sini film adı haritasında arattığımızda, bu kullanıcının en yüksek puan verdiği filmin animasyon filmi “Mulan” olduğunu görüyoruz:

kullanıcı=289308 için en yüksek puanlı film: Mulan (1998), id: 1907, puan: {'rating': 5.0}

Artık bu kullanıcının tercihlerine ve izleme geçmişine dayanarak öneri sağlamak için Jaccard Benzerliğini kullanabiliriz:

%%time
# Jaccard Benzerliğini çalıştırın
jacc_coeffs = list(nx.jaccard_coefficient(good_user_movie_G, ebunch))

CPU süreleri: kullanıcı 2dk 5sn, sistem: 15.4 ms, toplam: 2dk 5sn
Duvar zamanı: 2dk 14sn

Varsayılan NetworkX uygulamasıyla Jaccard Benzerliği hesaplama işlemi iki dakikadan fazla sürdü. Bu sonuçları kullanarak şimdi öneride bulunabiliriz:

# Katsayı değerine göre sıralayın (üçüncü eleman)
jacc_coeffs.sort(key=lambda t: t[2], reverse=True)

# Zaten görülmüş filmlere göre sıralı "en iyi" önerileri oluşturun.
movies_seen = list(good_user_movie_G.neighbors(user))
recommendations = [mid for (_, mid, _) in jacc_coeffs
               	  if mid not in movies_seen]

Artık sıralı öneri listemizin ilk filmini basitçe yazdırabiliriz:

Kullanıcı ID 289308 muhtemelen Tarzan'ı (1999) (film ID: 2687) sevecektir.

Kod Basit ve Sonuçlar Olumlu Fakat Performans Sorunları Yaşıyoruz

Görüldüğü üzere, öneri makul görünüyor; “Mulan”ı seven birinin de 1999 yapımı “Tarzan”ı beğenmesi muhtemel. Ancak, hedefimiz bir hizmet sağlamak veya yüzlerce, binlerce filmi analiz etmekse, iki dakikalık çalıştırma süresi bizi başka bir çözüm arayışına itebilir. Aşağıdaki sisteme ilişkin başka filmler arasında benzerlik ararken süre kaybının daha da arttığını görebiliriz:

%%time
# 1196: "Star Wars: Episode V - The Empire Strikes Back (1980)"
print_similar_movies(1196)

Star Wars: Episode V - The Empire Strikes Back (1980) filmiyle ilgili benzer filmler:
filmId=260, Star Wars: Episode IV - A New Hope (1977)
filmId=1210, Star Wars: Episode VI - Return of the Jedi (1983)
filmId=1198, Raiders of the Lost Ark (1981)
CPU süreleri: kullanıcı 13dk 47sn, sistem: 71.8 ms, toplam: 13dk 47sn
Duvar zamanı: 11dk 30sn

%%time
# 318: "The Shawshank Redemption (1994)"
print_similar_movies(318) 

"The Shawshank Redemption (1994)" için benzer filmler:
filmId=296, Pulp Fiction (1994)
filmId=593, "The Silence of the Lambs (1991)"
filmId=356, Forrest Gump (1994)
CPU süreleri: kullanıcı 28dk 28sn, sistem: 172 ms, toplam: 28dk 28sn
Duvar zamanı: 16dk 49sn

Gerçekten de, öneri sistemi sadece birkaç satırdan oluşmasına rağmen, aldığımız önerilerin kalitesi dikkat çekiyor. Ancak, çalıştırma süreleri, bunu kullanışsız hale getiriyor. “The Shawshank Redemption (1994)” filmi için benzerlik aramak neredeyse 17 dakika sürüyor.

NVIDIA cuGraph İle Performans Nasıl Hızlanır?

Yukarıdaki iş akışındaki grafik algoritması oldukça pahalıyken, NVIDIA cuGraph arka planını kullanarak ve uyumlu bir GPU ile performansı dramatik şekilde artırmak mümkündür. Uygulama değişmeyecek, yalnızca performans artışı sağlayacağız.

Jaccard Benzerliği, nx-cugraph sürüm 25.02 veya sonrasında desteklenmektedir. 25.02 sürümü, gecikmeli yapıların sağlandığı ve ilerleyen aylarda stabil sürimler arasında yer alacak olan bir sürümdür. nx-cugraph, RAPIDS Kurulum Kılavuzu üzerinden hem gecikmeli hem de stabil kanallardan kurulabilir. Bu kurulumdan sonra, sadece bir ortam değişkeni ayarlayarak nx-cugraph’u etkinleştirebilirsiniz:

NX_CUGRAPH_AUTOCONFIG=True

cuGraph, Jaccard Benzerliği hesaplaması için gereken komşu aramalarını ve set karşılaştırmalarını hızlandırarak GPU’yu kullanır. Ayrıca, grafik büyüdükçe ve film sayısı ile her film için değerlendirme sayısı arttıkça performans neredeyse sabit kalır.

Sisteminin en güzel kısmı – kodun basitliği – değişmezken, performans artışı 250 kat fazladır. Önceden yirmi dakikadan fazla süren işlemler, artık dört saniyenin altında sonuçlanmaktadır.

Barchart showing how Jaccard Similarity speedup with cuGraph over NetworkX for Movie Recommendations.
Şekil 4. Jaccard Benzerliği hesaplamasında cuGraph’ın NetworkX’e göre sağladığı hız artışını gösteren grafik.

Yazılım: NetworkX 3.4.2, cuGraph/nx-cugraph 25.02
CPU: Intel(R) Xeon(R) Platinum 8480CL @ 2.0GHz, 2TB RAM
GPU: NVIDIA Quadro RTX 8000 48GB RAM

Sonuç

Bu yazıda, Python kullanarak basit ve etkili bir öneri sisteminin nasıl geliştireceğini ele aldık. Farklı yaklaşımlar mevcut olsa da – içeriklerine de buradan ulaşabilirsiniz – NetworkX ile veri keşfine başlamak için bu kadar az çaba gerektiren pek az seçenek vardır. Ancak, üretken ve anlamlı veri keşfi hızlı sonuçlar gerektirir ve NetworkX genellikle daha büyük ve gerçek dünya problem boyutlarını ölçeklendirme noktasında zayıf kalmıştır.

İşte bu noktada NVIDIA cuGraph arka planı, NetworkX API’sini hızlandırarak paha biçilmez bir avantaj sunar; saniyeler içinde sonuç elde etmenizi sağlarken zamanınızı ve enerjinizi verimli kullanmanıza yardımcı olur. Kullanıcılar artık NetworkX gibi en popüler grafik analitik kütüphanesini, ölçekleme sorunları yaşamadan, bir GPU ve cuGraph arka planını ekleyerek kullanmaya devam edebilirler.

Daha fazla bilgi için https://rapids.ai/nx-cugraph adresini ziyaret edebilirsiniz.

Kaynak

Nvdia Blog

Düşüncenizi Paylaşın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

İlgili Teknoloji Haberleri