YAKE kütüphanesi ile Türkçe Metinlerden Anahtar Terimleri Türetin


Big Data (Büyük Veri) Nedir?. Günümüzün popüler kavramlarından biri… | by Big  Data Turkey | Düşünen Beyinler | Medium

Python ile herhangi bir metin içerisinden anahtar terimler çıkarma ve bunlara ilgililğine görse sayısal değerler vermek isterseniz Rake gibi kütüphaneler vardır ancak bunlar Türkçe dil desteği içeremez.

Türkçede bu işi yapmak için Yake adlı bir kütüphane vardır. Akademik makalesi de şurada:

Bu yazıda elimde bulunan bir haber veriseti içinde her bir haberin anahtar terimleri içindeki en yüksek değerleri başka bir kolona atıp daha sonra arama yapınca sadece en yüksek ilgili ifade işe eşleşme sağladım. Bu sayede içinde aradığım kelime geçen yazı değil, aradığım terimle ilgili olma olasılığı en yüksek olan haber geliyor. Bir nevi lokal google yani.

Hadi bu lezzetli tarifimi vereyim:

Önce Yake kütüphanesini kuralım:

# !pip install yake

Şimdi de Türkçeye göre ayarlama yapalım:

from yake import KeywordExtractor
import pandas as pd
kw_extractor = KeywordExtractor(lan="tr", n=1, top=5)

Verisetimi okuyorum:

df =pd.read_csv("deneme.csv")
text = df.at[22,'headline']
print(text)

Örnek bir haber:

Kuyu çöktü, 2 kişi toprak altında kaldı

Deneme 1,2,3:

keywords = kw_extractor.extract_keywords(text)
keywords
max(keywords)

Bu metin “toprak” ile ilgili (en çok). Elbette kusursuz değil ama istersek tüm anahtar kelimeleri de dizeriz.

(0.6286477325744138, 'toprak')

Şimdi dev verisetimde teker teker deniyorum:

secim = df
#secim.headline

Her bir çıktı anahtar terimin en yüksek değere sahip olanı olasılık rank değeri ile birlikte kolonlara aktardım:

secim['tk_ozet'] = ""
secim['tk_ihtimal'] = None
for index,row in secim.iterrows():
   try:
       haber = row['headline']
       keywords = kw_extractor.extract_keywords(haber)
       olasilik = round(float(max(keywords)[0]),2)
       tekkelime = max(keywords)[1]
       secim.at[index,'tk_ozet'] = tekkelime
       secim.at[index,'tk_ihtimal'] = olasilik
       #print(f"{haber}--> {tekkelime}: {olasilik}")
   except  Exception as ex:
       #print(str(ex))
       pass

Şimdi arama denemesi zamanı:

terim = "çocuk"
secim[secim.tk_ozet.str.contains(terim)][['headline','tk_ihtimal']].sort_values("tk_ihtimal",ascending=False)

​​

.dataframe tbody tr th {
  vertical-align: top;
}

.dataframe thead th {
  text-align: right;
}

</style>​

headlinetk_ihtimal
506Dini nikahlı kocası bıçakladı! 1 çocuk annesi …0.78
915Başakşehir anne çocuk merkezine sahip çıkıyor0.7
781Köy çocuklarının sesi oldular0.63
1204Pandemide çocukların yüzünü güldürdüler0.63
1423Gülabibey’de çocuklar mutlu0.54
1055Aydın Kadın Doğum ve Çocuk Hastalıkları Hastan…0.34
2052Lüleburgaz Belediyesi “Çocuk Hakları” Toplantı…0.25
2143ÇOCUKLARINA KAVUŞTU0.14

</div>

Haberleri “çocuk” terimi ile en ilgili şekilde listeledik. Kusursuz değil ama yakın.

News Please!: Haber analizi yapanlar için ilaç gibi bir Crawler


Kendi küçük crawler’ınızı oluşturmak ister misiniz? Ben haber analitiği ile ilgili çalışmalarımı yaparken eksteriyetle çok miktarda habere ihtiyaç duyuyorum. Şu ana kadar scra.py, newspaper3k gibi bir çok kütüphane kullandım Python’da. R’da ise Rvest. Ancak bu kütüphaneler bir yere kadar işe yarıyor. Çekebildiğim en fazla miktar 50.000 civarında haber idi. Burada suç bu kütüphanelerin değil, daha teknik ayrıntıda.

Yeni keşfettiğim kütüphane ise scraping değil crawling yapıyor ayrıca her çekilen veriyi .hjson formatında kayedediyor. CLI modunda sadece başlangıç sitesi vermek yeterli. O özel yollarla linkleri buluyor.

Kütüphane linki şurada: https://github.com/fhamborg/news-please#run-the-crawler-via-the-cli

Buradan derlenen haberler bilgisayarınıza json formatında ayrıştırılmış olarak (başlık, tarih, fulltext) ve html dosyasının kendisi ile birlikte gelir. Bu dosyaları ise Python Pandas ile birleştirip analiz edebilirsiniz:

Benim kendi lokalimdeki çalışan kodlar şunlar:

path_to_json = '/home/suat/news-please-repo/data/2020/10/15/haberler.com'
json_files = [pos_json for pos_json in os.listdir(path_to_json) if pos_json.endswith('.json')]
print(json_files)  # for me this prints ['foo.json']
jsons_data = pd.DataFrame(columns=['id', 'baslik','tarih','sayfa_url','tanim','anametin'])

i=0
for index, js in enumerate(json_files):
    with open(os.path.join(path_to_json, js)) as json_file:
        json_text = json.load(json_file)
        # here you need to know the layout of your json and each json has to have
        # the same structure (obviously not the structure I have here)
        anametin = json_text['maintext']
        baslik = json_text['title']
        tarih =  json_text['date_publish']
        sayfa_url = json_text['url']
        tanim = json_text['description']
        #city = json_text['features'][0]['properties']['name']
        #lonlat = json_text['features'][0]['geometry']['coordinates']
        # here I push a list of data into a pandas DataFrame at row given by 'index'
        jsons_data.loc[index] = [i,baslik,tarih,sayfa_url,tanim,anametin]
        i=i+1

Metin Madenciliğinde Kullanılan TF.IDF skoru nasıl hesaplanır


Elinizde diyelim ki Suriye hakkında yazılmış bir milyon habervar. Tek tek okumayı düşünmüyorsunuz:) Bu dokümanların içinden söz gelimi İdlib hakkında geçen haberleri arayacaksınız. Hemen Ctrl+F’ye davranıyorsunuz 120806 adet kavram geliyor. Eh bunları da okuyazsınız. Peki bunların içinden en ilgili olanı okumak isterseniz ne yaparsınız. Bir nevi kendi küçük Google’nizi yaratmanız gerekecek. İşte tam burada böyle bir durumda TF.IDF skoru hesaplatmak yardımınıza koşar. Nasıl yapılacağını basit bir simülasyonla şurada anlattım.

RCrawler ile Web Crawling İşlemi


Metin madenciliği yapabilmek için elde büyük miktarda verinin olması gereklidir. Bu miktardaki veriyi ancak ya hazır bulmak ya da web scraping adını verdiğimiz yöntemlerle web sayfalarından derlemek durumundayız. Bu durumda ise Python için kullanılacak scrapy, ve python selenium gibi kütüphanelerin yanında R için Rvest ve scrapeR gibi kütüphaneler bulunmaktadır.

R için Rcrawl adlı bir kütüphane daha bulunmaktadır. Bu kütüphaneyi yeni keşfettim. RCrawl kütüphanesinin diğerlerinden temel farkı scraping işleminde sayfa içerisinde scrape edilecek elementlerin yerlerini CSS veya XPath ile belirleme ihtiyacının olmaması. Bu durum sayfa içinde “iğne” arama külfetinden kurtarıyor. Ayrıca çok ama çok daha kısa kod ile scraping yapmayı sağlıyor.

library(Rcrawler)
Rcrawler(Website = "https://www.sayfa_adi.com/lg-mobile", 
                    no_cores = 4, 
                    no_conn = 4, 
                    crawlZoneCSSPat = c("#gridListView",".pagination"))

ASlında sadece web sayfasını parametre olarak versek de crawler sayfaları derlemeye ve bir klasöre atmaya başlıyor. Ancak bu kütüphanenin (şu adresteki https://github.com/salimk/Rcrawler ) dokümantasyonunda gördüğüm çok iyi özellikler var. Bunlardan en önemlisi no_cores ve no_conn parametreleri bu parametreler aynı anda birden fazla scraping bağlantısı ile hızı arttırıyor.

Bu crawler epey agresif. Sayfada bulduğu her bağlantıyı açarak o bağlantıyı ve altındaki bağlantıları da alıyor. Bu durum daha sonra baş edilmesi güç miktarda ilgili ilgisiz verinin gelmesine neden olabilir. Bunu engellemek için crawlZoneCSSPat parametresi mevcut, bu parametre saydada sadece ilgili CSS selectorü ile tanımlı yerdeki linkleri (mesela haber linki, yorumlar vs.) açıyor, sayfadaki diğer ilgisiz linklere izin vermiyor.

Kütüphane dokümantasyonunda ayrıca URL parametresi ile filtreleme, proxy ekleme, sadece belli bir url listesini indirme gibi özelliklerin yanında sayfalar arası bağlantıları network grafiği ile gösterme gibi harika özellikler de mevcut.

Keyifli kullanımlar…