.NET uygulamaları için Azure Machine Learning ile önerme motoru geliştirme

Bu yazıda farklı bulut API’larını kullanan Makine Öğrenmesini bir hizmet olarak nasıl kullanabileceğinizi ele almak istiyorum. İlk olarak Azure Machine Learning Studio’ya bakacağız. Bu bilgileri irdelemek için de, movielens dataset kullanarak bir film önerme hizmeti oluşturacağız. Önerme motorları, bugün arama sorgularının, müzik, kitap, filmlerin tahmin edilmesi gibi birçok yerde kullanılıyor. Çevrimiçi kaynaklarda Netflix üzerinde izlenen film ya da programların %75’ten fazlasının Netflix film önerme motoru ile çalıştığı söyleniyor. Bakalım oluşturacağımız önerme motoruyla bu oranı yükseltebilecek miyiz?

Bu yazıdaki bölümler:
• Arka Plan
• Bu öğretici için ön koşullar
• Bu önerme motorunu geliştirmenin yaklaşımı
• Azure Machine Learning Studio’da Film Önerme Modeli Oluşturma
• Film Önerme Web uygulamamızı ASP.NET Core ile Oluşturma
• Bitirirken
Zamanınız mı yok? Kaygılanmayın! Çözümün tamamını GitHub üzerinde de bulabilirsiniz, buna karşılık gelen Azure Machine Learning studio deneyini burada bulabilirsiniz.

Arka Plan
Yapay zekâ (AI) şu anda bir popülerlik patlaması yaşıyor. Birçok şey gibi bu da yeni değil! Aslında yapay zekâ alanında oldukça heyecan verici bazı şeylerin sözü daha 1960’larda verilmeye başlandı! Yapay zekâ için sözü verilen her şey gerçekleşmemiş de olsa, yapay zekânın Makine Öğrenmesi olarak bilinen alt kümesi epeyce bir süredir çeşitli bilgi işlem sistemlerinde kullanılıyor. Şu anda, işlem gücünün güçlü algoritmalarla bir araya gelmesi ve büyük miktarda verilerin kullanılabilirliği, farklı deneyimler sağlayan daha akıllı uygulamaları geliştirmek için çok daha benzersiz bir fırsatı getiriyor.

Makine öğrenmesi ile henüz tanışmadıysanız, önceden bilinmesi gereken bazı şeyler var. Bu konuda başarılı olmak için yüksek lisans derecesi gerekmese de sıfırdan başlıyorsanız öğrenmeniz gereken bazı şeyler olacaktır. Makine Öğrenmesi (ve Veribilim) temel olarak verileri araştırdığınız, kendi kullanımınıza göre değiştirdiğiniz, bir problemi çözmenin farklı yöntemlerini denediğiniz, her yöntemi yinelediğiniz ve çalışmanızı değerlendirdiğiniz bir bilimsel süreçtir. Programlama ağırlıklı olarak söz konusu olsa da daha çok sizi sonuca götüren bir araçtır. Blog yazılarından oluşan bir dizide size, .NET geliştiricilerinin etkileyici müşteri deneyimleri oluşturmak için Makine Öğrenmesi ve Yapay Zekâdan yararlanabilecekleri farklı yolları göstermek istiyoruz. Bunun için, etkileyici müşteri deneyimleri oluştururken .NET geliştiricilerinin Makine Öğrenmesi ve Yapay Zekâdan nasıl yararlanabileceklerini gösteren farklı senaryoları ele alacağız. Bu süreçte, birlikte bu alanı araştırırken sizden geribildirim almak bizi mutlu edecek.

Bu öğretici için ön koşullar
Bu deneyimin Azure üzerinde işlerliğini sağlamak için
• Aktif bir Azure hesabınız olmalıdır. Hesabınız yoksa, Azure Deneme Sürümüne ücretsiz kaydolabilirsiniz.
• Azure Machine Learning Studio ile başlangıç deneyiminin üstünden geçin.
• Henüz açıkça gerekmese de .NET development en iyi Visual Studio ile birlikte çalışır, ayrıca .NET bileşenlerinizin de kurulu olması gerekir.
• MovieLens 20M veri kümesi
• AzureML film önericisi kullanan ASP.NET Core web uygulaması prototipi (önizleme)
• [Opsiyonel] MovieLens 1M Film Önerme Modeli

Yaklaşım
Azure Machine Learning Studio, çeşitli örnek verilerin de olduğu bir paket olarak gelir. Bu öğreticide, film derecelendirme, başlıklar, türler vb. ile gelen MovieLens veri kümesini kullanacağız. Film önerme motorumuzu oluşturmak için kullanabileceğimiz seçenekler şunlar:

Popülasyon Ortalamaları
Oluşturulabilecek en basit önerme motoru, popülasyon ortalamalarını kullanır. Seçtiğiniz bir filme verilen tüm derecelendirmeleri alıp, bir ortalama değer oluşturun. Ortalama derecelendirme değeri belli bir eşikten yüksekse, örneğin 4/5 ise, bu filmi kullanıcımıza önerebiliriz. Bu basit çözüm iyi çalışabilir, ama kullanıcı tercihlerini dikkate almaz. Bir aksiyon filmleri tutkunu olarak ben ‘Görevimiz Tehlike’ serisini çok seviyorum; ama arkadaşım bilim kurguya meraklı, o da ‘Uzay Yolu’nu seviyor. Popülasyon ortalamasına göre bu filmlerin her ikisi de yüksek derecelendirilmiş olabilir, ama önerme motorunun bu filmleri göstermesi ne ben ne de arkadaşımı memnun eder.

İçerik temelli

İçerik temelli filtreleme yöntemleri, öğenin açıklamasına ve kullanıcının tercihler profiline dayanır. İçerik temelli bir önerme sisteminde, öğeleri tanımlamak için anahtar sözcükler kullanılır ve bu kullanıcının sevdiği öğe türlerini belirtmek için bir kullanıcı profili oluşturulur. Başka bir deyişle, bu algoritmalar, o kullanıcının geçmişte beğendiklerine benzer öğeleri önermeye çalışır.

İşbirliğine dayalı filtreleme
‘İşbirliğine dayalı filtreleme’, temeldeki bir varsayıma dayanarak çalışır; bu varsayıma göre eğer bir A kişisi bir konuda bir B kişisiyle aynı görüşü paylaşıyorsa, A’nın başka bir konuda B ile aynı görüşe sahip olma olasılığı, rasgele seçilmiş bir diğer kişiyle aynı görüşte olma olasılığından yüksektir.

Bu iki klasik önerme yöntemi, ‘içerik temelli yöntem’ ve ‘işbirliğine dayalı filtreleme’, popülasyon ortalamaları yönteminde eksik olan tercih sorununu çözer. Azure’un MatchBox Recommender‘i, en doğru önerileri sağlamak için bu iki yöntemden de yararlanır.

Grafik Modeller
İçerik temelli ve işbirliğine dayalı filtreleme kullanan karma bir yöntem işi çalışmakla birlikte iki varsayıma dayanır. Bunlardan birincisi, kullanıcı tercihlerinin statik olduğu, zaman içinde değişmediği; ikincisi de kullanıcı ile öğe tercihleri arasındaki ilişkinin basit olduğudur. Gerçekte bu doğru değildir. Grafik modeller, yukarıdaki iki varsayımda bir çözümün sağlanmasına yardımcı olur; örneğin, Markov yapısı, önerme sisteminde kullanıcı tercihlerinin zamansal yönlerini yakalayabilir, ama bu yazıyı basit tutmak için bu yaklaşımın ayrıntılarına girmeyeceğiz.

Bu modeli, Azure Machine Learning stüdyosunu kullanarak, içerik temelli ve işbirliği temelli filtrelemeye dayanan karma bir yaklaşımla oluşturacağız.

Model tamamlandıktan sonra, modelin görmediği filmlerin derecelendirmelerini tahmin etmeye çalışarak ve bu filmlerin gerçek derecelendirmelerini karşılaştırarak modeli değerlendireceğiz. Performansından memnun kalırsak, bu modeli bir web hizmeti olarak yayınlayıp, ASP.NET Core MVC uygulaması üzerinden REST kullanarak çağıracağız. Tamamlanmış örneği burada bulabilirsiniz. Tek yapmanız gereken örneğin ‘appsettings.json’ dosyasında API anahtarı ile URI’yi kendi Azure hesabınıza ve model ayarlarınıza göre değiştirmek.

Başlarken
Zamanının kısıtlıysa, MovieLens 1M veri kümesine dayanarak tamamlanan buradaki film önericisini açıp, doğrudan ‘Setup a webservice’ bölümüne gidebilirsiniz. Bu modelin nasıl derlendiğini biraz daha fazla anlamak isterseniz, aşağıdaki adımları izleyebilirsiniz.

Azure Machine Learning Studio’da Film Önerme Modeli Oluşturma
Makine öğrenmesi eklerken kullanılan analiz altyapısı, ön önişleme, özellik ayıklama ve seçme, makine öğrenmesi modelini ve modelin iyi çalışıp çalışmadığını anlamak için bir tür bir puanlama sistemi uygulama adımlarından oluşur. Öyleyse başlayalım

Adım 1: ‘Veri kümesini seçme’
Biz MovieLens20M veri kümesini kullanacağız; buradan indirebilirsiniz. Veri kümesi çoğu zaman önceden işlenmiştir ve movieId, filmin adı, tür tanımını içeren movies.csv ile birlikte gelir. ratings.csv ise userId, movieId, reyting ve zaman damgasını içerir.

Azure Machine Learning Studio’ya oturum açın; DataSets sekmesini kullanarak movies.csv ve ratings.csv’i yeni veri kümeleri olarak yükleyin.

Bu iki veri kümesini yükledikten sonra artık kullanmaya başlayabilirsiniz.

Adım 2: ‘Modelin geliştirileceği verileri seçme’
Veri kümeleri yüklendiğinde göre, şimdi denemeler sekmesine geçip, yeni bir deneme oluşturun ve ‘Blank Experiment’i seçin. Denemenizi adlandırın, örneğin ‘MovieLens Movie Recommender’ diyelim.
Adım 2a: ‘Veri kümelerinin seçimi’
Temelde bütün modeller veri kümesiyle başlar; onun için Ratings (MovieLens) veri kümesini bu denememize ekleyelim.

Bunu ekledikten sonra, setini görselleştirmeye başlayabilirsiniz.

Bu, modelinizin akışı içinde veri kümesini ve dönüşümleri görebildiğiniz hoş bir aşamadır. Aşağıda gördüğünüz gibi bu veri kümesinde 20M derecelendirme ve userId, movieId, rating, time-stamp başlıklı 4 sütun var:

Adım 2b Özellik Mühendisliği
Önerme motorunuzda en iyi sonucu almak için bundan sonra biraz özellik mühendisliği yapmamız, yani bu veri kümesinde yalnız tahminimizi etkileyeceğini düşündüğümüz sütunları seçmemiz gerekiyor. ‘UserId’, ‘MovieId’, ‘Rating’ önemli gibi görünüyor, ama bu derecelendirmenin ‘Timestamp’ ile birlikte gösterilmesinin hiçbir anlamı yok gibi.

Onun için ‘select columns in dataset’ seçeneğini kullanarak ‘Timestamp’ sütununu kaldıralım. Bu pencere öğesini bulmak için deneme bölmesine ‘select column’ yazabilirsiniz.

Şimdi, veri kümesini, veri kümesi modülündeki seçili sütunlarla bağlayın. Kırmızı bir uyarı simgesi göreceksiniz; bu bize seçilecek sütunları belirlememizi söylüyor.

Sırasıyla ‘userId’, ‘movieId’ ve ‘rating’ sütunlarını seçin.
Kullanıcı derecelendirmelerine ek olarak MovieLens veri kümesinde bir özellik öğesi olarak film türü de var. Bu öğe özelliğini kullanmamız hem bu modeli iyileştirecek hem de bundan sonraki bölümde anlatacağım hazırlıksız başlatma sorunundan kaçınmamızı da sağlayacak. Onun için bundan da yararlanalım.

Adım 2c Veri kümesini bölme
Bir makine öğrenmesi modelini eğitirken, her veri kümesi için iki şeyi mutlaka yapmamız gerekir: Birincisi verileri karıştırmak, ikincisi verileri eğitim ve test veri kümelerine bölmek. Eğitim verileri ile test verilerini 50/50 bölmek çok yaygındır; bunu yapmak, aşırı uygunluk veya yetersiz uygunluk probleminden kaçınmamızı sağlar.
Veri setinizi bölmek için Data Transformation kategorisi altındaki split data modülünü kullanabilirsiniz. Bu model için bölme modunda mutlaka ‘Recommender Split’ kullanın.

Adım 3: Matchbox Recommender kullanımı
Verilerimiz hazır olduğuna göre şimdi bir makine öğrenmesi modeli uygulamaya başlayabiliriz. Azure Machine Learning studio yaygın kullanılan birçok makine öğrenmesi modeliyle birlikte gelir. Matchbox recommender bunlardan biri.

Önerme sistemlerinde iki temel yöntem vardır. Bunlardan biri hem kullanıcıların hem öğelerin özelliklerini kullanan içerik temelli yöntemdir. Diğeri işbirliğine dayalı filtrelemedir. ‘İşbirliğine dayalı filtreleme’nin temelindeki varsayıma göre eğer bir A kişisi bir konuda bir B kişisiyle aynı görüşü paylaşıyorsa, A’nın başka bir konuda B ile aynı görüşe sahip olma olasılığı, rasgele seçilmiş bir diğer kişiyle aynı görüşte olma olasılığından yüksektir.

Matchbox Recommender, işbirliğine dayalı filtrelemeyi içerik temelli yöntemle birleştirir. Onun için de karma önerici olarak tanımlanır. Kullanıcı sisteme yeni girmişse, tahminler, o kullanıcıya dair özellik bilgileri kullanılarak geliştirilir; yani iyi bilinen “hazırlıksız başlatma” sorunu ele alınır. MovieLens veri kümesinde henüz herhangi bir kullanıcı özelliğimiz olmadığı için yerine öğe özelliklerini (ör. tür) kullanarak, ilgili öğeler üzerinde öneriler sunacağız. Bu, “hazırlıksız başlatma” sorununu çözmeye yardımcı olacak.

Belirli bir kullanıcıdan yeterli sayıda derecelendirme topladıktan sonra, yalnızca özelliklerine değil, bu kullanıcının belirli derecelendirmelerine dayanarak kullanıcı için tam kişiselleştirilmiş tahminler yapmak mümkündür. Dolayısıyla içerik temelli önerilerden işbirliğine dayalı filtrelemeye dayanan öneriler arasında sorunsuz bir geçiş vardır. Kullanıcı veya öğe özellikleri bulunmasa bile, Matchbox işbirliğine dayalı filtreleme modunda yine çalışacaktır.
Train Matchbox Recommender’e ilk girdi, kullanıcı-öğe-derecelendirme üçlüsünü gerektirir; bununla başlayalım.

Matchbox Recommender’in aldığı diğer iki girdinin üzerine giderseniz, daha fazla kullanıcı özelliği vb. kullanılacak şekilde kolayca genişletebildiğini göreceksiniz; ama bunu daha sonra yapacağız.
Şimdi Matchbox Recommender (Train) modülünü denememize ekleyin; bölünmüş veri modülünden ‘eğitim’ veri girdilerini alıp, ikisini bağlayın. Bu modülün özellikler penceresinde, yalnız bu modül için geçerli özellikleri seçebilirsiniz; örneğin, çalıştırılacak nitelik sayısı, yineleme sayısı, gösterilecek önerilerin sayısı gibi.

Sonra, Matchbox Recommender’in üçüncü girdisini de öğe özellikleri veri kümesi (movieId, Genre) ile bağlayın. Bu, Matchbox Recommender’imizin karma bir önerici olarak çalışmasını sağlayacak.

Eğitim tamamlandıktan sonra eğittiğiniz modeli daha sonra tekrar kullanmak için kaydedebilirsiniz. Bu size zamandan kazandıracak, aynı modeli tekrar tekrar eğitmeniz gerekmeyecektir. Bunu aşağıda gösterilen seçeneği kullanarak yapabilirsiniz:

Adım 4: ‘Matchbox Recommender’imizi Puanlama
Eğitim tamamlandıktan sonra önericiyi puanlamaya geçebilirsiniz. Train Matchbox Recommender’de olduğu gibi, matchbox recommender’i sürükleyip bırakın, train matchbox recommender çıktısına ‘Split Data’ modülünden gelen test verilerini bağlayın. Bu, eğitilen modeli test verilerine karşı test etmemize izin verecek.
Önerici türü tahmin özelliği, bir derecelendirme, öğe ve ilgili önerici türleri arasında seçim yapmamızı mümkün kılacak.

Derecelendirme tahminini algoritmamızı ve sonrasında bir film kümesi önerebilmek için ilgili öğeleri tahminimizi değerlendirmek için kullanacağız.

Bu noktada tamamlamış sayılırız; onun için modelinizi çalıştırmaya başlayabilirsiniz! Modeliniz başarılı bir şekilde çalıştıysa, modüllerinizin yanında küçük yeşil onay işaretleri göreceksiniz.

Adım 5: Modelinizi değerlendirme
Modelimizin nasıl bir performansa sahip olduğunu anlamak için modelimizi değerlendirmemiz gerekecek. ‘Evaluate Recommender’ modülünü sürükleyip bırakın.

Evaluate Recommender, test veri kümesindeki referans derecelendirmeleri puanlanan veri kümesindeki tahmini derecelendirmelerle karşılaştırır, ortalama mutlak hata ve kök ortalama karesi alınmış hata ölçümlerini hesaplar ve bu iki ölçüm değerini çıktı veri kümesinde gösterir. Kök ortalama karesi alınmış hata değeri sıklıkla bir model veya tahmin edici tarafından tahmin edilen değerler (örnek ve popülasyon değerleri) ile gerçekte gözlemlenen değerler arasındaki farkları ölçmek için kullanılır.

Bir kıyaslama noktası olarak, Netflix için BellKor’s Pragmatic Chaos kullanarak yapılan kök ortalama karesi alınmış hata ölçümü 0,8553’dir. Modelinizi yeniden çalıştırın. Tamamlandığında kök ortalama karesi alınmış hata ölçümünüzü görselleştirip, Netflix önericisini geçebilmiş miyiz bir bakın! (Eh, fena değil!)

Adım 6: Web hizmetimizin kurulum ve dağıtımı
ASP.NET çekirdeği uygulamamızın bu modeli üretimde kullanabilmesi için bunu bir hizmet olarak ayarlamamız gerekir. Bir hizmet olarak ayarlamak için ‘Set Up Web Service’ ve Predictive Web Service seçeneklerini kullanabilirsiniz.

‘Predictive Web Service’ kurulduktan sonra, webservice girdi ve çıktı modüllerinin görünür olduğunu göreceksiniz. Bunları aşağıdaki gibi değiştirin:

Bu, hazır gelen konfigürasyondur; bizim işimizi görür, ama ayrıca tahmin hizmetimize sonuçta filtrede kullanılmayacak olan bir ‘timestamp’ girdisi eklememizi gerektirir. Bu akışı, doğrudan yukarıda gösterilen ‘Score Matchbox Recommender input’a giderek biraz iyileştirebiliriz.

Bu web hizmetini yayınlamadan önce emin olunması gereken bir şey de ‘Score MatchBox Recommender’in önerilen tüm öğe seçimlerini puanlaya, eşlikçi uygulamamızın en iyi şekilde çalışması için maksimum öğe sayısının da ‘6’ya ayarlı olduğudur. Bu, üretim/web hizmeti ortamında çalışabilmesi için zorunludur.

Kurulum aşamasını hızlandırmak için, aşağıda gösterildiği gibi, puanlama için de bir bölme ekleyebilirsiniz. Bu noktada modeliniz eğitilmiş olduğu için, bu, sonuçlarınızı etkilemeden size zaman kazandırır, ama bu isteğe bağlıdır.
Son olarak, webservice çıktısının yalnız altı film önerisini kabul ettiğinden emin olmak gerekir; bu ek bir ‘Select Columns in Dataset’ işlemini gerektirir. İşinizi tamamladığınızda modeliniz aşağıdaki gibi olacaktır:

Adım 7: Web hizmeti test etme
Web sitenizin dağıtımını yaptıktan sonra aşağıdaki panoyu görmeniz gerekir. Panonun size, web hizmetimize bağlanmak için kullanacağımız API Anahtarını vermesi gerekir. Ayrıca, sağlanan test yeteneğini kullanarak varsayılan bitiş noktasını da test edebiliriz. Şimdi bunu yapalım.

Bunu test etmek için, MovieLens veritabanından gördüğüm bir film seçeceğim, derecelendirip, modelin nasıl çalıştığına bakacağım. Bunun için ‘Se7en’ adlı filmi (id:47) seçiyorum. Filmi gerçekten beğendiğim için de bu filmi 5/5 olarak derecelendirip, girdimi göndereceğim; buna uygun olarak sevebileceğim altı film tahminini alacağım.
Yanıtın bir JSON nesnesi olarak dönmesi gerekir:

MovieID’lerin eşleştirilmesi Movie Titles içeriğini döndürdü. Gayet güzel çalışıyor gibi görünüyor.

Adım 8: Film önerme hizmetinin uygulamama entegrasyonu
Azure Machine Learning Studio, gereken .NET kodunu size sağlayarak web hizmetinin entegrasyonunu kolaylaştırır. ‘Default End-point’ bölümünde ‘Request/Response’ bağlantısını tıklayın.

Bu sizi, bu Film Önericisinin istek/yanıt API belgeleri sayfasına yönlendirecek. Örnek kod bölümüne çapraz geçiş yapın. Size gereken kodu sağlayacaktır; bu durumda bu, hizmeti InvokeRequestResponseService yönteminin bir parçası olarak bağlamak için kullanacağınız C# kodudur.

Özelleştirmek için tek yapmanız gereken, apiKey dizesini, web hizmetinizin apiKey dizesiyle değiştirmektir. Ve hazırsınız! apiKey değerini bu web hizmetinin özgün panosunda bulabilirsiniz.

Bu yazıda verilen örnek, apiKey ve URI’yi appsettings.json dosyasında belirler.

ASP.NET Core film önerme web sitemizi oluşturma
Film önerme modelimiz Azure üzerinde hazır olduktan sonra, ASP.NET Core web sitemizi oluşturmaya başlayabiliriz.

Adım 9: Film önerme web sitemizi ASP.NET Core ile Oluşturma
Bundan sonra işimiz kolay: Önce bu örneği klonlayın. Ya da yeni bir ASP.NET Core MVC uygulama da oluşturabilirsiniz. Bunun için, Visual Studio’da File->New experience’de sağlanan kod örneğini refererans olarak kullanabilirsiniz.

Bir kod örneğinin çalışmasını sağlamak için yapmamız gereken ilk şey, appsettings.json dosyasına ‘apikey’ ve ‘uri’ değerlerini eklemek. Bu bilgileri Azure Machine Learning Studio’da modelinizi kurduktan sonra alacaksınız.

Çok basit olan bu uygulamada, bekleyeceğiniz gibi, aşağıdaki bileşenler bulunur:
• Model (Movie): Film Kimlikleri ve Film Başlıklarını içerir. Model örneği oluştururken modele, IMDB’deki film başlıklarından oluşan bir liste getirilir.
• Controller (MoviesController): Kullanıcı etkileşimini yönetir; bu modelle ve Azure film önerme hizmetini sorgulamak ve nelerin önerileceğini seçmek için bu mantığı kullanarak çalışır.
• Views (‘Choose’ ve ‘Recommend’): Birinci görünümde kullanıcı geçmişte görüp beğendiği filmleri seçebilir; ikinci görünüm ‘Recommend’ bu veri noktasına göre önerilen filmlerin listesini gösterir.
Uygulamayı derleyip başlatabilirsiniz. Uygulama, aşağıda gösterilen ‘Choose’ görünümünde başlatılacaktır. Geçmişte beğendiğiniz bir filmi seçtiğinizde, burada ‘Air Force One (1997)’ örneğini kullanalım, bir JSON isteği oluşturacak ve bu kod parçacığını kullanarak web hizmetinde bir tahmin sorgulayacaktır (InvokeRequestResponseService).
Sonra, önerilen ‘movieId’ içerikleri ile oluşan JSON nesnesi ‘Recommended’ görünümü altında gösterilen film adlarıyla eşleştirilecektir.

Bitirirken
Bu öğreticide, Makine Öğrenmesinin .NET uygulamalarınıza getireceği avantajların çok sayıdaki örneklerinden yalnızca biri gösterildi. Azure Machine Learning Studio kullanmak, .NET geliştiricilerin ML ile AI’yı uygulamalarına entegre etmek için kullanabilecekleri birçok yoldan yalnızca bir tanesidir. Bundan sonraki öğreticide .NET’i diğer ML/AI teknolojileriyle nasıl kullanabileceğinize bakacağız.

Yazıyı sonuna kadar okuduğunuz için teşekkür ederim.