Cách tốt nhất để tính toán các chủ đề hoặc thẻ xu hướng là gì?


183

Nhiều trang web cung cấp một số thống kê như "Các chủ đề nóng nhất trong 24 giờ qua". Ví dụ: Topix.com cho thấy điều này trong phần "Xu hướng tin tức". Ở đó, bạn có thể thấy các chủ đề có số lượng đề cập tăng nhanh nhất.

Tôi cũng muốn tính toán "buzz" cho một chủ đề. Làm thế nào tôi có thể làm điều này? Thuật toán nên cân nhắc các chủ đề luôn nóng. Các chủ đề mà bình thường (gần như) không ai đề cập đến nên là những chủ đề nóng nhất.

Google cung cấp "Xu hướng nóng", topix.com hiển thị "Chủ đề nóng", fav.or.it hiển thị "Xu hướng từ khóa" - tất cả các dịch vụ này đều có một điểm chung: Chúng chỉ hiển thị cho bạn các xu hướng sắp tới đang nóng bất thường vào lúc này.

Các thuật ngữ như "Britney Spears", "thời tiết" hoặc "Paris Hilton" sẽ không xuất hiện trong các danh sách này vì chúng luôn nóng và thường xuyên. Bài viết này gọi đây là "Vấn đề Britney Spears".

Câu hỏi của tôi: Làm thế nào bạn có thể mã hóa một thuật toán hoặc sử dụng một thuật toán hiện có để giải quyết vấn đề này? Có một danh sách với các từ khóa được tìm kiếm trong 24 giờ qua, thuật toán sẽ hiển thị cho bạn 10 từ khóa (ví dụ) nóng nhất.

Tôi biết, trong bài viết trên, có một số loại thuật toán được đề cập. Tôi đã cố gắng viết mã bằng PHP nhưng tôi không nghĩ rằng nó sẽ hoạt động. Nó chỉ tìm thấy đa số, phải không?

Tôi hy vọng bạn có thể giúp tôi (ví dụ mã hóa sẽ là tuyệt vời).


4
Câu hỏi thú vị, tò mò muốn xem mọi người nói gì.
mmcdole

14
Không có lý do để đóng, đây là một câu hỏi hợp lệ
TStamper

1
Đây chính xác là cùng một câu hỏi và ông thậm chí còn nói rằng! Tại sao mọi người nâng cao nó!
Darryl Hein

3
Tôi hơi bối rối về loại kết quả mà bạn đang tìm kiếm. Bài báo dường như chỉ ra rằng "Britney Spears" sẽ liên tục được tìm thấy trong danh sách "Hot" bởi vì rất nhiều người tìm kiếm cụm từ đó, nhưng câu hỏi của bạn nói rằng nó sẽ KHÔNG xuất hiện trong danh sách vì số lượng tìm kiếm cho cụm từ đó không tăng nhiều theo thời gian (chúng vẫn cao, nhưng ổn định). Kết quả nào bạn đang cố gắng để đạt được? "Britney Spears" nên xếp hạng cao hay thấp?
e.James

1
@eJames, "Britney Spears" không nên xếp hạng cao vì cô ấy luôn có cụm từ tìm kiếm cao và anh ấy đang tìm kiếm cụm từ tìm kiếm với vận tốc cao.
mmcdole

Câu trả lời:


103

Vấn đề này đòi hỏi điểm z hoặc điểm chuẩn, sẽ tính đến mức trung bình lịch sử, như những người khác đã đề cập, nhưng cũng là độ lệch chuẩn của dữ liệu lịch sử này, làm cho nó mạnh hơn so với chỉ sử dụng mức trung bình.

Trong trường hợp của bạn, điểm z được tính theo công thức sau, trong đó xu hướng sẽ là tỷ lệ như lượt xem / ngày.

z-score = ([current trend] - [average historic trends]) / [standard deviation of historic trends]

Khi sử dụng điểm z, điểm z càng cao hoặc thấp thì xu hướng càng bất thường, vì vậy, nếu điểm z có giá trị dương cao thì xu hướng tăng bất thường, trong khi nếu âm rất cao thì nó lại giảm bất thường. . Vì vậy, một khi bạn tính điểm z cho tất cả các xu hướng ứng cử viên, 10 điểm z cao nhất sẽ liên quan đến điểm z tăng bất thường nhất.

Vui lòng xem Wikipedia để biết thêm thông tin, về điểm z.

from math import sqrt

def zscore(obs, pop):
    # Size of population.
    number = float(len(pop))
    # Average population value.
    avg = sum(pop) / number
    # Standard deviation of population.
    std = sqrt(sum(((c - avg) ** 2) for c in pop) / number)
    # Zscore Calculation.
    return (obs - avg) / std

Đầu ra mẫu

>>> zscore(12, [2, 4, 4, 4, 5, 5, 7, 9])
3.5
>>> zscore(20, [21, 22, 19, 18, 17, 22, 20, 20])
0.0739221270955
>>> zscore(20, [21, 22, 19, 18, 17, 22, 20, 20, 1, 2, 3, 1, 2, 1, 0, 1])
1.00303599234
>>> zscore(2, [21, 22, 19, 18, 17, 22, 20, 20, 1, 2, 3, 1, 2, 1, 0, 1])
-0.922793112954
>>> zscore(9, [1, 2, 0, 3, 1, 3, 1, 2, 9, 8, 7, 10, 9, 5, 2, 4, 1, 1, 0])
1.65291949506

Ghi chú

  • Bạn có thể sử dụng phương pháp này với một cửa sổ trượt (tức là 30 ngày qua) nếu bạn không muốn tính đến nhiều lịch sử, điều này sẽ làm cho các xu hướng ngắn hạn rõ rệt hơn và có thể cắt giảm thời gian xử lý.

  • Bạn cũng có thể sử dụng điểm z cho các giá trị, chẳng hạn như thay đổi lượt xem từ một ngày sang ngày tiếp theo để xác định các giá trị bất thường để tăng / giảm lượt xem mỗi ngày. Điều này giống như sử dụng độ dốc hoặc đạo hàm của biểu đồ mỗi ngày.

  • Nếu bạn theo dõi kích thước hiện tại của dân số, tổng dân số hiện tại và tổng số x ^ 2 hiện tại của dân số, bạn không cần phải tính toán lại các giá trị này, chỉ cần cập nhật chúng và do đó bạn chỉ cần giữ các giá trị này cho lịch sử, không phải mỗi giá trị dữ liệu. Các mã sau đây chứng minh điều này.

    from math import sqrt
    
    class zscore:
        def __init__(self, pop = []):
            self.number = float(len(pop))
            self.total = sum(pop)
            self.sqrTotal = sum(x ** 2 for x in pop)
        def update(self, value):
            self.number += 1.0
            self.total += value
            self.sqrTotal += value ** 2
        def avg(self):
            return self.total / self.number
        def std(self):
            return sqrt((self.sqrTotal / self.number) - self.avg() ** 2)
        def score(self, obs):
            return (obs - self.avg()) / self.std()
    
  • Sử dụng phương pháp này luồng công việc của bạn sẽ như sau. Đối với mỗi chủ đề, thẻ hoặc trang tạo một trường dấu phẩy động, cho tổng số ngày, tổng số lượt xem và tổng số lượt xem bình phương trong cơ sở dữ liệu của bạn. Nếu bạn có dữ liệu lịch sử, hãy khởi tạo các trường này bằng dữ liệu đó, nếu không thì khởi tạo thành không. Vào cuối mỗi ngày, hãy tính điểm z bằng cách sử dụng số lượt xem trong ngày so với dữ liệu lịch sử được lưu trữ trong ba trường cơ sở dữ liệu. Các chủ đề, thẻ hoặc trang có điểm số z z cao nhất là "xu hướng nóng nhất" trong ngày của bạn. Cuối cùng cập nhật từng trường trong số 3 trường với giá trị của ngày và lặp lại quy trình vào ngày mai.

Bổ sung mới

Điểm z thông thường như được thảo luận ở trên không tính đến thứ tự của dữ liệu và do đó, điểm z cho quan sát '1' hoặc '9' sẽ có cùng độ lớn so với chuỗi [1, 1, 1, 1 , 9, 9, 9, 9]. Rõ ràng đối với việc tìm kiếm xu hướng, dữ liệu mới nhất nên có trọng số lớn hơn dữ liệu cũ và do đó chúng tôi muốn quan sát '1' có điểm số lớn hơn so với quan sát '9'. Để đạt được điều này, tôi đề xuất một điểm z trung bình nổi. Cần phải rõ ràng rằng phương pháp này KHÔNG được đảm bảo là hợp lý về mặt thống kê nhưng sẽ hữu ích cho việc tìm kiếm xu hướng hoặc tương tự. Sự khác biệt chính giữa điểm z chuẩn và điểm z trung bình nổi là việc sử dụng trung bình nổi để tính giá trị dân số trung bình và giá trị dân số trung bình bình phương. Xem mã để biết chi tiết:

class fazscore:
    def __init__(self, decay, pop = []):
        self.sqrAvg = self.avg = 0
        # The rate at which the historic data's effect will diminish.
        self.decay = decay
        for x in pop: self.update(x)
    def update(self, value):
        # Set initial averages to the first value in the sequence.
        if self.avg == 0 and self.sqrAvg == 0:
            self.avg = float(value)
            self.sqrAvg = float((value ** 2))
        # Calculate the average of the rest of the values using a 
        # floating average.
        else:
            self.avg = self.avg * self.decay + value * (1 - self.decay)
            self.sqrAvg = self.sqrAvg * self.decay + (value ** 2) * (1 - self.decay)
        return self
    def std(self):
        # Somewhat ad-hoc standard deviation calculation.
        return sqrt(self.sqrAvg - self.avg ** 2)
    def score(self, obs):
        if self.std() == 0: return (obs - self.avg) * float("infinity")
        else: return (obs - self.avg) / self.std()

IO mẫu

>>> fazscore(0.8, [1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9]).score(1)
-1.67770595327
>>> fazscore(0.8, [1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9]).score(9)
0.596052006642
>>> fazscore(0.9, [2, 4, 4, 4, 5, 5, 7, 9]).score(12)
3.46442230724
>>> fazscore(0.9, [2, 4, 4, 4, 5, 5, 7, 9]).score(22)
7.7773245459
>>> fazscore(0.9, [21, 22, 19, 18, 17, 22, 20, 20]).score(20)
-0.24633160155
>>> fazscore(0.9, [21, 22, 19, 18, 17, 22, 20, 20, 1, 2, 3, 1, 2, 1, 0, 1]).score(20)
1.1069362749
>>> fazscore(0.9, [21, 22, 19, 18, 17, 22, 20, 20, 1, 2, 3, 1, 2, 1, 0, 1]).score(2)
-0.786764452966
>>> fazscore(0.9, [1, 2, 0, 3, 1, 3, 1, 2, 9, 8, 7, 10, 9, 5, 2, 4, 1, 1, 0]).score(9)
1.82262469243
>>> fazscore(0.8, [40] * 200).score(1)
-inf

Cập nhật

Như David Kemp đã chỉ ra một cách chính xác, nếu đưa ra một loạt các giá trị không đổi và sau đó một zscore cho một giá trị quan sát khác với các giá trị khác được yêu cầu, kết quả có thể phải khác không. Trong thực tế, giá trị trả về phải là vô cùng. Vì vậy, tôi đã thay đổi dòng này,

if self.std() == 0: return 0

đến:

if self.std() == 0: return (obs - self.avg) * float("infinity")

Sự thay đổi này được phản ánh trong mã giải pháp fazscore. Nếu một người không muốn đối phó với các giá trị vô hạn, một giải pháp có thể chấp nhận thay vào đó có thể thay đổi dòng thành:

if self.std() == 0: return obs - self.avg

1
Không, mã của bạn có một lỗi nhỏ, trên dòng sau. $ z_score = $ hit_today - ($ Average_hits_per_day / $ standard_deviation); Nó phải là: $ z_score = ($ hit_today- $ Average_hits_per_day) / $ standard_deviation; Lưu ý sự thay đổi trong ngoặc đơn.
Nixuz

1
@nixuz - Tôi có thiếu thứ gì không: fazscore (0.8, map (lambda x: 40, phạm vi (0,200))). điểm (1) == 0 (cho bất kỳ giá trị nào)?
kͩeͣmͮpͥ 17/12/2016

1
@Nixus - Nghĩ rằng tôi có thể đào cái này từ ngôi mộ. Bạn có thể đăng lại việc thực hiện PHP này không? Các pasteliên kết dường như không hoạt động ... cảm ơn!
Sự lôi cuốn

1
Đối với bất kỳ ai muốn nó, bây giờ tôi có các truy vấn SQL để làm điều này.
thouliha 8/2/2016

1
Sự phân rã ở đây là phản trực giác; nếu bạn nhập 2 giá trị, giả sử [10, 20] với độ phân rã là 0,8, AVG là 10 * 0,8 + 20 * 0,2 = 12. Bạn sẽ mong đợi một giá trị trên 15, vì 20 nên có trọng lượng lớn hơn 10 nếu có sâu răng. Có một sự thay thế tốt hơn nhiều có sẵn bằng cách sử dụng mức trung bình có trọng số trong numpy.alusive, nơi bạn tạo một danh sách song song với các trọng số. Ví dụ: data = phạm vi (10,30,10) decay = 0,8 decay_weights = [decay ** a cho một phạm vi (len (dữ liệu), 0, -1)] in np.alusive (data, weights = decay_weights)
Jeroen

93

Bạn cần một thuật toán đo vận tốc của một chủ đề - hay nói cách khác, nếu bạn vẽ biểu đồ, bạn muốn hiển thị những thuật toán đang tăng lên với tốc độ đáng kinh ngạc.

Đây là đạo hàm đầu tiên của đường xu hướng và không khó để kết hợp như một yếu tố trọng số của tính toán tổng thể của bạn.

Bình thường hóa

Một kỹ thuật bạn sẽ cần làm là bình thường hóa tất cả dữ liệu của mình. Đối với mỗi chủ đề bạn đang theo dõi, hãy giữ bộ lọc thông qua rất thấp xác định đường cơ sở của chủ đề đó. Bây giờ mọi điểm dữ liệu liên quan đến chủ đề đó nên được chuẩn hóa - trừ đi đường cơ sở của nó và bạn sẽ nhận được TẤT CẢ các chủ đề của mình gần 0, với các gai trên và dưới dòng. Thay vào đó, bạn có thể muốn chia tín hiệu theo cường độ cơ sở của nó, điều này sẽ đưa tín hiệu về khoảng 1.0 - điều này không chỉ mang tất cả các tín hiệu thẳng hàng với nhau (bình thường hóa đường cơ sở), mà còn bình thường hóa các xung. Một cành britney sẽ có cường độ lớn hơn gai của người khác, nhưng điều đó không có nghĩa là bạn nên chú ý đến nó - mũi nhọn có thể rất nhỏ so với đường cơ sở của cô ấy.

Lấy được

Khi bạn đã bình thường hóa mọi thứ, hãy tìm ra độ dốc của từng chủ đề. Lấy hai điểm liên tiếp, và đo sự khác biệt. Một sự khác biệt tích cực đang có xu hướng tăng lên, một sự khác biệt tiêu cực đang có xu hướng giảm. Sau đó, bạn có thể so sánh sự khác biệt được chuẩn hóa và tìm hiểu những chủ đề nào đang trở nên phổ biến so với các chủ đề khác - với mỗi chủ đề được chia tỷ lệ phù hợp với 'bình thường' có thể là mức độ khác nhau của các chủ đề khác.

Đây thực sự là một vượt qua đầu tiên tại vấn đề. Có nhiều kỹ thuật tiên tiến hơn mà bạn sẽ cần sử dụng (chủ yếu là sự kết hợp của các thuật toán trên với các thuật toán khác, có trọng số phù hợp với nhu cầu của bạn) nhưng nó đủ để bạn bắt đầu.

Về bài viết

Bài viết nói về xu hướng chủ đề, nhưng không phải là về cách tính toán những gì hấp dẫn và những gì không, đó là về cách xử lý lượng thông tin khổng lồ mà thuật toán đó phải xử lý ở những nơi như Lycos và Google. Không gian và thời gian cần thiết để cung cấp cho mỗi chủ đề một bộ đếm và tìm bộ đếm của từng chủ đề khi tìm kiếm trên đó là rất lớn. Bài viết này là về những thách thức mà một người phải đối mặt khi cố gắng thực hiện một nhiệm vụ như vậy. Nó không đề cập đến hiệu ứng Brittney, nhưng nó không nói về cách khắc phục nó.

Như Nixuz chỉ ra, điều này cũng được gọi là Điểm Z hoặc Điểm chuẩn .


1
Tôi đã nâng cấp nó trước khi chỉnh sửa, và quay lại và tôi muốn nâng cấp nó một lần nữa! Làm tốt lắm
mmcdole

Cảm ơn! Tôi sẽ làm mã giả, nhưng tôi không có thời gian ngay bây giờ. Có thể sau này, hoặc có lẽ ai đó sẽ lấy những khái niệm này và thực hiện nó ...
Adam Davis

Cảm ơn bạn rất nhiều, Adam Davis! Nếu Nixuz thực sự mô tả giống như vậy, tôi nghĩ rằng tôi đã có một giải pháp trong PHP: paste.bradleygill.com/index.php?paste_id=9206 Bạn có nghĩ mã này là đúng không?
caw

Không phải là tăng tốc của chủ đề chứ không phải là vận tốc? Kiểm tra câu trả lời cuối cùng
Sap

17

Chad Birch và Adam Davis chính xác ở chỗ bạn sẽ phải nhìn về phía sau để thiết lập đường cơ sở. Câu hỏi của bạn, như được đặt ra, gợi ý rằng bạn chỉ muốn xem dữ liệu trong 24 giờ qua và điều đó sẽ không hoàn toàn bay.

Một cách để cung cấp cho dữ liệu của bạn một số bộ nhớ mà không phải truy vấn cho một khối lượng lớn dữ liệu lịch sử là sử dụng trung bình di chuyển theo cấp số nhân. Ưu điểm của việc này là bạn có thể cập nhật thông tin này một lần mỗi kỳ và sau đó xóa tất cả dữ liệu cũ, vì vậy bạn chỉ cần nhớ một giá trị duy nhất. Vì vậy, nếu thời gian của bạn là một ngày, bạn phải duy trì thuộc tính "trung bình hàng ngày" cho mỗi chủ đề, bạn có thể thực hiện bằng cách:

a_n = a_(n-1)*b + c_n*(1-b)

Trường hợp a_ntrung bình di chuyển tính đến ngày n, b là một số không đổi trong khoảng từ 0 đến 1 (càng gần 1, bộ nhớ càng dài) và c_nlà số lần truy cập trong ngày n. Vẻ đẹp là nếu bạn thực hiện cập nhật này vào cuối ngày n, bạn có thể tuôn ra c_na_(n-1).

Một lưu ý là ban đầu nó sẽ nhạy cảm với bất cứ thứ gì bạn chọn cho giá trị ban đầu của bạn a.

BIÊN TẬP

Nếu nó giúp để hình dung cách tiếp cận này, hãy n = 5, a_0 = 1b = .9.

Giả sử các giá trị mới là 5,0,0,1,4:

a_0 = 1
c_1 = 5 : a_1 = .9*1 + .1*5 = 1.4
c_2 = 0 : a_2 = .9*1.4 + .1*0 = 1.26
c_3 = 0 : a_3 = .9*1.26 + .1*0 = 1.134
c_4 = 1 : a_4 = .9*1.134 + .1*1 = 1.1206
c_5 = 4 : a_5 = .9*1.1206 + .1*5 = 1.40854

Không giống như một mức trung bình phải không? Lưu ý cách giá trị ở gần 1, mặc dù đầu vào tiếp theo của chúng tôi là 5. Điều gì đang xảy ra? Nếu bạn mở rộng toán học, bạn sẽ nhận được điều đó:

a_n = (1-b)*c_n + (1-b)*b*c_(n-1) + (1-b)*b^2*c_(n-2) + ... + (leftover weight)*a_0

Tôi có ý nghĩa gì bởi trọng lượng còn lại? Chà, ở bất kỳ mức trung bình nào, tất cả các trọng số đều phải cộng thêm 1. Nếu n là vô cùng và ... có thể kéo dài mãi mãi, thì tất cả các trọng số sẽ bằng 1. Nhưng nếu n tương đối nhỏ, bạn sẽ có một lượng cân nặng còn lại trên đầu vào ban đầu.

Nếu bạn nghiên cứu công thức trên, bạn sẽ nhận ra một vài điều về cách sử dụng này:

  1. Tất cả dữ liệu đóng góp một cái gì đó đến trung bình mãi mãi. Thực tế mà nói, có một điểm mà sự đóng góp thực sự rất nhỏ.
  2. Các giá trị gần đây đóng góp nhiều hơn các giá trị cũ.
  3. B càng cao, giá trị mới càng ít quan trọng và giá trị cũ càng dài. Tuy nhiên, b càng cao, bạn càng cần nhiều dữ liệu để giảm giá trị ban đầu của a.

Tôi nghĩ rằng hai đặc điểm đầu tiên chính xác là những gì bạn đang tìm kiếm. Để cung cấp cho bạn một ý tưởng đơn giản có thể thực hiện, đây là một triển khai python (trừ tất cả các tương tác cơ sở dữ liệu):

>>> class EMA(object):
...  def __init__(self, base, decay):
...   self.val = base
...   self.decay = decay
...   print self.val
...  def update(self, value):
...   self.val = self.val*self.decay + (1-self.decay)*value
...   print self.val
... 
>>> a = EMA(1, .9)
1
>>> a.update(10)
1.9
>>> a.update(10)
2.71
>>> a.update(10)
3.439
>>> a.update(10)
4.0951
>>> a.update(10)
4.68559
>>> a.update(10)
5.217031
>>> a.update(10)
5.6953279
>>> a.update(10)
6.12579511
>>> a.update(10)
6.513215599
>>> a.update(10)
6.8618940391
>>> a.update(10)
7.17570463519

1
Đây còn được gọi là bộ lọc đáp ứng xung vô hạn (IIR)
Adam Davis

Này một phiên bản tốt hơn của câu trả lời của tôi.
Joshua

@Adam Thật sao? Tôi không quen thuộc với họ. Đây có phải là trường hợp đặc biệt của IIR không? Các bài viết tôi lướt qua dường như không cung cấp các công thức giảm xuống mức trung bình di chuyển theo cấp số nhân trong trường hợp đơn giản.
David Berger

Cảm ơn bạn rất nhiều, David Berger! Nếu nó hoạt động, nó sẽ là một bổ sung tuyệt vời cho các câu trả lời khác! Tôi có một số câu hỏi, mặc dù. Tôi hy vọng bạn có thể trả lời chúng: 1) Yếu tố b có xác định dữ liệu cũ giảm cân nhanh như thế nào không? 2) Cách tiếp cận này sẽ cho kết quả tương đương so với việc lưu trữ dữ liệu cũ và tính trung bình? 3) Đây có phải là công thức của bạn trong lời nói? $ average_value = $ old_average_value * $ smoothing_factor + $ hits_today * (1- $ smoothing_factor)
caw

Điểm 1 và 3 đều đúng. Xem bản chỉnh sửa của tôi để biết một chút thảo luận về sắc thái của 2.
David Berger

8

Thông thường "buzz" được tìm ra bằng cách sử dụng một số dạng cơ chế phân rã theo cấp số nhân / log. Để biết tổng quan về cách Hacker News, Reddit và những người khác xử lý việc này một cách đơn giản, hãy xem bài đăng này .

Điều này không giải quyết đầy đủ những điều luôn luôn phổ biến. Những gì bạn đang tìm kiếm có vẻ giống như tính năng " Xu hướng nóng " của Google . Vì thế, bạn có thể chia giá trị hiện tại cho một giá trị lịch sử và sau đó trừ đi những giá trị nằm dưới ngưỡng nhiễu.


Đúng, Xu hướng nóng của Google chính xác là những gì tôi đang tìm kiếm. Giá trị lịch sử nên là gì? Giá trị trung bình của 7 ngày qua chẳng hạn?
caw

1
Nó phụ thuộc vào mức độ biến động dữ liệu của bạn. Bạn có thể bắt đầu với trung bình 30 ngày. Nếu đó là một việc theo chu kỳ (ví dụ Kentucky Derby) thì có thể có ý nghĩa để so sánh hàng năm. Tôi đã thử nghiệm và xem những gì hoạt động tốt nhất trong thực tế.
Jeff Moser

7

Tôi nghĩ rằng từ khóa mà bạn cần chú ý là "bất thường". Để xác định khi nào có gì đó "bất thường", bạn phải biết điều gì là bình thường. Đó là, bạn sẽ cần dữ liệu lịch sử, mà bạn có thể trung bình để tìm ra tỷ lệ bình thường của một truy vấn cụ thể. Bạn có thể muốn loại trừ những ngày bất thường khỏi tính toán trung bình, nhưng một lần nữa điều đó sẽ yêu cầu phải có đủ dữ liệu, để bạn biết ngày nào cần loại trừ.

Từ đó, bạn sẽ phải đặt ngưỡng (sẽ yêu cầu thử nghiệm, tôi chắc chắn) và nếu có gì đó vượt quá ngưỡng, hãy nói rằng tìm kiếm nhiều hơn 50% so với bình thường, bạn có thể coi đó là "xu hướng". Hoặc, nếu bạn muốn có thể tìm thấy "Top X Trendiest" như bạn đã đề cập, bạn chỉ cần đặt hàng mọi thứ theo cách xa (tỷ lệ phần trăm) mà chúng cách xa mức bình thường.

Ví dụ: giả sử dữ liệu lịch sử của bạn đã nói với bạn rằng Britney Spears thường nhận được 100.000 lượt tìm kiếm và Paris Hilton thường nhận được 50.000. Nếu bạn có một ngày cả hai nhận được 10.000 lượt tìm kiếm nhiều hơn bình thường, bạn nên xem Paris "nóng" hơn Britney, bởi vì các tìm kiếm của cô ấy tăng hơn 20% so với bình thường, trong khi Britney chỉ là 10%.

Chúa ơi, tôi không thể tin rằng mình vừa viết một đoạn so sánh "độ nóng" của Britney Spears và Paris Hilton. Bạn đã làm gì với tôi?


Cảm ơn, nhưng sẽ quá dễ dàng để đặt hàng chúng chỉ bằng cách tăng tiến độ của chúng, phải không?
caw

7

Tôi đã tự hỏi nếu nó hoàn toàn có thể sử dụng công thức gia tốc vật lý thông thường trong trường hợp như vậy?

v2-v1/t or dv/dt

Chúng ta có thể coi v1 là lượt thích / phiếu / số bình luận ban đầu mỗi giờ và v2 là "vận tốc" hiện tại mỗi giờ trong 24 giờ qua?

Đây giống như một câu hỏi hơn là một câu trả lời, nhưng dường như nó có thể chỉ hoạt động. Bất kỳ nội dung nào có khả năng tăng tốc cao nhất sẽ là chủ đề xu hướng ...

Tôi chắc chắn rằng điều này có thể không giải quyết vấn đề Britney Spears :-)


Nó sẽ hoạt động, vì nó chỉ tính toán số phiếu / lượt thích tăng lên mỗi lần, và đây là thứ chúng ta cần. Nó có thể giải quyết "vấn đề giáo Britney" theo từng phần vì thuật ngữ tìm kiếm này luôn ở mức cao v1và sẽ cần rất cao v2để được coi là "xu hướng". Tuy nhiên, có lẽ có các công thức và thuật toán tốt hơn và tinh vi hơn để làm điều này. Tuy nhiên, đây là một ví dụ làm việc cơ bản.
caw

Trong bối cảnh mà bạn luôn cần có một cái gì đó trong nguồn cấp dữ liệu "xu hướng", điều này là hoàn hảo. Một cái gì đó giống như tab Khám phá nơi bạn liệt kê những gì tốt nhất trên nền tảng ngay bây giờ. Sử dụng một thuật toán khác, cuối cùng bạn có thể có một tập kết quả trống.
kilianc

5

có lẽ một dải tần số chủ đề đơn giản sẽ hoạt động - độ dốc dương lớn = tăng nhanh về mức độ phổ biến.

cách dễ nhất sẽ là bin số lượng tìm kiếm mỗi ngày, vì vậy bạn có một cái gì đó như

searches = [ 10, 7, 14, 8, 9, 12, 55, 104, 100 ]

và sau đó tìm hiểu xem nó đã thay đổi bao nhiêu từ ngày này sang ngày khác:

hot_factor = [ b-a for a, b in zip(searches[:-1], searches[1:]) ]
# hot_factor is [ -3, 7, -6, 1, 3, 43, 49, -4 ]

và chỉ áp dụng một số loại ngưỡng để những ngày mà mức tăng> 50 được coi là 'nóng'. bạn có thể làm điều này phức tạp hơn nhiều nếu bạn cũng muốn. thay vì sự khác biệt tuyệt đối, bạn có thể lấy sự khác biệt tương đối để đi từ 100 đến 150 được coi là nóng, nhưng 1000 đến 1050 thì không. hoặc một gradient phức tạp hơn có tính đến các xu hướng trong hơn một ngày tới ngày tiếp theo.


Cảm ơn bạn. Nhưng tôi không biết chính xác gradient là gì và làm thế nào tôi có thể làm việc với nó. Lấy làm tiếc!
caw

Cảm ơn. Vì vậy, tôi phải xây dựng một vector chứa tần số hàng ngày, phải không? Các giá trị tương đối sẽ tốt hơn, tôi chắc chắn. Ví dụ: Tăng trưởng từ 100 đến 110 không tốt bằng tăng trưởng từ 1 đến 9, tôi có thể nói. Nhưng không có chức năng vectơ mà tôi có thể sử dụng để tìm các chủ đề nóng nhất? Chỉ đánh giá các giá trị tương đối sẽ không đủ, phải không? Tăng trưởng từ 100 đến 200 (100%) không tốt bằng tăng trưởng từ 20.000 đến 39.000!?
caw

Những loại trang web bạn đang thêm này vào? Đề xuất của @ Autoplectic để đếm sự thay đổi trong các tìm kiếm hàng ngày sẽ không mở rộng tốt cho một cái gì đó giống như một diễn đàn phổ biến, nơi bạn có hàng ngàn chủ đề với những chủ đề mới được xác định mỗi ngày.
Quantum7

Bạn nói đúng, tôi cần một thuật toán cho lượng dữ liệu khổng lồ, hàng ngàn chủ đề mỗi giờ.
caw

đây là một chiến lược kém bằng cách này, tổng cộng 50 lượt tìm kiếm về Britney Spears cũng hấp dẫn không kém 50 lần tìm kiếm về một cuộc trưng cầu dân ý mới ở châu Âu.
Iman Akbari

4

Tôi đã làm việc trong một dự án, trong đó mục tiêu của tôi là tìm kiếm các Chủ đề Xu hướng từ Live Twitter Stream và cũng thực hiện phân tích tình cảm về các chủ đề xu hướng (tìm xem Chủ đề Xu hướng tích cực / nói tiêu cực). Tôi đã sử dụng Storm để xử lý luồng twitter.

Tôi đã xuất bản báo cáo của mình dưới dạng blog: http://sayrohan.blogspot.com/2013/06/finding-treinating-topics-and-treinating.html

Tôi đã sử dụng Tổng số và Z-Score để xếp hạng.

Cách tiếp cận mà tôi đã sử dụng là hơi chung chung và trong phần thảo luận, tôi đã đề cập rằng làm thế nào chúng ta có thể mở rộng hệ thống cho Ứng dụng không phải Twitter.

Hy vọng thông tin giúp.


3

Nếu bạn chỉ cần xem các tweet hoặc thông điệp trạng thái để lấy chủ đề của mình, bạn sẽ gặp rất nhiều tiếng ồn. Ngay cả khi bạn loại bỏ tất cả các từ dừng lại. Một cách để có được một tập hợp con tốt hơn của các ứng cử viên chủ đề là chỉ tập trung vào các tweet / tin nhắn chia sẻ URL và lấy từ khóa từ tiêu đề của các trang web đó. Và hãy chắc chắn rằng bạn áp dụng gắn thẻ POS để có được danh từ + cụm danh từ.

Các tiêu đề của các trang web thường mang tính mô tả nhiều hơn và chứa các từ mô tả nội dung của trang. Ngoài ra, việc chia sẻ một trang web thường tương quan với việc chia sẻ tin tức đang bị phá vỡ (tức là nếu một người nổi tiếng như Michael Jackson chết, bạn sẽ nhận được rất nhiều người chia sẻ một bài viết về cái chết của anh ta).

Tôi đã chạy thử nghiệm trong đó tôi chỉ lấy các từ khóa phổ biến từ các tiêu đề, và sau đó nhận được tổng số từ khóa đó trên tất cả các thông báo trạng thái và chúng chắc chắn loại bỏ rất nhiều tiếng ồn. Nếu bạn làm theo cách này, bạn không cần một thuật toán phức tạp, chỉ cần thực hiện một thứ tự đơn giản về tần số từ khóa và bạn đã đi được nửa đường.


2

Bạn có thể sử dụng tỷ lệ khả năng đăng nhập để so sánh ngày hiện tại với tháng hoặc năm trước. Đây là âm thanh thống kê (cho rằng các sự kiện của bạn thường không được phân phối, mà sẽ được giả định từ câu hỏi của bạn).

Chỉ cần sắp xếp tất cả các điều khoản của bạn bằng logLR và chọn mười điều khoản hàng đầu.

public static void main(String... args) {
    TermBag today = ...
    TermBag lastYear = ...
    for (String each: today.allTerms()) {
        System.out.println(logLikelihoodRatio(today, lastYear, each) + "\t" + each);
    }
} 

public static double logLikelihoodRatio(TermBag t1, TermBag t2, String term) {
    double k1 = t1.occurrences(term); 
    double k2 = t2.occurrences(term); 
    double n1 = t1.size(); 
    double n2 = t2.size(); 
    double p1 = k1 / n1;
    double p2 = k2 / n2;
    double p = (k1 + k2) / (n1 + n2);
    double logLR = 2*(logL(p1,k1,n1) + logL(p2,k2,n2) - logL(p,k1,n1) - logL(p,k2,n2));
    if (p1 < p2) logLR *= -1;
    return logLR;
}

private static double logL(double p, double k, double n) {
    return (k == 0 ? 0 : k * Math.log(p)) + ((n - k) == 0 ? 0 : (n - k) * Math.log(1 - p));
}

PS, TermBag là một tập hợp các từ không có thứ tự. Đối với mỗi tài liệu bạn tạo một túi điều khoản. Chỉ cần đếm sự xuất hiện của các từ. Sau đó phương thức occurrencestrả về số lần xuất hiện của một từ đã cho và phương thức sizetrả về tổng số từ. Tốt nhất là bình thường hóa các từ bằng cách nào đó, thường toLowerCaselà đủ tốt. Tất nhiên, trong các ví dụ trên, bạn sẽ tạo một tài liệu với tất cả các truy vấn của ngày hôm nay và một tài liệu có tất cả các truy vấn của năm ngoái.


Xin lỗi, tôi không hiểu mã. TermBags là gì? Sẽ thật tuyệt nếu bạn có thể giải thích ngắn gọn về mã này.
caw

1
TermBag là một túi các thuật ngữ, tức là lớp sẽ có thể trả lời tổng số từ trong văn bản và số lần xuất hiện cho mỗi từ.
akuhn

0

Ý tưởng là để theo dõi những điều như vậy và chú ý khi chúng nhảy đáng kể so với đường cơ sở của chính họ.

Vì vậy, đối với các truy vấn có nhiều ngưỡng nhất định, hãy theo dõi từng truy vấn và khi nó thay đổi thành một giá trị nào đó (gần như gấp đôi) giá trị lịch sử của nó, thì đó là một xu hướng nóng mới.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.