.NET 7 ile Microservices Mimarisi


Merhaba değerli takipçilerim,

Microservice (Mikro hizmet) mimarisi sanıldığı kadar basit değil. Birbirleriyle Kafka üzerinden iletişim kurabilen bağımsız ya da zayıf bağlı mikro hizmetler geliştiriyorsunuz. Her bir mikro hizmetiniz belirli bir portu kullanıyor olacak. Mikro hizmetlerin kullandığı bağımlılık enjeksiyonu için Autofac kullanabilirsiniz. Mikro hizmetlerin listelendiği konfigürasyon dosyasını gRPC-Web API Gateway (API ağ geçidi) projesi içerisinde merkezi olarak kaydedebilirsiniz, konfigürasyon dosyası Discovery Service (Keşif Hizmeti) kullanabilirsiniz. gRPC-Web API ağ geçidini .NET 7 minimal API ile hazırlayabiliyorsunuz yalnız her bir gRPC mikro hizmetiniz aynı isimde bir C# sınıfı geliştirip map etmeniz gerekiyor.

İşte bir Mikrohizmet Mimarisinde olması gereken elemanlar:

.NET 7’de Kafka ve gRPC-Web API Gateway kullanan bir mikro hizmet mimarisi genellikle aşağıdaki öğeleri içerir:

Mikro hizmetler: Bunlar, genel uygulamayı oluşturan bireysel hizmetlerdir. Her mikro hizmet, belirli bir iş etki alanından veya işlevinden sorumludur ve uzaktan yordam çağrısı (RPC) API’leri oluşturmak için yüksek performanslı, açık kaynaklı bir çerçeve olan gRPC’yi kullanarak birbirleriyle iletişim kurarlar.

gRPC-Web API Ağ Geçidi: Bu, gelen tüm istemci istekleri için giriş noktasıdır. API ağ geçidi, istekleri uygun mikro hizmete yönlendirmekten ve ayrıca kimlik doğrulama, hız sınırlama ve istek/yanıt dönüştürme gibi görevleri yerine getirmekten sorumludur.

Kafka: Bu, gerçek zamanlı veri boru hatları ve akış uygulamaları oluşturmak için kullanılan dağıtılmış bir akış platformudur. Mimarideki mikro hizmetler, mesajları yayınlamak ve bunlara abone olmak için Kafka’yı kullanabilir ve birbirleriyle gevşek bağlı, eşzamansız bir şekilde iletişim kurmalarına olanak tanır.

Cassandra: Bu, mikro hizmetler için verileri depolamak için kullanılabilen, yüksek oranda erişilebilir, dağıtılmış bir NoSQL veritabanıdır. Cassandra’nın ölçeklenebilirliği ve performansı, onu bir mikro hizmet mimarisinde kullanım için çok uygun hale getirir.

Redis: Bu, önbelleğe alma katmanı olarak veya oturum durumunu depolamak için kullanılabilen bir bellek içi veri yapısı deposudur. Redis, arka uç veritabanlarına yapılması gereken isteklerin sayısını azaltarak mikro hizmetlerin performansını artırmaya yardımcı olabilir.

Bağımlılık Enjeksiyonu (Autofac): Mimarinin farklı bileşenleri arasındaki bağımlılıkları yönetmeye izin veren bir kalıp, kodu daha test edilebilir, bakımı yapılabilir ve ölçeklenebilir hale getirir.

Konfigürasyon Yönetimi: Mikro hizmetlerin gerektirdiği farklı konfigürasyonları yönetmenin bir yolu, en yaygın uygulama bir konfigürasyon dosyası veya bir konfigürasyon sunucusu kullanmaktır, fakat aynı zamanda bellek içi de olabilir.

Hizmet Keşfi: Ağdaki mikro hizmetlerin konumunu keşfetmenin bir yolu olarak, bir mikro hizmetin farklı örneklerini bulmak ve aralarındaki yükü dengelemek yararlıdır. gRPC-Web API ağ geçidi projesinde merkezi konfigürasyon dosyası tutarsanız buna gerek yoktur.

İzleme ve günlük kaydı: Mikro hizmetlerin performansını, hatalarını ve kullanımını izlemenin ve analiz etmenin bir yolu; sorunları verimli bir şekilde tespit edip düzeltmek için sistemin iyi bir şekilde görülebilmesi önemlidir.

Tüm bu unsurlar, büyük miktarda veriyi ve yüksek düzeyde trafiği işleyebilen esnek ve ölçeklenebilir bir mikro hizmet mimarisi oluşturmak için birlikte çalışır. gRPC-Web API Ağ Geçidi, gelen tüm istemci isteklerini işleyen ve bunları uygun mikro hizmete yönlendiren merkezi bir kontrol noktası görevi görür. Kafka, mikro hizmetler arasında mesajlaşma için kullanılır ve bunların eşzamansız ve bağımsız olarak iletişim kurmasına olanak tanır. Depolama için Cassandra ve Redis, bağımlılıkları ve hizmet konumunu yönetmek için Bağımlılık ekleme ve hizmet keşfi kullanılır. Ve son olarak, sistem performansını takip etmek için izleme ve günlüğe kaydetme çok önemlidir.

Tüm bu mimaride hizmetleri Kubernetes üzerinde deploy edeceğinizi ve güncellemeleri CI/CD ile yapmanızın büyük kolaylık getireceğini söylemeyi unutmayalım.

Mutlu kodlamalar 🙂

Reklam

Full Stack Web ve Mobil Yazılım Eğitimi Müfredatı


Merhaba,

Full Stack Yazılım Eğitimi Müfredatı aşağıdaki teknolojileri önereceğim:

  1. Java
  2. .NET
  3. Python
  4. NodeJS

Veritabanı için: Cassandra

Frontend için: React, Redux, React Native, Expo, NextJS

Aşağıdaki örnek müfredat C# ve TypeScript dilleri ile Web ve Mobil Yazılım Eğitimi önerisidir.

Full Stack Web ve Mobil Yazılım Eğitimi Müfredatı Önerisi (süre: 100 gün)

  • Backend Geliştirici Eğitimi
    1. IDE: Visual Studio
    2. Veritabanları: Cassandra, CQL
    3. Veri Yapıları ve Algoritma
    4. C#, OOP, Dependency Injection, Design Patterns
    5. Dosya İşlemleri, JSON, XML
    6. Hata Yönetimi ve Loglama
    7. Entity Framework for Cassandra
    8. Yazılım Mimarileri: Mikroservis Mimarisi
    9. Sanallaştırma: Kubernetes, Docker, Minikube, Istio
    10. Kafka, Producer, Consumer
    11. API Gateway: Rest, gRPC, WebSocket
    12. GitHub/GitLab/Devops
    13. Bulut Bilişim: Azure
    14. CI/CD
    15. Yapay Zeka: ML.NET, Bot Framework
    16. Geleneksel JWT üyelik ve yeni SSI/DID/VC (örn: Trinsic)
    17. Yazılım Güvenliği
    18. Test
  • Frontend Geliştirici Eğitimi
    1. IDE: Visual Studio Code
    2. HTML, CSS, SCSS, JavaScript, jQuery, Bootstrap
    3. TypeScript, NPM, Yarn
    4. React
    5. Material Design
    6. Hooks
    7. Redux
    8. Expo
    9. NextJS
    10. React Native
    11. NX
    12. Firebase Hosting, FCM
    13. CI/CD
    14. SSR
    15. Geleneksel JWT üyelik ve yeni SSI/DID/VC (örn: Trinsic)
    16. WebRTC
    17. WebXR, AR, VR, MR
    18. Test

Neden Cassandra?
SQL Server ve MongoDB veritabanlarının profesyonel sürümleri ücretlidir. MySQL ve SQLite gibi veritabanları da yüksek performans ve big data için uygun sayılmazlar. Oysa Apache Cassandra tamamen ücretsiz bir big data veritabanıdır. NoSQL veritabanı olmasına karşın SQL’e çok benzer CQL dilini kullanır ve dünyanın en büyük big data projesini dahi yapıyor olsanız Cassandra ile yapabilirsiniz, PetaByte veriyi kaldırabilecek kapasitedir. Cassandra’yı Entity Framework ile de kullanabilirsiniz. Ve Cassandra Netflix gibi büyük kuruluşlar tarafından kullanılır.

Küresel Isınma ve Yazılım

Ayrıca küresel ısınma konusunda bilişim sektöründe yapabileceklerimizden de bahsetmekte fayda var: Green Yazılım, Red Yazılım konusuna değinmeliyiz. Green yazılım küresel ısınma probleminin çözümüne katkı sağlayan çevre-dostu yazılım demektir.

C# ve TypeScript az enerji tüketen green yazılım kategorisinde değerlendirilirken, Python henüz çok fazla enerji tüketen ve dolayısıyla daha fazla karbon salınımı yapmakta ve biz bu durumun düzeltilmesini beklemekteyiz.

BlockChain PoW algoritması ve madencilik çok fazla karbon salınımı yaparken, PoS ve PoA algoritmaları daha çevrecidir, gibi küresel ısınma konusunda farkındalık kazandırılabilir.

Mutlu kodlamalar 🙂

React Native Hooks


React Native Hooks, React.js kütüphanesinin mobil uygulamalar için uyarlanmış versiyonudur. Hooks, komponentlerinizi daha esnek ve verimli hale getirmek için kullanabileceğiniz fonksiyonlar sunar. Öncelikle, Hooks ile state veya diğer React özelliklerini komponentleriniz dışında da kullanabilirsiniz. Ayrıca, Hooks ile komponentler arasında veri paylaşımını veya fonksiyonların tekrar kullanımını kolaylaştırabilirsiniz.

En yaygın kullanılan Hooks arasında useState ve useEffect bulunur. useState, bir komponentin state’ini yönetmek için kullanılır ve useEffect ise komponentin mount edilmesi veya güncellenmesi sırasında çalışmasını sağlar. Örneğin, useEffect ile bir komponentin başlangıçta veri çekmesini veya bir event’e cevap vermesini sağlayabilirsiniz.

React Native Hooks kullanımı, React.js kullanmaya alışkın olanlar için oldukça kolaydır. Ayrıca, Hooks sayesinde kodunuz daha okunaklı ve anlaşılır hale gelecektir. Özellikle, projeleriniz büyüdükçe veya takım içinde geliştirilmeye başladıkça Hooks’un faydasını daha iyi göreceksiniz.

Örnek olarak, useState Hook’u kullanarak bir komponentin içinde state tanımlayabilirsiniz:

import React, { useState } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </>
  );
}

Bu örnekte, useState Hook’u kullanarak count adında bir state tanımladık ve setCount fonksiyonunu kullanarak state’i güncelledik. Ayrıca, bir düğmeye tıklama olayı eklendi ve tıklama olayına göre count state’ini arttırdık.

useEffect Hook’u da kullanarak komponentin bir etki yaratmasını sağlayabilirsiniz:

import React, { useState, useEffect } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `Count: ${count}`;
  }, [count]);

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </>
  );
}

Bu örnekte, useEffect Hook’u kullanarak sayfa başlığının count state’ine göre değişmesini sağladık.

React Native Hook’larının Listesi:

  1. useState: Komponent içinde state tanımlamak için kullanılır. Örnekteki gibi, değer ve değeri güncellemek için kullanılan bir fonksiyon döndürür.
  2. useEffect: Komponentin bir etki yaratmasını sağlar. Örnekteki gibi, componentDidMount, componentDidUpdate ve componentWillUnmount işlevlerini karşılamak için kullanılır.
  3. useContext: Context API’yı kullanmak için kullanılır. Bu Hook ile, bir context değerini ve bu değerin değiştiğinde çalışacak bir fonksiyon alabilirsiniz.
  4. useReducer: Reducer fonksiyonlarını kullanmak için kullanılır. Bu Hook ile, state’in nasıl güncelleneceğini tanımlayan bir fonksiyon ve başlangıç değeri alabilirsiniz.
  5. useCallback: Komponentin yeniden render edilme sıklığını azaltmak için kullanılır. Bu Hook ile, tekrar kullanılacak bir fonksiyon ve dependancy array oluşturabilirsiniz.
  6. useMemo: Komponentin performansını arttırmak için kullanılır. Bu Hook ile, tekrar hesaplanması gereken bir değer ve dependancy array oluşturabilirsiniz.
  7. useRef: DOM referanslarını veya komponent içi referansları almak için kullanılır.
  8. useImperativeHandle: Komponentin kontrol edilmesini sağlamak için kullanılır.
  9. useLayoutEffect: useEffect ile aynı ama layout ve paint işlemleri tamamlandıktan sonra çalışır.
  10. useDebugValue: Hook’un ne için kullanıldığını görmek için kullanılır.

Son olarak, React Native Hooks ile geliştirme yaparken aşağıdaki kurallara dikkat etmeniz gerekir:

  • Hooks, sadece React fonksiyonel komponentlerinde veya komponent fonksiyonları içinde kullanılabilir.
  • Hooks, fonksiyonel komponentlerin en üst seviyesinde veya event handler fonksiyonları içinde çağrılmalıdır.
  • Hooks, her render edildiğinde aynı sırada ve aynı değerlerle çağrılmalıdır.

Umarım, React Native Hooks hakkında bu bilgiler faydalı olmuştur ve projelerinizde kullanmaya başlamanızda size yardımcı olmuştur.

Mutlu kodlamalar 🙂

Not: Bu makale ChatGPT’den yararlanılarak hazırlanmıştır.

Python ve Kafka Kullanan Microservice Mimarisi


Merhaba değerli takipçilerim,

ChatGPT’ten Python ve Kafka kullanarak örnek bir Microservice mimarisi hazırlamasını istedim. Ve cevaplara göre bu makaleyi hazırladım.

Öncelikle Producer, Consumer ve API Gateway sınıflarına ihtiyacımız var ve sonra bu Producer ve Consumer sınıflarını kullanarak mikroservislerimizi kodluyoruz.

Microservice Mimarisi:

  1. Producer
  2. Consumer
  3. API Gateway
  4. Microservice’ler
  5. Zookeeper

1. Producer

Cassandra veritabanından sürekli güncel veriyi alıp Kafkaya gönderen örnek bir Producer yazdırdım:

from cassandra.cluster import Cluster
from kafka import KafkaProducer
import json

cluster = Cluster(['127.0.0.1'])
session = cluster.connect()
producer = KafkaProducer(bootstrap_servers='localhost:9092')

# Create a keyspace and table
session.execute("""
    CREATE KEYSPACE IF NOT EXISTS mykeyspace
    WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 }
""")
session.execute("""
    CREATE TABLE IF NOT EXISTS mykeyspace.data (
        id int PRIMARY KEY,
        value text
    )
""")

# Function to retrieve data from Cassandra
def get_data_from_cassandra():
    rows = session.execute("SELECT * FROM mykeyspace.data")
    data = []
    for row in rows:
        data.append({'id': row.id, 'value': row.value})
    return data

# Function to send data to Kafka topic
def send_data_to_kafka(topic, data):
    for item in data:
        producer.send(topic, value=json.dumps(item))
    producer.flush()

# Continuously poll for new data in Cassandra
while True:
    data = get_data_from_cassandra()
    send_data_to_kafka("example_topic", data)

2. Consumer

from kafka import KafkaConsumer, KafkaProducer
import json

# Create a Kafka consumer to subscribe to a specific topic
consumer = KafkaConsumer('example_topic', bootstrap_servers='localhost:9092')

# Create a Kafka producer to send messages to a specific topic
producer = KafkaProducer(bootstrap_servers='localhost:9092')

# Define a function that performs a specific task
def process_data(data):
    # Perform some task on the data, such as transforming or analyzing it
    result = data * 2
    return result

# Continuously poll for new messages on the topic
for message in consumer:
    # Deserialize the message
    data = json.loads(message.value)
    # Process the data and send the result to another topic
    result = process_data(data)
    producer.send('result_topic', value=json.dumps(result))
    producer.flush()

3. API Gateway (FastAPI kullandım)

from fastapi import FastAPI, Request, HTTPException
from kafka import KafkaProducer, KafkaConsumer
import json

app = FastAPI()
producer = KafkaProducer(bootstrap_servers='localhost:9092')

@app.post("/data/{topic}")
async def send_data(request: Request, topic: str):
    data = await request.json()
    producer.send(topic, value=json.dumps(data))
    producer.flush()
    return {"status": "success"}

@app.get("/data/{topic}")
def receive_data(topic: str):
    consumer = KafkaConsumer(topic, bootstrap_servers='localhost:9092')
    data = []
    for message in consumer:
        data.append(json.loads(message.value))
    return data

@app.get("/topics")
def get_topics():
    try:
        consumer = KafkaConsumer(bootstrap_servers='localhost:9092')
        topics = consumer.topics()
        return topics
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

4. Microservice

from kafka import KafkaConsumer, KafkaProducer
import json

# Create a Kafka consumer to subscribe to a specific topic
consumer = KafkaConsumer('example_topic', bootstrap_servers='localhost:9092')

# Create a Kafka producer to send messages to a specific topic
producer = KafkaProducer(bootstrap_servers='localhost:9092')

# Define a function that performs a specific task
def process_data(data):
    # Perform some task on the data, such as transforming or analyzing it
    result = data * 2
    return result

# Continuously poll for new messages on the topic
for message in consumer:
    # Deserialize the message
    data = json.loads(message.value)
    # Process the data and send the result to another topic
    result = process_data(data)
    producer.send('result_topic', value=json.dumps(result))
    producer.flush()

5. ZooKeeper

Apache ZooKeeper, genellikle Apache Kafka ile birlikte kullanılan bir dağıtık koordinasyon hizmetidir. İşte Python’da bir ZooKeeper örneğini kurmak için bir örnek kod:

from kazoo.client import KazooClient

zk = KazooClient(hosts='localhost:2181')
zk.start()

# create a znode
zk.create("/my_znode", b"my_data")

# check if znode exists
if zk.exists("/my_znode"):
    print("Znode exists.")

# get data from znode
data, stat = zk.get("/my_znode")
print("Version: %s, data: %s" % (stat.version, data.decode("utf-8")))

# update data in znode
zk.set("/my_znode", b"new_data")

# delete a znode
zk.delete("/my_znode")

zk.stop()

Bu örnekte, kazoo kütüphanesini kullanarak localhost’ta 2181 portunda çalışan bir ZooKeeper örneği ile etkileşim kuruyoruz. Kod yeni bir znode oluşturuyor ve adı “/my_znode” ile veri “my_data” ile, znode var mı diye kontrol ediyor, veriyi alıyor, güncelliyor ve znode’u siliyor. Lütfen unutmayın ki bu sadece bir örnektir, üretim ortamında kullanmadan önce uygun hata yönetimi ve testleri yapmanız gerekir, ayrıca host, port ve tüm parametrelerin kullanılan zookeeper kümesinin özelleştirilmiş yapılandırmasına göre ayarlanması gerekir.

Değerli takipçilerim, bu makale Python ve Kafka ile mikroservis mimarisine giriş seviyesinde olup Producer ve Consumer kodlarının TOPIC parametresini kullanacak şekilde sınıflara dönüştürülmesi gerektiği kanaatimdeyim. Bu görevi şimdilik sizlere bırakıyorum.

Mutlu kodlamalar 🙂

.NET 7 ile Makine Öğrenmesi


ChatGPT hayatımıza girdiğinden bu yana yazılım öğrenmek ve öğretmek daha kolay oldu. Mesela .NET’te BotSharp gibi hiçbir üçüncü parti kütüphane kullanmadan ChatBot nasıl geliştirebilirim diye merak ettiniz mi? Microsoft’un geliştirdiği ML.NET ile bu mümkün.

ML.NET Microsoft’un makine öğrenmesi kütüphanesi çıkmadan önce Makine Öğrenmesi’nde C#’ta AForge.NET kullanılıyordu. Fakat o çok eskide kaldı ve onun yerini daha modern olan ML.NET aldı. ML.NET, Python kütüphaneleri ile uyumlu olsa da Python kütüphanelerinin .NET’e aktarımı işi halen sürüyor.

Mesela Microsoft Tensorflow, NLTK gibi kütüphanelerin .NET alternatiflerini hazırlayacak diye beklemekteyiz. CognitiveToolkit projesi kapatıldığından bu yana C#’ın Deep Learning çözümlerinde halen zayıf olduğunu söyleyebilirim.

Neyse ki ML.NET var ve ML.NET ile C# dilini kullanarak verilerimiz üzerinde makine öğrenmesi algoritmalarını çalıştırabiliyoruz. Google’ın Dialogflow’u ile, Python’un ChatterBot’u ile rekabet etmek nispeten zor da olsa basit bir soru-cevap verisinden sohbet botu üretmek mümkün.

İşte en ilkel haliyle bir ML.NET ChatBotu:

using System;
using Microsoft.ML;
using Microsoft.ML.Data;

namespace Chatbot
{
    class Program
    {
        static void Main(string[] args)
        {
            // Set up the ML context
            var mlContext = new MLContext();

            // Load the data
            var data = mlContext.Data.LoadFromTextFile<MessageData>(
                path: "conversations.csv",
                hasHeader: true,
                separatorChar: ','
            );

            // Split the data into training and test sets
            var trainTestData = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);
            var trainingData = trainTestData.TrainSet;
            var testData = trainTestData.TestSet;

            // Set up the pipeline
            var pipeline = mlContext.Transforms.Text.FeaturizeText(
                "Features",
                "Message"
            ).Append(mlContext.Regression.Trainers.FastTree(
                labelColumn: "Label",
                featureColumn: "Features"
            ));

            // Train the model
            var model = pipeline.Fit(trainingData);

            // Evaluate the model on the test data
            var testMetrics = mlContext.Regression.Evaluate(
                model.Transform(testData),
                labelColumn: "Label"
            );

            // Print the evaluation metrics
            Console.WriteLine("R-Squared: " + testMetrics.RSquared);
            Console.WriteLine("Mean Absolute Error: " + testMetrics.MeanAbsoluteError);

            // Use the model to predict the response to a new message
            var predictionEngine = mlContext.Model.CreatePredictionEngine<MessageData, MessagePrediction>(model);
            while (true)
            {
                Console.WriteLine("Enter a message:");
                var message = Console.ReadLine();
                if (message == "exit")
                {
                    break;
                }
                var response = predictionEngine.Predict(new MessageData
                {
                    Message = message
                });
                Console.WriteLine("Response: " + response.Response);
            }
        }
    }

    // The input data for the model.
    // This defines the shape of the data that the model expects.
    public class MessageData
    {
        [LoadColumn(0)]
        public string Message { get; set; }

        [LoadColumn(1)]
        public float Label { get; set; }
    }

    // The output of the model.
    // This defines the shape of the data that the model produces.
    public class MessagePrediction
    {
        [ColumnName("Prediction")]
        public float Response { get; set; }
    }
}

Bir başka makine öğrenmesi ise spam filtrelemesi için. Diyelim ki Twitter benzeri bir sosyal medya sitesi hazırlıyorsunuz ya da bir e-posta istemcisi ya da sunucu hazırlıyorsunuz ve makine öğrenmesi ile gelen tweetler üzerinde ya da gelen mesajlar üzerinde spam olanları tespit etmek istiyorsunuz. Veya web siteniz yorumlar bölümünde spam yorumları tespit etmek istiyorsunuz. Bunun için ML.NET ile yazabileceğiniz makine öğrenmesi kodu şöyle:

using System;
using Microsoft.ML;
using Microsoft.ML.Data;

namespace SpamFilter
{
    class Program
    {
        static void Main(string[] args)
        {
            // Set up the ML context
            var mlContext = new MLContext();

            // Load the data
            var data = mlContext.Data.LoadFromTextFile<MessageData>(
                path: "messages.csv",
                hasHeader: true,
                separatorChar: ','
            );

            // Split the data into training and test sets
            var trainTestData = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);
            var trainingData = trainTestData.TrainSet;
            var testData = trainTestData.TestSet;

            // Set up the pipeline
            var pipeline = mlContext.Transforms.Text.FeaturizeText(
                "Features",
                "Message"
            ).Append(mlContext.BinaryClassification.Trainers.FastTree(
                labelColumn: "Label",
                featureColumn: "Features"
            ));

            // Train the model
            var model = pipeline.Fit(trainingData);

            // Evaluate the model on the test data
            var testMetrics = mlContext.BinaryClassification.Evaluate(
                model.Transform(testData),
                labelColumn: "Label"
            );

            // Print the evaluation metrics
            Console.WriteLine("Accuracy: " + testMetrics.Accuracy);
            Console.WriteLine("AUC: " + testMetrics.AreaUnderRocCurve);

            // Use the model to predict whether a new message is spam or not
            var predictionEngine = mlContext.Model.CreatePredictionEngine<MessageData, MessagePrediction>(model);
            var message = new MessageData
            {
                Message = "You have won a prize! Claim it now!"
            };
            var prediction = predictionEngine.Predict(message);
            Console.WriteLine("Prediction: " + prediction.Prediction);
        }
    }

    // The input data for the model.
    // This defines the shape of the data that the model expects.
    public class MessageData
    {
        [LoadColumn(0)]
        public bool Label { get; set; }

        [LoadColumn(1)]
        public string Message { get; set; }
    }

    // The output of the model.
    // This defines the shape of the data that the model produces.
    public class MessagePrediction
    {
        [ColumnName("Prediction")]
        public bool Prediction { get; set; }
    }
}

ML.NET kütüphanesi C# eğitimlerinde mutlaka gösterilmelidir. Yapay Zeka, Makine Öğrenmesi, Derin Öğrenme için illa ki Python dilini kullanmak gerekmez, elbette ki yapay zeka projeleri için Python’da çok daha fazla paket bulunmaktadır ama temel makine öğrenmesi algoritmaları için .NET’in de sağladığı imkanları öğrenip öğretmekte fayda var.


Mutlu kodlamalar 🙂