Apa cara terbaik untuk menghitung topik atau tag yang sedang tren?

183

Banyak situs menawarkan beberapa statistik seperti "Topik terpanas dalam 24 jam terakhir". Misalnya, Topix.com menunjukkan ini di bagiannya "Tren Berita". Di sana, Anda dapat melihat topik yang memiliki jumlah penyebutan tercepat.

Saya juga ingin menghitung "buzz" untuk suatu topik. Bagaimana saya bisa melakukan ini? Algoritma harus mempertimbangkan topik yang selalu kurang panas. Topik-topik yang biasanya (hampir) tidak ada yang menyebutkan harus menjadi topik terpanas.

Google menawarkan "Hot Trends", topix.com menunjukkan "Hot Topics", fav.or.it menunjukkan "Tren Kata Kunci" - semua layanan ini memiliki satu kesamaan: Mereka hanya menampilkan tren yang akan datang yang tidak biasa panas saat ini.

Istilah seperti "Britney Spears", "cuaca" atau "Paris Hilton" tidak akan muncul dalam daftar ini karena selalu panas dan sering. Artikel ini menyebutnya "Masalah Britney Spears".

Pertanyaan saya: Bagaimana Anda bisa membuat kode algoritma atau menggunakan yang sudah ada untuk menyelesaikan masalah ini? Memiliki daftar dengan kata kunci yang dicari dalam 24 jam terakhir, algoritme akan menunjukkan kepada Anda 10 (misalnya) yang terpanas.

Saya tahu, dalam artikel di atas, ada beberapa jenis algoritma yang disebutkan. Saya sudah mencoba kode di PHP tapi saya tidak berpikir itu akan berhasil. Itu hanya menemukan mayoritas, bukan?

Saya harap Anda dapat membantu saya (contoh pengkodean akan bagus).

gak
sumber
4
Pertanyaan yang menarik, ingin tahu apa yang orang katakan.
mmcdole
14
Tidak ada alasan untuk menutup, ini adalah pertanyaan yang valid
TStamper
1
Ini persis pertanyaan yang sama dan dia bahkan menyatakan itu! Mengapa orang tidak mendukungnya!
Darryl Hein
3
Saya agak bingung tentang jenis hasil yang Anda cari. Artikel tersebut tampaknya mengindikasikan bahwa "Britney Spears" akan secara konsisten ditemukan di daftar "Panas" karena begitu banyak orang mencari istilah itu, tetapi pertanyaan Anda menyatakan bahwa itu TIDAK akan muncul dalam daftar karena jumlah pencarian untuk istilah itu dilakukan tidak meningkat banyak dari waktu ke waktu (mereka tetap tinggi, tetapi stabil). Hasil mana yang ingin Anda capai? Haruskah "Britney Spears" memiliki peringkat tinggi atau rendah?
e.James
1
@ eJames, "Britney Spears" tidak boleh peringkat tinggi karena dia secara konsisten merupakan istilah pencarian tinggi dan dia sedang mencari istilah pencarian dengan kecepatan tinggi.
mmcdole

Jawaban:

103

Masalah ini memerlukan skor-z atau skor standar, yang akan memperhitungkan rata-rata historis, seperti yang disebutkan orang lain, tetapi juga simpangan baku dari data historis ini, membuatnya lebih kuat daripada hanya menggunakan rata-rata.

Dalam kasus Anda, skor-z dihitung dengan rumus berikut, di mana trennya adalah tingkat seperti pandangan / hari.

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

Ketika skor-z digunakan, semakin tinggi atau lebih rendah skor-z semakin tren abnormal, jadi misalnya jika skor-z sangat positif maka trennya naik secara tidak normal, sedangkan jika sangat negatif itu akan jatuh secara tidak normal . Jadi, begitu Anda menghitung skor-z untuk semua tren kandidat, skor-10 tertinggi akan berhubungan dengan skor-z yang paling tidak normal.

Silakan lihat Wikipedia untuk informasi lebih lanjut, tentang skor-z.

Kode

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

Output Sampel

>>> 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

Catatan

  • Anda dapat menggunakan metode ini dengan jendela geser (yaitu 30 hari terakhir) jika Anda tidak ingin memperhitungkan banyak riwayat, yang akan membuat tren jangka pendek lebih jelas dan dapat mengurangi waktu pemrosesan.

  • Anda juga dapat menggunakan skor-z untuk nilai-nilai seperti perubahan tampilan dari satu hari ke hari berikutnya untuk menemukan nilai abnormal untuk meningkatkan / menurunkan tampilan per hari. Ini seperti menggunakan kemiringan atau turunan dari grafik tampilan per hari.

  • Jika Anda melacak ukuran populasi saat ini, total populasi saat ini, dan total populasi saat ini x ^ 2, Anda tidak perlu menghitung ulang nilai-nilai ini, hanya memperbaruinya dan karenanya Anda hanya perlu simpan nilai-nilai ini untuk histori, bukan setiap nilai data. Kode berikut menunjukkan ini.

    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()
    
  • Dengan menggunakan metode ini alur kerja Anda adalah sebagai berikut. Untuk setiap topik, tag, atau halaman buat bidang floating point, untuk jumlah hari, jumlah tampilan, dan jumlah tampilan yang dikuadratkan dalam database Anda. Jika Anda memiliki data historis, inisialisasi bidang ini menggunakan data itu, jika tidak, inisialisasi ke nol. Pada akhir setiap hari, hitung skor-z menggunakan jumlah tampilan hari itu terhadap data historis yang disimpan dalam tiga bidang basis data. Topik, tag, atau halaman, dengan skor X z tertinggi adalah "tren terpanas" Anda hari ini. Terakhir perbarui masing-masing 3 bidang dengan nilai hari dan ulangi proses besok.

Penambahan Baru

Skor-z normal seperti yang dibahas di atas tidak memperhitungkan urutan data dan karenanya skor-z untuk pengamatan '1' atau '9' akan memiliki besaran yang sama terhadap urutan [1, 1, 1, 1 , 9, 9, 9, 9]. Jelas untuk penemuan tren, data terbaru harus memiliki bobot lebih dari data yang lebih tua dan karenanya kami ingin observasi '1' memiliki skor magnitudo lebih besar daripada observasi '9'. Untuk mencapai ini, saya mengusulkan skor-z mengambang. Harus jelas bahwa metode ini TIDAK dijamin secara statistik baik tetapi harus berguna untuk menemukan tren atau serupa. Perbedaan utama antara skor-z standar dan rata-rata mengambang skor-z adalah penggunaan rata-rata mengambang untuk menghitung nilai populasi rata-rata dan nilai populasi rata-rata kuadrat. Lihat kode untuk detail:

Kode

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()

Contoh IO

>>> 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

Memperbarui

Seperti yang David Kemp tunjukkan dengan benar, jika diberikan serangkaian nilai konstan dan kemudian zscore untuk nilai yang diamati yang berbeda dari nilai-nilai lain yang diminta hasilnya mungkin harus tidak nol. Bahkan nilai yang dikembalikan harus tak terhingga. Jadi saya mengubah baris ini,

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

untuk:

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

Perubahan ini tercermin dalam kode solusi fazscore. Jika seseorang tidak ingin berurusan dengan nilai-nilai tak terbatas, solusi yang dapat diterima adalah mengubah baris menjadi:

if self.std() == 0: return obs - self.avg
Nixuz
sumber
1
Tidak, kode Anda memiliki satu kesalahan kecil, pada baris berikut. $ z_score = $ hits_today - ($ average_hits_per_day / $ standard_deviation); Seharusnya: $ z_score = ($ hits_today- $ average_hits_per_day) / $ standard_deviation; Perhatikan perubahan tanda kurung.
Nixuz
1
@nixuz - apakah saya kehilangan sesuatu: fazscore (0,8, peta (lambda x: 40, range (0,200))) skor (1) == 0 (untuk nilai apa pun)?
kͩeͣmͮpͥ ͩ
1
@Nixus - Pikir saya mungkin menggali yang satu ini dari kubur. Bisakah Anda memposting ulang implementasi PHP ini? The pastelink tidak tampaknya akan bekerja ... terima kasih!
Drewness
1
Bagi siapa saja yang suka, saya sekarang memiliki pertanyaan SQL untuk melakukan ini.
thouliha
1
Kerusakan di sini bersifat kontra intuitif; jika Anda memasukkan 2 nilai, katakan [10, 20] dengan peluruhan 0,8, AVG adalah 10 * 0,8 + 20 * 0,2 = 12. Anda akan mengharapkan nilai di atas 15, karena 20 harus memiliki bobot lebih dari 10 jika ada pembusukan. Ada alternatif yang jauh lebih baik tersedia menggunakan rata-rata tertimbang di numpy. Rata-rata, di mana Anda membuat daftar paralel dengan bobot. Misalnya: data = range (10,30,10) decay = 0,8 decay_weights = [decay ** a untuk rentang dalam (len (data), 0, -1)] cetak np.rata-rata (data, bobot = decay_weights)
Jeroen
93

Anda memerlukan algoritme yang mengukur kecepatan suatu topik - atau dengan kata lain, jika Anda membuat grafiknya, Anda ingin menunjukkan kepada mereka yang naik dengan kecepatan luar biasa.

Ini adalah turunan pertama dari garis tren, dan tidak sulit untuk dimasukkan sebagai faktor pembobotan dari keseluruhan perhitungan Anda.

Normalisasi

Salah satu teknik yang perlu Anda lakukan adalah menormalkan semua data Anda. Untuk setiap topik yang Anda ikuti, simpan filter dengan lulus sangat rendah yang menentukan garis dasar topik itu. Sekarang setiap titik data tentang topik itu harus dinormalisasi - kurangi baseline dan Anda akan mendapatkan SEMUA topik Anda mendekati 0, dengan lonjakan di atas dan di bawah garis. Sebagai gantinya Anda mungkin ingin membagi sinyal dengan besarnya garis pangkal, yang akan membawa sinyal ke sekitar 1,0 - ini tidak hanya membawa semua sinyal sejalan satu sama lain (menormalkan garis dasar), tetapi juga menormalkan paku. Lonjakan britney akan menjadi lebih besar dari lonjakan orang lain, tetapi itu tidak berarti Anda harus memperhatikannya - lonjakan itu mungkin sangat kecil dibandingkan dengan garis dasarnya.

Memperoleh

Setelah Anda menormalkan semuanya, cari tahu kemiringan setiap topik. Ambil dua poin berurutan, dan ukur perbedaannya. Perbedaan positif sedang tren naik, perbedaan negatif sedang tren turun. Kemudian Anda dapat membandingkan perbedaan yang dinormalisasi, dan mencari tahu topik apa yang sedang naik popularitasnya dibandingkan dengan topik lainnya - dengan masing-masing topik diskalakan sesuai dengan 'normalnya' sendiri yang mungkin besarnya urutan berbeda dari topik lainnya.

Ini benar-benar lulus pertama di masalah. Ada teknik yang lebih maju yang Anda perlu gunakan (sebagian besar kombinasi di atas dengan algoritma lain, tertimbang sesuai dengan kebutuhan Anda) tetapi itu harus cukup untuk membantu Anda memulai.

Mengenai artikelnya

Artikel ini tentang tren topik, tetapi ini bukan tentang bagaimana menghitung apa yang panas dan apa yang tidak, ini tentang bagaimana memproses sejumlah besar informasi yang harus diproses oleh algoritma seperti itu di tempat-tempat seperti Lycos dan Google. Ruang dan waktu yang diperlukan untuk memberi setiap topik penghitung, dan menemukan penghitung setiap topik saat pencarian melaluinya sangat besar. Artikel ini adalah tentang tantangan yang dihadapi ketika mencoba tugas seperti itu. Itu memang menyebutkan efek Brittney, tetapi tidak berbicara tentang cara mengatasinya.

Seperti yang ditunjukkan Nixuz, ini juga disebut sebagai Z atau Skor Standar .

Adam Davis
sumber
1
Saya membatalkan ini sebelum diedit, dan kembali dan saya ingin mengunggahnya lagi!
Kerja
Terima kasih! Saya akan melakukan kode semu, tetapi saya tidak punya waktu sekarang. Mungkin nanti, atau mungkin orang lain akan mengambil konsep-konsep ini dan mengimplementasikannya ...
Adam Davis
Terima kasih banyak, Adam Davis! Jika Nixuz benar-benar menggambarkan hal yang sama, saya pikir saya punya solusi di PHP: paste.bradleygill.com/index.php?paste_id=9206 Apakah menurut Anda kode ini benar?
gak
Bukankah seharusnya percepatan topik alih-alih kecepatan? Lihatlah jawaban terakhir
Sap
17

Chad Birch dan Adam Davis benar karena Anda harus melihat ke belakang untuk menetapkan garis dasar. Pertanyaan Anda, seperti yang diungkapkan, menyarankan bahwa Anda hanya ingin melihat data dari 24 jam terakhir, dan itu tidak akan cukup.

Salah satu cara untuk memberikan data Anda beberapa memori tanpa harus meminta data besar dari data historis adalah dengan menggunakan rata-rata bergerak eksponensial. Keuntungan dari ini adalah Anda dapat memperbarui ini sekali per periode dan kemudian menyiram semua data lama, sehingga Anda hanya perlu mengingat satu nilai. Jadi, jika periode Anda sehari, Anda harus mempertahankan atribut "rata-rata harian" untuk setiap topik, yang dapat Anda lakukan dengan:

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

Di mana a_nrata-rata bergerak per hari n, b adalah beberapa konstan antara 0 dan 1 (semakin dekat dengan 1, semakin lama ingatannya) dan c_nmerupakan jumlah hit pada hari itu n. Keindahannya adalah jika Anda melakukan pembaruan ini di akhir hari n, Anda dapat menyiram c_ndan a_(n-1).

Satu peringatan adalah bahwa pada awalnya akan sensitif terhadap apa pun yang Anda pilih untuk nilai awal Anda a.

EDIT

Jika hal ini membantu untuk memvisualisasikan pendekatan ini, mengambil n = 5, a_0 = 1dan b = .9.

Katakanlah nilai-nilai baru adalah 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

Tidak terlihat seperti rata-rata bukan? Perhatikan bagaimana nilainya tetap dekat dengan 1, meskipun input kami berikutnya adalah 5. Apa yang terjadi? Jika Anda mengembangkan matematika, apa yang Anda dapatkan:

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

Apa yang saya maksud dengan sisa berat badan? Nah, dalam rata-rata berapa pun, semua bobot harus ditambahkan ke 1. Jika n adalah tak terhingga dan ... bisa berlangsung selamanya, maka semua bobot akan berjumlah 1. Tapi jika n relatif kecil, Anda mendapatkan sisa berat yang baik pada input asli.

Jika Anda mempelajari rumus di atas, Anda harus menyadari beberapa hal tentang penggunaan ini:

  1. Semua data memberikan kontribusi sesuatu dengan rata-rata selamanya. Secara praktis, ada titik di mana kontribusinya benar-benar kecil.
  2. Nilai terbaru berkontribusi lebih dari nilai lama.
  3. Semakin tinggi b, semakin rendah nilai-nilai baru dan semakin lama nilai-nilai penting. Namun, semakin tinggi b, semakin banyak data yang Anda butuhkan untuk mempermudah nilai awal a.

Saya pikir dua karakteristik pertama adalah persis apa yang Anda cari. Untuk memberi Anda gagasan sederhana ini dapat diterapkan, berikut adalah implementasi python (minus semua interaksi basis data):

>>> 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
David Berger
sumber
1
Ini juga dikenal sebagai filter respon impuls tak terbatas (IIR)
Adam Davis
Hai versi yang lebih baik dari jawaban saya.
Joshua
@Adam Benarkah? Saya tidak terbiasa dengan mereka. Apakah ini kasus khusus IIR? Artikel-artikel yang saya skimming sepertinya tidak menyediakan formula yang mengurangi ke rata-rata bergerak eksponensial dalam kasus sederhana.
David Berger
Terima kasih banyak, David Berger! Jika berhasil, itu akan menjadi tambahan yang bagus untuk jawaban lain! Saya punya beberapa pertanyaan. Saya harap Anda bisa menjawabnya: 1) Apakah faktor b menentukan seberapa cepat data lama kehilangan berat? 2) Apakah pendekatan ini akan memberikan hasil yang setara dengan hanya menyimpan data lama dan menghitung rata-rata? 3) Apakah ini formula Anda dalam kata-kata? $ average_value = $ old_average_value * $ smoothing_factor + $ hits_today * (1- $ smoothing_factor)
caw
Poin 1 dan 3 sudah benar. Lihat hasil edit saya untuk sedikit diskusi bernuansa 2.
David Berger
8

Biasanya "buzz" diperhitungkan menggunakan beberapa bentuk mekanisme peluruhan eksponensial / log. Untuk ikhtisar tentang bagaimana Hacker News, Reddit, dan lainnya menangani ini dengan cara yang sederhana, lihat posting ini .

Ini tidak sepenuhnya membahas hal-hal yang selalu populer. Apa yang Anda cari tampaknya mirip dengan fitur " Tren Panas " Google. Untuk itu, Anda bisa membagi nilai saat ini dengan nilai historis dan kemudian kurangi yang di bawah ambang batas kebisingan.

Jeff Moser
sumber
Ya, Tren Panas Google adalah persis apa yang saya cari. Apa yang seharusnya menjadi nilai historis? Nilai rata-rata 7 hari terakhir misalnya?
gak
1
Itu tergantung pada seberapa volatile data Anda. Anda bisa mulai dengan rata-rata 30 hari. Jika itu adalah hal yang bersifat siklus (mis. Kentucky Derby) maka mungkin masuk akal untuk melakukan perbandingan tahunan. Saya akan bereksperimen dan melihat apa yang paling berhasil dalam praktik.
Jeff Moser
7

Saya pikir mereka kata kunci yang perlu Anda perhatikan adalah "tidak normal". Untuk menentukan kapan sesuatu itu "tidak normal", Anda harus tahu apa yang normal. Artinya, Anda akan membutuhkan data historis, yang dapat Anda rata-rata untuk mengetahui tingkat normal dari permintaan tertentu. Anda mungkin ingin mengecualikan hari yang tidak normal dari perhitungan rata-rata, tetapi sekali lagi itu akan memerlukan sudah cukup data, sehingga Anda tahu hari-hari mana yang harus dikecualikan.

Dari sana, Anda harus menetapkan ambang (yang akan membutuhkan eksperimen, saya yakin), dan jika sesuatu melampaui ambang, katakanlah 50% lebih banyak pencarian daripada biasanya, Anda dapat menganggapnya sebagai "tren". Atau, jika Anda ingin dapat menemukan "Top X Paling Trendi" seperti yang Anda sebutkan, Anda hanya perlu memesan berdasarkan seberapa jauh (berdasarkan persentase) mereka jauh dari tingkat normal.

Misalnya, katakanlah data historis Anda memberi tahu Anda bahwa Britney Spears biasanya mendapat 100.000 pencarian, dan Paris Hilton biasanya mendapat 50.000. Jika Anda memiliki hari di mana mereka berdua mendapatkan 10.000 pencarian lebih banyak dari biasanya, Anda harus mempertimbangkan Paris "lebih panas" daripada Britney, karena pencariannya meningkat 20% lebih dari biasanya, sedangkan Britney hanya 10%.

Ya Tuhan, aku tidak percaya aku baru saja menulis sebuah paragraf yang membandingkan "kepanasan" Britney Spears dan Paris Hilton. Apa yang telah kau lakukan padaku?

Chad Birch
sumber
Terima kasih, tetapi akan sedikit terlalu mudah untuk memesannya hanya dengan peningkatan prosentual mereka, bukan?
gak
7

Saya bertanya-tanya apakah mungkin menggunakan rumus akselerasi fisika biasa dalam kasus seperti itu?

v2-v1/t or dv/dt

Kita dapat menganggap v1 sebagai suka / suara / hitungan komentar per jam dan v2 sebagai "kecepatan" saat ini per jam dalam 24 jam terakhir?

Ini lebih seperti sebuah pertanyaan daripada jawaban, tetapi sepertinya itu hanya bekerja. Konten apa pun dengan akselerasi tertinggi akan menjadi trending topic ...

Saya yakin ini mungkin tidak menyelesaikan masalah Britney Spears :-)

Getah
sumber
Ini akan berhasil, karena hanya menghitung kenaikan suara / suka per waktu, dan inilah yang kita butuhkan. Ini bisa menyelesaikan "masalah Britney spears" di beberapa bagian karena istilah pencarian ini selalu tinggi v1dan perlu sangat tinggi v2untuk dianggap "tren". Namun, mungkin ada formula dan algoritma yang lebih baik dan lebih canggih untuk melakukan ini. Namun demikian, ini adalah contoh kerja dasar.
gak
Dalam konteks di mana Anda selalu perlu memiliki sesuatu dalam umpan "tren", ini sempurna. Sesuatu seperti tab Jelajahi di mana Anda mencantumkan yang terbaik di platform saat ini. Menggunakan algo yang berbeda, Anda mungkin akhirnya memiliki hasil yang kosong.
kilianc
5

mungkin gradien sederhana dari frekuensi topik akan berhasil - gradien positif besar = tumbuh dengan cepat dalam popularitas.

cara termudah adalah dengan membuang jumlah pencarian setiap hari, sehingga Anda memiliki sesuatu seperti

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

dan kemudian mencari tahu berapa banyak itu berubah dari hari ke hari:

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

dan hanya menerapkan semacam ambang batas sehingga hari-hari di mana kenaikannya> 50 dianggap 'panas'. Anda bisa membuat ini jauh lebih rumit jika Anda mau. alih-alih perbedaan absolut Anda dapat mengambil perbedaan relatif sehingga beralih dari 100 ke 150 dianggap panas, tetapi 1000 menjadi 1050 tidak. atau gradien yang lebih rumit yang memperhitungkan tren akun selama lebih dari satu hari ke hari berikutnya.

Autoplektik
sumber
Terima kasih. Tapi saya tidak tahu persis apa gradien itu dan bagaimana saya bisa bekerja dengannya. Maaf!
gak
Terima kasih. Jadi saya harus membuat vektor yang berisi frekuensi harian, bukan? Nilai relatifnya akan lebih baik, saya yakin. Contoh: Pertumbuhan dari 100 menjadi 110 tidak sebagus pertumbuhan dari 1 hingga 9, menurut saya. Tapi bukankah ada fungsi vektor yang bisa saya gunakan untuk menemukan topik terpanas? Hanya mengevaluasi nilai-nilai relatif tidak akan cukup, bukan? Pertumbuhan dari 100 menjadi 200 (100%) tidak sebagus pertumbuhan dari 20.000 menjadi 39.000 !?
gak
Situs web seperti apa yang Anda tambahkan ini? @ Autoplectic's saran untuk menghitung perubahan dalam pencarian sehari-hari tidak akan skala baik untuk sesuatu seperti forum populer, di mana Anda memiliki ribuan topik dengan yang baru didefinisikan setiap hari.
Quantum7
Anda benar, saya memerlukan algoritma untuk data dalam jumlah besar, ribuan topik per jam.
gak
ini adalah strategi yang buruk. dengan cara ini, peningkatan total 50 pencarian tentang Britney Spears sama panasnya dengan +50 pencarian tentang referendum baru di Eropa.
Iman Akbari
4

Saya telah mengerjakan sebuah proyek, di mana tujuan saya adalah menemukan Topik Tren dari Streaming Twitter Langsung dan juga melakukan analisis sentimental pada topik yang sedang tren (menemukan apakah Topik Tren dibicarakan secara positif / negatif). Saya telah menggunakan Storm untuk menangani aliran twitter.

Saya telah menerbitkan laporan saya sebagai blog: http://sayrohan.blogspot.com/2013/06/finding-trending-topics-and-trending.html

Saya telah menggunakan Total Hitungan dan Skor Z untuk peringkat.

Pendekatan yang saya gunakan agak umum, dan di bagian diskusi, saya telah menyebutkan bahwa bagaimana kita dapat memperluas sistem untuk Aplikasi non-Twitter.

Semoga informasinya membantu.

Rohan Karwa
sumber
3

Jika Anda hanya melihat tweet, atau pesan status untuk mendapatkan topik Anda, Anda akan menghadapi banyak kebisingan. Bahkan jika Anda menghapus semua kata berhenti. Salah satu cara untuk mendapatkan subset kandidat topik yang lebih baik adalah dengan memfokuskan hanya pada tweet / pesan yang membagikan URL, dan mendapatkan kata kunci dari judul halaman web tersebut. Dan pastikan Anda menerapkan penandaan POS untuk mendapatkan kata benda + frasa kata benda juga.

Judul halaman web biasanya lebih deskriptif dan mengandung kata-kata yang menggambarkan tentang halaman tersebut. Selain itu, berbagi halaman web biasanya berkorelasi dengan berbagi berita yang melanggar (yaitu jika seorang selebriti seperti Michael Jackson meninggal, Anda akan mendapatkan banyak orang berbagi artikel tentang kematiannya).

Saya telah menjalankan percobaan di mana saya hanya mengambil kata kunci populer dari judul, DAN kemudian mendapatkan jumlah total kata kunci tersebut di semua pesan status, dan mereka pasti menghilangkan banyak suara. Jika Anda melakukannya dengan cara ini, Anda tidak perlu algoritma yang rumit, cukup lakukan pemesanan sederhana dari frekuensi kata kunci, dan Anda setengah jalan di sana.

Henley Chiu
sumber
2

Anda dapat menggunakan rasio kemungkinan log untuk membandingkan tanggal saat ini dengan bulan atau tahun terakhir. Ini secara statistik masuk akal (mengingat bahwa acara Anda tidak terdistribusi secara normal, yang harus diasumsikan dari pertanyaan Anda).

Urutkan semua persyaratan Anda dengan logLR dan pilih sepuluh besar.

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 adalah kumpulan kata-kata yang tidak teratur. Untuk setiap dokumen Anda membuat satu kantong istilah. Hitung saja kemunculan kata-kata. Kemudian metode occurrencesmengembalikan jumlah kemunculan kata yang diberikan, dan metode sizemengembalikan jumlah total kata. Cara terbaik adalah menormalkan kata-kata itu, biasanya toLowerCasecukup baik. Tentu saja, dalam contoh di atas Anda akan membuat satu dokumen dengan semua kueri hari ini, dan satu dengan semua kueri tahun lalu.

akuhn
sumber
Maaf, saya tidak mengerti kodenya. Apa itu TermBags? Alangkah baiknya jika Anda bisa menjelaskan dengan singkat apa yang dilakukan kode ini.
gak
1
TermBag adalah sekumpulan istilah, yaitu kelas harus dapat menjawab jumlah total kata dalam teks dan jumlah kemunculan untuk setiap kata.
akuhn
0

Idenya adalah untuk melacak hal-hal seperti itu dan perhatikan ketika mereka melompat secara signifikan dibandingkan dengan baseline mereka sendiri.

Jadi, untuk kueri yang memiliki lebih dari ambang tertentu, lacak masing-masing dan ketika itu berubah ke beberapa nilai (katakanlah hampir dua kali lipat) dari nilai historisnya, maka itu adalah tren panas baru.

Joshua
sumber