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).
Từ danh sách 10.000 tiêu đề (strings), tìm ra:
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)
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ếu bạn muốn nhóm “xe hơi”, “ô tô”, “car”, “automobile” → 1 nhóm:
Nếu mỗi tiêu đề có ngày đăng, ta có thể:
| Keyword / Cụm từ | Số lần nhắc | % trong tổng | Xu hướng |
|---|---|---|---|
| vinfast | 2312 | 23.1% | 🔺 tăng |
| xe điện | 1876 | 18.7% | 🔺 tăng mạnh |
| tesla | 1321 | 13.2% | 🔻 giảm |
<?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ế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;
}
titles.txt (mỗi dòng 1 tiêu đề) date, ta có thể gom nhóm theo ngày/tuần để phát hiện từ đang tăng nhanh.