app/Services/RecommendationService.php

 Produk -> Rating
            // Rating 1-5 berdasarkan histori transaksi
            $matrix[$order->user_id][$order->product_name] 
                = (float) $order->rating;
        }

        // 2. Jika user baru (Cold Start), kembalikan produk populer
        if (!isset($matrix[$userId])) {
            return $this->getPopularProducts($limit);
        }

        // 3. Hitung Cosine Similarity dengan user lain
        $userRatings = $matrix[$userId];
        $similarities = [];
        
        foreach ($matrix as $otherId => $otherRatings) {
            if ($otherId == $userId) continue;
            
            // Core Algorithm: Cosine Similarity
            $similarities[$otherId] = 
                $this->calculateCosineSimilarity($userRatings, $otherRatings);
        }

        // 4. Urutkan user yang paling mirip (Nearest Neighbors)
        arsort($similarities);
        $neighbors = array_slice($similarities, 0, 10, true);

        // 5. Prediksi skor untuk produk yang belum dibeli
        $predictions = [];
        $allProducts = $this->getAllUniqueProducts($orders);
        
        foreach ($allProducts as $productName) {
            // Skip produk yang sudah dibeli user target
            if (isset($userRatings[$productName])) continue; 

            $scoreSum = 0;
            $simSum = 0;

            foreach ($neighbors as $neighborId => $sim) {
                // Hanya hitung jika neighbor pernah membeli produk ini
                if (isset($matrix[$neighborId][$productName])) {
                    // Rumus Weighted Sum
                    $scoreSum += $sim * $matrix[$neighborId][$productName];
                    $simSum += abs($sim);
                }
            }

            if ($simSum > 0) {
                $predictions[$productName] = $scoreSum / $simSum;
            }
        }
        
        // Urutkan prediksi dari skor tertinggi
        arsort($predictions);
        return array_slice($predictions, 0, $limit, true);
    }
}
?>