Section 8/161 menit

8. Integrasi dengan Natural Language Framework

8. Integrasi dengan Natural Language Framework

Natural Language framework menggunakan Core ML untuk NLP tasks dan menyediakan pre-trained models yang tidak perlu di-download terpisah.

Text Classification Custom (Sentiment Analysis)

swift
import NaturalLanguage
import CoreML

class SentimentAnalyzer {
    private let classifier: NLModel
    
    init() throws {
        // Load custom NLP model yang di-train dengan Create ML
        let modelURL = Bundle.main.url(
            forResource: "SentimentClassifier",
            withExtension: "mlmodelc"
        )!
        classifier = try NLModel(contentsOf: modelURL)
    }
    
    enum Sentiment: String {
        case positive = "Positive"
        case negative = "Negative"
        case neutral = "Neutral"
    }
    
    func analyze(_ text: String) -> (sentiment: Sentiment, confidence: Double) {
        let prediction = classifier.predictedLabel(for: text) ?? "Neutral"
        let sentiment = Sentiment(rawValue: prediction) ?? .neutral
        
        // Dapatkan confidence untuk setiap label
        let hypotheses = classifier.predictedLabelHypotheses(for: text, maximumCount: 3)
        let confidence = hypotheses[prediction] ?? 0.5
        
        return (sentiment, confidence)
    }
    
    func analyzeBatch(_ texts: [String]) -> [(text: String, sentiment: Sentiment, confidence: Double)] {
        return texts.map { text in
            let result = analyze(text)
            return (text, result.sentiment, result.confidence)
        }
    }
}

Word Embedding dengan NLEmbedding

swift
// NLEmbedding menggunakan model pre-trained Apple — tidak perlu download
class SemanticSearchService {
    private let embedding = NLEmbedding.wordEmbedding(for: .english)!
    
    func similarity(word1: String, word2: String) -> Double {
        guard let vector1 = embedding.vector(for: word1),
              let vector2 = embedding.vector(for: word2) else { return 0 }
        
        // Cosine similarity
        let dotProduct = zip(vector1, vector2).map(*).reduce(0, +)
        let magnitude1 = sqrt(vector1.map { $0 * $0 }.reduce(0, +))
        let magnitude2 = sqrt(vector2.map { $0 * $0 }.reduce(0, +))
        
        guard magnitude1 > 0, magnitude2 > 0 else { return 0 }
        return dotProduct / (magnitude1 * magnitude2)
    }
    
    func findNearest(to word: String, from candidates: [String]) -> String? {
        guard let vector = embedding.vector(for: word) else { return nil }
        
        // NLEmbedding.nearestNeighbors — built-in approximate nearest neighbor
        let neighbors = embedding.neighbors(for: vector, maximumCount: 1)
        return neighbors.first?.0
    }
    
    // Sentence embedding menggunakan NLEmbedding sentence model (iOS 14+)
    func sentenceSimilarity(sentence1: String, sentence2: String) -> Double {
        guard let sentenceEmbedding = NLEmbedding.sentenceEmbedding(for: .english) else { return 0 }
        return sentenceEmbedding.distance(between: sentence1, and: sentence2)
    }
}