Rất hay — mục tiêu của bạn là tự động phát hiện các cụm từ hoặc từ khóa đang được nhắc đến nhiều nhất trong một tập 10.000 tiêu đề bài viết.
Ta có thể coi đây là bài toán phát hiện xu hướng từ khóa (keyword trending detection).


🎯 Mục tiêu

Từ danh sách 10.000 tiêu đề (strings), tìm ra:

  • Các từ khóa / cụm từ phổ biến nhất
  • Có thể lọc bỏ từ dừng (stopwords) như “the”, “and”, “ở”, “của”, “tin”, “về”, “bài”, v.v.
  • (Tuỳ chọn nâng cao): Nhóm các từ có nghĩa gần nhau, ví dụ “ô tô”, “xe hơi” → cùng nhóm.

⚙️ Thuật toán cơ bản (bằng Python minh họa)

import re
from collections import Counter
from itertools import islice

# 🔹 Giả sử bạn đã có danh sách tiêu đề
titles = [
    "VinFast ra mắt mẫu xe điện mới tại Mỹ",
    "Tesla công bố doanh số xe điện tăng mạnh",
    "VinFast mở rộng nhà máy sản xuất tại Ấn Độ",
    # ... ~10k tiêu đề
]

# 🔹 Bước 1: Tiền xử lý – chuyển thường, loại ký tự đặc biệt
def clean_text(text):
    text = text.lower()
    text = re.sub(r'[^a-zA-ZÀ-Ỵà-ỵ0-9\s]', '', text)
    return text

titles_cleaned = [clean_text(t) for t in titles]

# 🔹 Bước 2: Tách từ và đếm tần suất
words = []
for t in titles_cleaned:
    words.extend(t.split())

# 🔹 Bước 3: Loại bỏ stopwords cơ bản (bạn có thể mở rộng thêm)
stopwords = {"là", "và", "của", "ở", "về", "ra", "mới", "tại", "đã", "sẽ", "cho"}
filtered_words = [w for w in words if w not in stopwords and len(w) > 2]

# 🔹 Bước 4: Đếm tần suất
counter = Counter(filtered_words)

# 🔹 Bước 5: Top 20 từ khoá phổ biến
for word, freq in counter.most_common(20):
    print(word, freq)

💡 Nâng cao 1: Phát hiện cụm 2–3 từ phổ biến (bigram/trigram)

from nltk import ngrams

bigrams = []
for t in titles_cleaned:
    tokens = [w for w in t.split() if w not in stopwords]
    bigrams.extend(ngrams(tokens, 2))  # hoặc 3 nếu muốn cụm 3 từ

counter_bi = Counter([' '.join(bg) for bg in bigrams])
print(counter_bi.most_common(20))

Ví dụ:

xe điện  153
vinfast ra  120
ra mắt  110

💡 Nâng cao 2: Gom cụm từ đồng nghĩa

Nếu bạn muốn nhóm “xe hơi”, “ô tô”, “car”, “automobile” → 1 nhóm:

  • Có thể dùng bảng synonym tự xây (dict thủ công hoặc từ WordNet).
  • Hoặc dùng embedding vector (spaCy / SentenceTransformer) để nhóm từ gần nhau bằng cosine similarity.

💡 Nâng cao 3: Đo xu hướng theo thời gian

Nếu mỗi tiêu đề có ngày đăng, ta có thể:

  • Gom theo ngày/tuần → đếm tần suất keyword
  • So sánh tốc độ tăng trưởng để phát hiện từ đang nổi.

📦 Kết quả đầu ra có thể là:

Keyword / Cụm từSố lần nhắc% trong tổngXu hướng
vinfast231223.1%🔺 tăng
xe điện187618.7%🔺 tăng mạnh
tesla132113.2%🔻 giảm

⚙️ PHP: Phát hiện từ khóa nổi bật trong danh sách tiêu đề

<?php
// 🔹 Giả sử bạn có danh sách tiêu đề
$titles = [
    "VinFast ra mắt mẫu xe điện mới tại Mỹ",
    "Tesla công bố doanh số xe điện tăng mạnh",
    "VinFast mở rộng nhà máy sản xuất tại Ấn Độ",
    "Toyota giới thiệu công nghệ pin mới cho xe điện",
    // ... (10k tiêu đề)
];

// 🔹 1. Tiền xử lý: Chuyển thường, loại ký tự đặc biệt
function clean_text($text) {
    $text = mb_strtolower($text, 'UTF-8');
    $text = preg_replace('/[^a-zA-ZÀ-Ỵà-ỵ0-9\s]/u', '', $text);
    return trim($text);
}

// 🔹 2. Danh sách stopwords (từ dừng) cơ bản tiếng Việt
$stopwords = [
    'và','là','của','ở','về','ra','mới','tại','đã','sẽ','cho','này','đang','các','những','một',
    'trong','bị','được','khi','đến','đi','năm','ngày','với','đó','từ','theo'
];

// 🔹 3. Đếm tần suất từ
$word_freq = [];

foreach ($titles as $title) {
    $clean = clean_text($title);
    $words = preg_split('/\s+/', $clean);

    foreach ($words as $w) {
        if (in_array($w, $stopwords) || mb_strlen($w) < 2) continue;
        if (!isset($word_freq[$w])) $word_freq[$w] = 0;
        $word_freq[$w]++;
    }
}

// 🔹 4. Sắp xếp giảm dần theo tần suất
arsort($word_freq);

// 🔹 5. Hiển thị top 20 từ khóa phổ biến
echo "Top 20 từ khóa phổ biến:\n";
$count = 0;
foreach ($word_freq as $word => $freq) {
    echo str_pad($word, 20) . " : " . $freq . "\n";
    if (++$count >= 20) break;
}

💡 Nâng cao: Đếm cụm từ (bigram 2 từ)

Nếu bạn muốn phát hiện cụm từ 2 từ như “xe điện”, “vinfast ra”, “ra mắt”:

<?php
$bigram_freq = [];

foreach ($titles as $title) {
    $clean = clean_text($title);
    $words = array_values(array_filter(
        preg_split('/\s+/', $clean),
        fn($w) => !in_array($w, $stopwords) && mb_strlen($w) > 2
    ));

    for ($i = 0; $i < count($words) - 1; $i++) {
        $bigram = $words[$i] . ' ' . $words[$i + 1];
        if (!isset($bigram_freq[$bigram])) $bigram_freq[$bigram] = 0;
        $bigram_freq[$bigram]++;
    }
}

arsort($bigram_freq);

echo "\nTop 20 cụm từ phổ biến:\n";
$count = 0;
foreach ($bigram_freq as $phrase => $freq) {
    echo str_pad($phrase, 25) . " : " . $freq . "\n";
    if (++$count >= 20) break;
}

📦 Gợi ý mở rộng

  • Input từ file: bạn có thể lưu danh sách 10k tiêu đề vào titles.txt (mỗi dòng 1 tiêu đề)
  • Xuất CSV cho việc phân tích thêm
  • Phân tích theo thời gian: nếu bạn có cột date, ta có thể gom nhóm theo ngày/tuần để phát hiện từ đang tăng nhanh.