Ana içeriğe atla

Metindeki Kelimelerin Mutlak ve Ağırlıklandırılmış Sıklığı

Bu eğitimde, metin madenciliğinde mutlak ve ağırlıklandırılmış kelime sıklığını ve bunu defaultdict ile pandas DataFrame’leri kullanarak nasıl hesaplayacağınızı öğreneceksiniz.
Güncel 3 Eki 2026  · 15 dk. oku

Yapay Zeka ile Keşfedin

ChatGPTClaudePerplexity

Metin madenciliğinde önemli metrik kümelerinden biri, belirli bir metin dokümanları külliyatındaki kelimelerin (veya herhangi bir token’ın) sıklığıyla ilgilidir. Ancak, her belgenin belgeye ait belirli bir niteliği tanımlayan sayısal bir değerle ilişkilendirildiği durumlarda, ilave metrik kümeleri de kullanabilirsiniz.

Bazı örnekler:

  • Tweet’ler ve bunların aldığı etkileşim sayıları.
  • URL’ler ve sayfa görüntülemeleri ile hemen çıkma sayıları.
  • Film adları ve gişe geliri.
  • Anahtar kelimeler ve gösterimler, tıklamalar, dönüşümler.

Bu eğitimde,

  • Önce, bir belge külliyatında kelimelerin mutlak ve ağırlıklandırılmış geçiş sıklığını hesaplayan ve karşılaştıran basit bir fonksiyon oluşturma sürecinden geçeceksiniz. Bu, bazen ilk on değere bakarak net olmayan gizli eğilimleri ve toplamları ortaya çıkarabilir. Ayrıca çoğu zaman mutlak kelime sıklığından da farklı olabilirler.
  • Ardından, gerçek bir veri kümesini (film adları ve gişe geliri) görecek ve gizli eğilimleri keşfetmeyi umacağız. Küçük bir ipucu: aşk bir şekilde karşımıza çıkacak!
  • Programlama dili olarak Python kullanacak ve işin ağır kısmı için collections modülünün defaultdict veri yapısından, nihai çıktıyı yönetmek için de pandas DataFramelerinden yararlanacaksınız.

Mutlak ve Ağırlıklandırılmış Kelime Sıklığı: Giriş

İki tweet’iniz olduğunu ve içerikleri ile gösterim (görüntüleme) sayılarının aşağıdaki gibi olduğunu varsayalım:

Tweet Metni Görüntüleme
spain 800
france 200

Basit analizi yapmak ve kelimelerinizin 'france' ve 'spain' arasında 50:50 bölündüğünü bulmak kolaydır. Çoğu durumda elinizde yalnızca bu olur ve sadece kelimelerin mutlak sıklığını ölçebilir, bazı ilişkileri çıkarsamaya çalışabilirsiniz. Bu örnekte ise her belgeye dair bazı verileriniz var.

Burada ağırlıklandırılmış sıklık belirgin şekilde farklıdır ve dağılım 80:20’dir. Başka bir deyişle, tweet’lerinizde 'spain' ve 'france' birer kez görünse de, okuyucularınızın gözünde ilki 800, ikincisi 200 kez görünmüştür. Büyük fark!

defaultdict kullanarak Basit Kelime Sıklığı

Şimdi benzer bir belge kümesi için biraz daha kapsamlı şu örneği ele alalım:

Belge Görüntüleme
france 200
spain 180
spain beaches 170
france beaches 160
spain best beaches 160

Şimdi belgeler arasında döngü kuruyor, onları kelimelere ayırıyor ve her kelimenin kaç kez geçtiğini sayıyorsunuz:

 from collections import defaultdict

import pandas as pd

text_list = ['france', 'spain', 'spain beaches', 'france beaches', 'spain best beaches']

word_freq = defaultdict(int)

for text in text_list:
    for word in text.split():
        word_freq[word] += 1

pd.DataFrame.from_dict(word_freq, orient='index') \
.sort_values(0, ascending=False) \
.rename(columns={0: 'abs_freq'})
  abs_freq
spain 3
beaches 3
france 2
best 1

Yukarıdaki döngüde ilk satır, text_list üzerinde birer birer gezinir. İkinci satır (her belge için), öğeyi boşluk karakterine göre bölerek (başka bir karakter de olabilirdi ('-', ',', '_', vb.)) kelimeleri arasında döngü yapar.

word_freq[word]’a bir değer atamaya çalıştığınızda iki olası senaryo vardır:

  1. word anahtarı vardır: bu durumda atama yapılır (bir eklenir)
  2. word anahtarı word_freq içinde yoktur; bu durumda defaultdict, ilk tanımlandığında kendisine atanan varsayılan fonksiyonu çağırır; burada bu fonksiyon int’tir.

int çağrıldığında sıfır döndürür. Artık anahtar vardır, değeri sıfırdır ve değerine 1 eklenerek atama yapılmaya hazırdır.

İlk tabloda üst sıradaki kelime 'france' iken, her belgedeki tüm kelimeler sayıldıktan sonra 'spain' ve 'beaches'in birincilikte başa baş olduğunu görüyoruz. Bu, özellikle üzerinde çalıştığınız belge listesi onlarca ya da yüz binlerce öğeden oluştuğunda gizli eğilimleri ortaya çıkarmada önemlidir.

Ağırlıklandırılmış Kelime Sıklığı

Artık külliyattaki her kelimenin geçişlerini saydığınıza göre, ağırlıklandırılmış sıklığı görmek istiyorsunuz. Yani, kelimelerin okuyucularınıza kaç kez göründüğünü, sizin onları kaç kez kullandığınıza kıyasla görmek istiyorsunuz.

İlk tabloda kelimelerin mutlak sıklığı 'spain' ve 'france' arasında eşit dağılmıştı, ancak 'spain' bariz biçimde daha fazla ağırlığa sahipti; çünkü değeri 800 iken 'france' için 200’dü.

Peki ikinci, biraz daha karmaşık tablo için ağırlıklandırılmış kelime sıklığı ne olurdu?

Hadi bulalım!

Yukarıda kullandığınız kodun bir kısmını, bazı eklemelerle yeniden kullanabilirsiniz:

 # default value is now a list with two ints
word_freq = defaultdict(lambda: [0, 0]) 

# the `views` column you had in the first DataFrame
num_list = [200, 180, 170, 160, 160]

# looping is now over both the text and the numbers
for text, num in zip(text_list, num_list): 
    for word in text.split(): 
        # same as before
        word_freq[word][0] += 1 
        # new line, incrementing the numeric value for each word
        word_freq[word][1] += num 

columns = {0: 'abs_freq', 1: 'wtd_freq'}

abs_wtd_df = pd.DataFrame.from_dict(word_freq, orient='index') \
             .rename(columns=columns) \
             .sort_values('wtd_freq', ascending=False) \
             .assign(rel_value=lambda df: df['wtd_freq'] / df['abs_freq']) \
            .round()

abs_wtd_df.style.background_gradient(low=0, high=.7, subset=['rel_value'])
  abs_freq wtd_freq rel_value
spain 3 510 170
beaches 3 490 163
france 2 360 180
best 1 160 160

Bazı gözlemler:

  • 'france' genel olarak en yüksek ifade olmasına rağmen, ağırlıklandırılmış sıklığı dikkate aldığınızda 'spain' ve 'beaches' daha baskın görünüyor.
  • rel_value, her kelimenin geçiş başına değerini elde etmek için yapılan basit bir bölmedir.
  • rel_value’a bakınca, 'france' wtd_freq metriğinde oldukça düşük olsa da, geçiş başına değeri yüksek olduğu için potansiyel barındırdığı görülüyor. Bu, örneğin 'france' kapsamındaki içeriklerinizi artırmayı düşündürebilir.

Ayrıca, toplamın çoğunluğunu kaç kelimenin oluşturduğuna daha iyi bir perspektiften bakmak için her tür sıklığın yüzdelerini ve kümülatif yüzdelerini gösteren bazı diğer metrikleri de eklemek isteyebilirsiniz:

 abs_wtd_df.insert(1, 'abs_perc', value=abs_wtd_df['abs_freq'] / abs_wtd_df['abs_freq'].sum())
abs_wtd_df.insert(2, 'abs_perc_cum', abs_wtd_df['abs_perc'].cumsum())
abs_wtd_df.insert(4, 'wtd_freq_perc', abs_wtd_df['wtd_freq'] / abs_wtd_df['wtd_freq'].sum())
abs_wtd_df.insert(5, 'wtd_freq_perc_cum', abs_wtd_df['wtd_freq_perc'].cumsum())
abs_wtd_df.style.background_gradient(low=0, high=0.8)
  abs_freq abs_perc abs_perc_cum wtd_freq wtd_freq_perc wtd_freq_perc_cum rel_value
spain 3 0.333333 0.333333 510 0.335526 0.335526 170
beaches 3 0.333333 0.666667 490 0.322368 0.657895 163
france 2 0.222222 0.888889 360 0.236842 0.894737 180
best 1 0.111111 1 160 0.105263 1 160

Daha fazla analiz yapılabilir ve daha fazla veriyle genellikle daha çok sürprizle karşılaşırsınız.

Peki bu, gerçek verilerle gerçek dünyada nasıl görünür?

Film adlarına bakacak, başlıklarda en çok hangi kelimelerin kullanıldığını —yani mutlak sıklığı— ve en çok hangi kelimelerin gelirle ilişkilendirildiğini, yani ağırlıklandırılmış sıklığı göreceksiniz.

Boxoffice Mojo 15.000’den fazla filmi, ilgili gişe geliri ve sıralamalarıyla birlikte listeliyor. requests ve BeautifulSoup kullanarak veriyi kazıyarak başlayın — İsterseniz Boxoffice Mojo’yu burada şimdiden keşfedebilirsiniz:

 
import requests
from bs4 import BeautifulSoup
 final_list = []

for i in range(1, 156):
    if not i%10:
        print(i)
    page = 'http://www.boxofficemojo.com/alltime/domestic.htm?page=' + str(i) + '&p=.htm'
    resp = requests.get(page)
    soup = BeautifulSoup(resp.text, 'lxml')
    # trial and error to get the exact positions
    table_data = [x.text for x in soup.select('tr td')[11:511]]  
    # put every 5 values in a row
    temp_list = [table_data[i:i+5] for i in range(0, len(table_data[:-4]), 5)] 
    for temp in temp_list:
        final_list.append(temp)
10
20
30
40
50
60
70
80
90
100
110
120
130
140
150
boxoffice_df = pd.DataFrame.from_records(final_list)

boxoffice_df.head(10)
  0 1 2 3 4
0 1 Star Wars: The Force Awakens BV $936,662,225 2015
1 2 Avatar Fox $760,507,625 2009^
2 3 Black Panther BV $681,084,109 2018
3 4 Titanic Par. $659,363,944 1997^
4 5 Jurassic World Uni. $652,270,625 2015
5 6 Marvel's The Avengers BV $623,357,910 2012
6 7 Star Wars: The Last Jedi BV $620,181,382 2017
7 8 The Dark Knight WB $534,858,444 2008^
8 9 Rogue One: A Star Wars Story BV $532,177,324 2016
9 10 Beauty and the Beast (2017) BV $504,014,165 2017
boxoffice_df.tail(15)
  0 1 2 3 4
15485 15486 The Dark Hours N/A $423 2005
15486 15487 2:22 Magn. $422 2017
15487 15488 State Park Atl $421 1988
15488 15489 The Magician (2010) Reg. $406 2010
15489 15490 Skinless PPF $400 2014
15490 15491 Cinemanovels Mont. $398 2014
15491 15492 Hannah: Buddhism's Untold Journey KL $396 2016
15492 15493 Apartment 143 Magn. $383 2012
15493 15494 The Marsh All. $336 2007
15494 15495 The Chambermaid FM $315 2015
15495 15496 News From Planet Mars KL $310 2016
15496 15497 Trojan War WB $309 1997
15497 15498 Lou! Journal infime Distrib. $287 2015
15498 15499 Intervention All. $279 2007
15499 15500 Playback Magn. $264 2012

Bazı sayısal değerlerde özel karakterler ($, , ve ^) yer aldığını ve bazı değerlerin aslında N/A olduğunu göreceksiniz. Dolayısıyla bunları dönüştürmeniz gerekir:

na_year_idx =  [i for i, x in enumerate(final_list) if x[4] == 'n/a'] # get the indexes of the 'n/a' values
new_years = [1998, 1999, 1960, 1973]  # got them by checking online

print(*[(i, x) for i, x in enumerate(final_list) if i in na_year_idx], sep='\n')
print('new year values:', new_years)
(8003, ['8004', 'Warner Bros. 75th Anniversary Film Festival', 'WB', '$741,855', 'n/a'])
(8148, ['8149', 'Hum Aapke Dil Mein Rahte Hain', 'Eros', '$668,678', 'n/a'])
(8197, ['8198', 'Purple Moon (Re-issue)', 'Mira.', '$640,945', 'n/a'])
(10469, ['10470', 'Amarcord', 'Jan.', '$125,493', 'n/a'])
new year values: [1998, 1999, 1960, 1973]
for na_year, new_year in zip(na_year_idx, new_years):
    final_list[na_year][4] = new_year
    print(final_list[na_year], new_year)
['8004', 'Warner Bros. 75th Anniversary Film Festival', 'WB', '$741,855', 1998] 1998
['8149', 'Hum Aapke Dil Mein Rahte Hain', 'Eros', '$668,678', 1999] 1999
['8198', 'Purple Moon (Re-issue)', 'Mira.', '$640,945', 1960] 1960
['10470', 'Amarcord', 'Jan.', '$125,493', 1973] 1973

Şimdi listeyi uygun adlarla sütunlarını adlandırıp, istediğiniz veri türlerine dönüştürerek bir pandas DataFrame’ine çeviriyorsunuz.

 import re
regex = '|'.join(['\$', ',', '\^'])

columns = ['rank', 'title', 'studio', 'lifetime_gross', 'year']

boxoffice_df = pd.DataFrame({
    'rank': [int(x[0]) for x in final_list],  # convert ranks to integers
    'title': [x[1] for x in final_list],  # get titles as is
    'studio': [x[2] for x in final_list],  # get studio names as is
    'lifetime_gross': [int(re.sub(regex, '', x[3])) for x in final_list],  # remove special characters and convert to integer
    'year': [int(re.sub(regex, '', str(x[4]))) for x in final_list],  # remove special characters and convert to integer
})
print('rows:', boxoffice_df.shape[0])
print('columns:', boxoffice_df.shape[1])
print('\ndata types:')
print(boxoffice_df.dtypes)
boxoffice_df.head(15)
rows: 15500
columns: 5

data types:
lifetime_gross     int64
rank               int64
studio            object
title             object
year               int64
dtype: object
  lifetime_gross rank studio title year
0 936662225 1 BV Star Wars: The Force Awakens 2015
1 760507625 2 Fox Avatar 2009
2 681084109 3 BV Black Panther 2018
3 659363944 4 Par. Titanic 1997
4 652270625 5 Uni. Jurassic World 2015
5 623357910 6 BV Marvel's The Avengers 2012
6 620181382 7 BV Star Wars: The Last Jedi 2017
7 534858444 8 WB The Dark Knight 2008
8 532177324 9 BV Rogue One: A Star Wars Story 2016
9 504014165 10 BV Beauty and the Beast (2017) 2017
10 486295561 11 BV Finding Dory 2016
11 474544677 12 Fox Star Wars: Episode I - The Phantom Menace 1999
12 460998007 13 Fox Star Wars 1977
13 459005868 14 BV Avengers: Age of Ultron 2015
14 448139099 15 WB The Dark Knight Rises 2012

'star' kelimesi, ilk on beş filmden beşinde geçtiği için en üst sıralardadır ve Star Wars serisinin, aralarında birkaçı üst sıralarda yer alan daha fazla filmi olduğunu da biliyorsunuz.

Şimdi geliştirdiğiniz kodu kullanalım ve bu veri kümesinde nasıl çalıştığını görelim. Aşağıdaki kodda yeni bir şey yok; sadece hepsini tek bir fonksiyonda topladınız:

 def word_frequency(text_list, num_list, sep=None):
    word_freq = defaultdict(lambda: [0, 0])

    for text, num in zip(text_list, num_list):
        for word in text.split(sep=sep): 
            word_freq[word][0] += 1 
            word_freq[word][1] += num

    columns = {0: 'abs_freq', 1: 'wtd_freq'}

    abs_wtd_df = (pd.DataFrame.from_dict(word_freq, orient='index')
                 .rename(columns=columns )
                 .sort_values('wtd_freq', ascending=False)
                 .assign(rel_value=lambda df: df['wtd_freq'] / df['abs_freq']).round())

    abs_wtd_df.insert(1, 'abs_perc', value=abs_wtd_df['abs_freq'] / abs_wtd_df['abs_freq'].sum())
    abs_wtd_df.insert(2, 'abs_perc_cum', abs_wtd_df['abs_perc'].cumsum())
    abs_wtd_df.insert(4, 'wtd_freq_perc', abs_wtd_df['wtd_freq'] / abs_wtd_df['wtd_freq'].sum())
    abs_wtd_df.insert(5, 'wtd_freq_perc_cum', abs_wtd_df['wtd_freq_perc'].cumsum())

    return abs_wtd_df
word_frequency(boxoffice_df['title'], boxoffice_df['lifetime_gross']).head()
  abs_freq abs_perc abs_perc_cum wtd_freq wtd_freq_perc wtd_freq_perc_cum rel_value
The 3055 0.068747 0.068747 67518342498 0.081167 0.081167 22100930.0
the 1310 0.029479 0.098227 32973100860 0.039639 0.120806 25170306.0
of 1399 0.031482 0.129709 30180592467 0.036282 0.157087 21572975.0
and 545 0.012264 0.141973 12188113847 0.014652 0.171739 22363512.0
2 158 0.003556 0.145529 9032673058 0.010859 0.182598 57168817.0

Şaşırtıcı olmayan şekilde, 'stop word'ler en üstte; bu çoğu belge koleksiyonu için benzerdir. Ayrıca bazıları büyük harfle, bazıları küçük harfle yazıldığı için yinelenmiş durumdalar. Dolayısıyla ilgilenmeniz gereken iki açık konu var:

  1. Tüm stop word’leri kaldırın: Bunu fonksiyona yeni bir parametre ekleyip, kendi stop word listenizi sağlayarak yapabilirsiniz.
  2. Tüm kelimeleri küçük harfe çevirerek yinelenmeyi önleyin

İşte fonksiyonun basit bir güncellemesi (yeni rm_words parametresi ve 6, 7, 8. satırlar):

# words will be expanded
def word_frequency(text_list, num_list, sep=None, rm_words=('the', 'and', 'a')):  
    word_freq = defaultdict(lambda: [0, 0])

    for text, num in zip(text_list, num_list):
        for word in text.split(sep=sep): 
            # This should take care of ignoring the word if it's in the stop words
            if word.lower() in rm_words:  
                continue                  
            # .lower() makes sure we are not duplicating words
            word_freq[word.lower()][0] += 1  
            word_freq[word.lower()][1] += num

    columns = {0: 'abs_freq', 1: 'wtd_freq'}

    abs_wtd_df = (pd.DataFrame.from_dict(word_freq, orient='index')
                 .rename(columns=columns )
                 .sort_values('wtd_freq', ascending=False)
                 .assign(rel_value=lambda df: df['wtd_freq'] / df['abs_freq']).round())

    abs_wtd_df.insert(1, 'abs_perc', value=abs_wtd_df['abs_freq'] / abs_wtd_df['abs_freq'].sum())
    abs_wtd_df.insert(2, 'abs_perc_cum', abs_wtd_df['abs_perc'].cumsum())
    abs_wtd_df.insert(4, 'wtd_freq_perc', abs_wtd_df['wtd_freq'] / abs_wtd_df['wtd_freq'].sum())
    abs_wtd_df.insert(5, 'wtd_freq_perc_cum', abs_wtd_df['wtd_freq_perc'].cumsum())

    abs_wtd_df = abs_wtd_df.reset_index().rename(columns={'index': 'word'})

    return abs_wtd_df
from collections import defaultdict
word_freq_df =  word_frequency(boxoffice_df['title'], 
                               boxoffice_df['lifetime_gross'],
                               rm_words=['of','in', 'to', 'and', 'a', 'the', 
                                         'for', 'on', '&', 'is', 'at', 'it',
                                         'from', 'with'])



word_freq_df.head(15).style.bar(['abs_freq', 'wtd_freq', 'rel_value'],
                                               color='#60DDFF') # E6E9EB

  word abs_freq abs_perc abs_perc_cum wtd_freq wtd_freq_perc wtd_freq_perc_cum rel_value
0 2 158 0.00443945 0.00443945 9032673058 0.0137634 0.0137634 5.71688e+07
1 star 45 0.0012644 0.00570385 5374658819 0.00818953 0.0219529 1.19437e+08
2 man 195 0.00547907 0.0111829 3967037854 0.0060447 0.0279976 2.03438e+07
3 part 41 0.00115201 0.0123349 3262579777 0.00497129 0.0329689 7.95751e+07
4 movie 117 0.00328744 0.0156224 3216050557 0.00490039 0.0378693 2.74876e+07
5 3 63 0.00177016 0.0173925 3197591193 0.00487227 0.0427415 5.07554e+07
6 ii 67 0.00188255 0.0192751 3077712883 0.0046896 0.0474311 4.5936e+07
7 wars: 6 0.000168587 0.0194437 2757497155 0.00420168 0.0516328 4.59583e+08
8 last 133 0.003737 0.0231807 2670229651 0.00406871 0.0557015 2.00769e+07
9 harry 27 0.00075864 2611329714 0.00397896 0.0596805 9.67159e+07
10 me 140 0.00393369 0.027873 2459330128 0.00374736 0.0634279 1.75666e+07
11 potter 10 0.000280978 0.028154 2394811427 0.00364905 0.0670769 2.39481e+08
12 black 71 0.00199494 0.0301489 2372306467 0.00361476 0.0706917 3.34128e+07
13 - 49 0.00137679 0.0315257 2339484878 0.00356474 0.0742564 4.77446e+07
14 story 107 0.00300646 0.0345322 2231437526 0.00340011 0.0776565 2.08546e+07

Aynı DataFrame’e abs_freq’e göre sıralanmış olarak bakalım:

(word_freq_df.sort_values('abs_freq', ascending=False)
 .head(15)
    .style.bar(['abs_freq', 'wtd_freq', 'rel_value'],
               color='#60DDFF'))

  word abs_freq abs_perc abs_perc_cum wtd_freq wtd_freq_perc wtd_freq_perc_cum rel_value
26 love 211 0.00592863 0.069542 1604206885 0.00244438 0.111399 7.60288e+06
2 man 195 0.00547907 0.0279976 3967037854 0.0060447 0.0279976 2.03438e+07
24 my 191 0.00536668 0.0618994 1629540498 0.00248298 0.106478 8.53163e+06
15 i 168 0.00472043 0.0392526 2203439786 0.00335745 0.081014 1.31157e+07
0 2 158 0.00443945 0.00443945 9032673058 0.0137634 0.0137634 5.71688e+07
10 me 140 0.00393369 0.027873 2459330128 0.00374736 0.0634279 1.75666e+07
31 life 134 0.0037651 0.0764822 1534647732 0.00233839 0.123297 1.14526e+07
8 last 133 0.003737 0.0231807 2670229651 0.00406871 0.0557015 2.00769e+07
23 you 126 0.00354032 0.0565327 1713758853 0.00261131 0.103995 1.36013e+07
4 movie 117 0.00328744 0.0156224 3216050557 0.00490039 0.0378693 2.74876e+07
14 story 107 0.00300646 0.0345322 2231437526 0.00340011 0.0776565 2.08546e+07
33 night 104 0.00292217 0.0814555 1523917360 0.00232204 0.127946 1.46531e+07
19 american 93 0.00261309 0.0478505 1868854192 0.00284763 0.0932591 2.00952e+07
117 girl 90 0.0025288 0.151644 842771661 0.00128416 0.26663 9.36413e+06
16 day 87 0.00244451 0.0416971 2164198760 0.00329766 0.0843116 2.48758e+07

Şimdi ikisini karşılaştırmak ve gizli eğilimleri görmek için görselleştirelim:

 import matplotlib.pyplot as plt
plt.figure(figsize=(20,8))
plt.subplot(1, 2, 1)

word_freq_df_abs = word_freq_df.sort_values('abs_freq', ascending=False).reset_index()

plt.barh(range(20),
         list(reversed(word_freq_df_abs['abs_freq'][:20])), color='#288FB7')
for i, word in enumerate(word_freq_df_abs['word'][:20]):
    plt.text(word_freq_df_abs['abs_freq'][i], 20-i-1, 
             s=str(i+1) + '. ' + word + ': '  + str(word_freq_df_abs['abs_freq'][i]),
             ha='right', va='center', fontsize=14, color='white', fontweight='bold')
plt.text(0.4, -1.1, s='Number of times the word was used in a movie title; out of 15500 movies.', fontsize=14)
plt.text(0.4, -1.8, s='Data: boxofficemojo.com Apr. 2018.   Feedback: @eliasdabbas', fontsize=14)


plt.vlines(range(0, 210, 10), -1, 20, colors='gray', alpha=0.1)
plt.hlines(range(0, 20, 2), 0, 210, colors='gray', alpha=0.1)
plt.yticks([])
plt.xticks([])
plt.title('Words Most Used in Movie Titles', fontsize=22, fontweight='bold')

# =============
plt.subplot(1, 2, 2)
# plt.axis('off')
plt.barh(range(20),
         list(reversed(word_freq_df['wtd_freq'][:20])), color='#288FB7')
for i, word in enumerate(word_freq_df['word'][:20]):
    plt.text(word_freq_df['wtd_freq'][i], 20-i-1, 
             s=str(i+1) + '. ' + word + ': ' + '$' + str(round(word_freq_df['wtd_freq'][i] / 1000_000_000, 2)) + 'b',
             ha='right', va='center', fontsize=14, color='white', fontweight='bold')
plt.text(0.4, -1.1, s='Alltime boxoffice revenue of all movies whos title contained the word. (Top word is "2") ', fontsize=14)
plt.text(0.4, -1.8, s='Data collection & methodology: http://bit.ly/word_freq', fontsize=14)

plt.vlines(range(0, 9_500_000_000, 500_000_000), -1, 20, colors='gray', alpha=0.1)
plt.hlines(range(0, 20, 2), 0, 10_000_000_000, colors='gray', alpha=0.1)
plt.xlim((-70_000_000, 9_500_000_000))
plt.yticks([])
plt.xticks([])
plt.title('Words Most Associated With Boxoffice Revenue', fontsize=22, fontweight='bold')
plt.tight_layout(pad=0.01)
plt.show()

words most box office data

Görünüşe göre en azından yapımcıların ve yazarların zihninde aşk her şeye galip geliyor! Tüm film adlarında en çok kullanılan kelime o. Ancak ağırlıklandırılmış sıklık (gişe geliri) söz konusu olduğunda o kadar yukarıda değil.

Başka bir deyişle, tüm film başlıklarına bakarsanız, en çok karşınıza çıkacak kelime 'love' olurdu. Ancak izleyicilerin gözünde en çok hangi kelimenin göründüğünü (metrik olarak toplam gişe gelirini kullanarak) tahmin ederseniz, '2', 'star' ve 'man' en çok görüntülenen ya da en fazla gelirle ilişkilendirilenler olurdu.

Açıklık getirmek gerekirse: bunlar çok basit hesaplamalar. 'love' kelimesinin ağırlıklandırılmış sıklığının 1.604.106.767 olduğunu söylediğinizde, bu yalnızca başlığında 'love' kelimesi geçen tüm filmlerin toplam ömür boyu gişe gelirinin bu tutar olduğu anlamına gelir.

'2' kelimesinin en üstte olması da ilginç. Elbette bu bir kelime değil; ancak film serilerinin ikinci bölümlerinin çok büyük bir toplam oluşturduğunu gösteriyor. Beşinci sıradaki '3' için de aynı durum geçerli. 'part' ve 'ii' ifadelerinin de ilk onda olması bu gerçeği doğruluyor.

'American' ve 'movie' yüksek göreli değere sahip.

Bu fonksiyonda kullanılan stop word’lere dair kısa bir not

Genellikle burada olandan daha kapsamlı bir stop word listesi sağlarsınız; özellikle makaleler veya sosyal medya gönderileriyle uğraşıyorsanız. Örneğin nltk paketi çeşitli dillerde stop word listeleri sağlar; bunlar indirilebilir ve kullanılabilir.

Buradaki kelimeler, üst sıralardaki filmler üzerinde birkaç kontrol yapıldıktan sonra seçildi. Bunların birçoğu genellikle stop word kabul edilir; ancak film adları söz konusu olduğunda bazılarını tutmak mantıklıydı; çünkü fikir verebilirler. Örneğin 'I', 'me', 'you' kelimeleri bazı sosyal dinamiklere işaret edebilir. Bir diğer neden de film adlarının çok kısa ifadeler olması ve onlardan mümkün olduğunca anlam çıkarmaya çalışmamızdır.

Kesinlikle kendi kelime listenizle deneyebilir ve biraz farklı sonuçlar görebilirsiniz.

Orijinal film başlıkları listesine geri döndüğümüzde, en üstteki bazı kelimelerin ilk onda bile yer almadığını görüyoruz ve bu, tam da bu yaklaşımla ortaya çıkarmaya çalıştığımız içgörü türüdür.

boxoffice_df.head(10)
  lifetime_gross rank studio title year
0 936662225 1 BV Star Wars: The Force Awakens 2015
1 760507625 2 Fox Avatar 2009
2 681084109 3 BV Black Panther 2018
3 659363944 4 Par. Titanic 1997
4 652270625 5 Uni. Jurassic World 2015
5 623357910 6 BV Marvel's The Avengers 2012
6 620181382 7 BV Star Wars: The Last Jedi 2017
7 534858444 8 WB The Dark Knight 2008
8 532177324 9 BV Rogue One: A Star Wars Story 2016
9 504014165 10 BV Beauty and the Beast (2017) 2017

Sıradaki mantıklı adım, ilginç olan üst kelimeleri daha fazla keşfetmek olabilir. '2' içeren filmleri filtreleyelim ve görelim:

(boxoffice_df[boxoffice_df['title']                  
              .str
              .contains('2 | 2', case=False)] # spaces used to exclude words like '2010'
              .head(10))
  lifetime_gross rank studio title year
15 441226247 16 DW Shrek 2 2004
30 389813101 31 BV Guardians of the Galaxy Vol. 2 2017
31 381011219 32 WB Harry Potter and the Deathly Hallows Part 2 2011
35 373585825 36 Sony Spider-Man 2 2004
38 368061265 39 Uni. Despicable Me 2 2013
64 312433331 65 Par. Iron Man 2 2010
79 292324737 80 LG/S The Twilight Saga: Breaking Dawn Part 2 2012
87 281723902 88 LGF The Hunger Games: Mockingjay - Part 2 2015
117 245852179 118 BV Toy Story 2 1999
146 226164286 147 NL Rush Hour 2 2001

Üst 'star' filmlerine de bir göz atalım:

boxoffice_df[boxoffice_df['title'].str.contains('star | star', case=False)].head(10)
  lifetime_gross rank studio title year
0 936662225 1 BV Star Wars: The Force Awakens 2015
6 620181382 7 BV Star Wars: The Last Jedi 2017
8 532177324 9 BV Rogue One: A Star Wars Story 2016
11 474544677 12 Fox Star Wars: Episode I - The Phantom Menace 1999
12 460998007 13 Fox Star Wars 1977
33 380270577 34 Fox Star Wars: Episode III - Revenge of the Sith 2005
65 310676740 66 Fox Star Wars: Episode II - Attack of the Clones 2002
105 257730019 106 Par. Star Trek 2009
140 228778661 141 Par. Star Trek Into Darkness 2013
301 158848340 302 Par. Star Trek Beyond 2016

Ve son olarak, üst 'man' filmleri:

boxoffice_df[boxoffice_df['title'].str.contains('man | man', case=False)].head(10)
  lifetime_gross rank studio title year
18 423315812 19 BV Pirates of the Caribbean: Dead Man's Chest 2006
22 409013994 23 BV Iron Man 3 2013
35 373585825 36 Sony Spider-Man 2 2004
48 336530303 49 Sony Spider-Man 3 2007
53 330360194 54 WB Batman v Superman: Dawn of Justice 2016
59 318412101 60 Par. Iron Man 2008
64 312433331 65 Par. Iron Man 2 2010
82 291045518 83 WB Man of Steel 2013
176 206852432 177 WB Batman Begins 2005
182 202853933 183 Sony The Amazing Spider-Man 2 2014

Sonraki Adımlar ve İyileştirmeler

İlk adım olarak daha fazla kelime elde etmeyi deneyebilirsiniz: film adları son derece kısadır ve çoğu zaman kelimelerin gerçek anlamını yansıtmaz. Örneğin, bir vaftiz babası normalde bir çocuğun vaftizine tanıklık eden ve o çocuğa bakmayı taahhüt eden kişidir (ya da belki keyif için öldüren bir mafya babası?!).

Bir sonraki egzersiz, film adına ek olarak daha ayrıntılı açıklamalar elde etmek olabilir. Örneğin:

"Bir bilgisayar korsanı, gizemli isyancılardan gerçekliğinin gerçek doğasını ve denetleyicilerine karşı savaştaki rolünü öğrenir."

bize 'The Matrix'ten çok daha fazlasını anlatır.

Alternatif olarak, analizinizi zenginleştirmek için aşağıdaki yollardan birini de izleyebilirsiniz:

  • Daha iyi istatistiksel analiz: aşırı değerlerin/aykırı değerlerin ele alınması, diğer metriklerin kullanılması.
  • Metin madenciliği: benzer kelimeleri ve konuları bir araya getirme ('happy', 'happiness', 'happily', vb.)
  • Daha ayrıntılı analiz: aynı fonksiyonu farklı yıllar/on yıllar veya belirli yapım stüdyoları için çalıştırma.

Veriyi kendinizin ve diğer verileri de keşfetmek isteyebilirsiniz:

Artık film başlıklarındaki kelime sayımlarını incelediniz, mutlak ve ağırlıklandırılmış sıklık arasındaki farkı ve birini göz ardı etmenin tablonun büyük bir kısmını kaçırmanıza nasıl yol açabileceğini gördünüz. Ayrıca bu yaklaşımın sınırlamalarını gördünüz ve analizinizi nasıl geliştirebileceğinize dair bazı önerileriniz var.

Benzer sayılar içeren herhangi bir metin veri kümesini kolayca analiz etmek için çalıştırabileceğiniz özel bir fonksiyonu oluşturma sürecinden geçtiniz ve bu tür bir veri kümesini anlamanızı nasıl geliştirebileceğini öğrendiniz.

Bunu tweet performansınızı, web sitenizin URL’lerini, Facebook gönderilerinizi veya karşılaşabileceğiniz benzer herhangi bir veri kümesini analiz ederek deneyin.

Kodu depo olarak klonlamak ve kendiniz denemek daha kolay olabilir.

word_frequency fonksiyonu, indirilip çalışmalarınızda/araştırmalarınızda kullanmayı deneyebileceğiniz advertools paketinin bir parçasıdır.

Göz atın ve bana bildirin! @eliasdabbas

Kelime sıklığını nasıl oluşturacağınızı öğrenmek için DataCamp’in Python Sözlükleri Eğitimine ve kelime sıklığı dağılımlarını nasıl çizeceğinizi öğrenmek için Python’da Web Kazıma & NLP eğitimine göz atın.

Konular
Python
Makine Öğrenimi

Python hakkında daha fazlasını öğrenin

Kurs

Python’a Giriş

4 sa
7.1M
Python ile veri analizi temellerini sadece dört saatte öğrenin. Bu çevrimiçi kurs, Python arayüzünü tanıtacak ve popüler paketleri keşfedecektir.
Ayrıntıları GörüntüleRight Arrow
Kursa Başla
Devamını GörRight Arrow
İlgili

blog

2026’da En Popüler 40 Yazılım Mühendisi Mülakat Sorusu

Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Dario Radečić's photo

Dario Radečić

15 dk.

blog

Hızlı Sevkiyat İçin Pratik Vibe Kodlama Teknoloji Yığını

Ön uç, arka uç, veritabanları, kimlik doğrulama, depolama, e-posta, test, dağıtım ve izleme için en iyi araçları keşfedin.
Abid Ali Awan's photo

Abid Ali Awan

14 dk.

Eğitim

Python'da Listeyi String'e Nasıl Dönüştürürsünüz

Bu hızlı eğitimde, Python'da bir listeyi string'e nasıl dönüştüreceğinizi öğrenin.
Adel Nehme's photo

Adel Nehme

Eğitim

.gitignore Nasıl Kullanılır: Örneklerle Pratik Bir Giriş

Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
Kurtis Pykes 's photo

Kurtis Pykes

8 dk.

Devamını GörDevamını Gör