Bu program, yayıncı tarafından "Uygun" olarak etiketlenmiştir.
Python ve kütüphaneleri
1. librosa — loading and resampling audio
def load_audio(path):
y, sr = librosa.load(path, sr=SR, mono=True)
return y, sr
Her bir bölüm, orijinal örnekleme oranına veya kanal sayısına bakılmaksızın, 16 kHz'e (SR = 16000) indirgenir ve tek bir mono akış olarak yüklenir. Bu, librosa, yeniden örnekleme ve stereo'yu mono'ya dönüştürme işlemlerini tek bir hat üzerinde gerçekleştirir. Bu, VAD, pitch izleme ve MFCC çıkarma gibi tüm sonraki araçların, MP3 kodlayıcısı veya podcast yayıncısı tarafından orijinal olarak kullanılan herhangi bir şeyden bağımsız olarak tutarlı ve öngörülebilir bir giriş üzerinde çalışmasını sağlar.
2. Parselmouth (Ses ses ve ses kalitesi takibi)
def pitch_and_hnr(y, sr): snd = parselmouth.Sound(y, sampling_frequency=sr) pitch = snd.to_pitch(time_step=PITCH_TIME_STEP, pitch_floor=PITCH_FLOOR, pitch_ceiling=PITCH_CEILING) f0 = pitch.selected_array["frequency"] times = pitch.xs() try: harmonicity = snd.to_harmonicity_cc(time_step=PITCH_TIME_STEP) hnr = np.array([harmonicity.get_value(t) for t in times]) hnr = np.nan_to_num(hnr, nan=-999.0) exceptException: hnr = np.full_like(f0, 999.0) # başarısız olursa HNR çıkarma hataları return f0, hnr, times
parselmouth, Praat'ın Python arayüzüdür ve fonetik araştırmalarda standart olarak kullanılan araçtır. Bu, ses monotonluğu ölçümünün temelini oluşturur: to_pitch(), her 20 ms'de temel frekansı (F0, yaklaşık "ton") verir ve to_harmonicity_cc(), aynı zaman damgalarında harmonik-gürültü oranını (HNR) verir — bu, daha sonra gürültülü veya kötü sıkıştırılmış seslerden elde edilen ton tahminlerini ortadan kaldırmak için kullanılan bir sinyal kalitesi puanıdır, böylece kötü sesler "düz" ton gibi görünmez.
3. webrtcvad — hangi karelerin gerçekte konuşma olduğunu belirleme
def vad_speech_mask(y, sr, aggressiveness=2): vad = webrtcvad.Vad(aggressiveness) pcm16 = (np.clip(y, -1.0, 1.0) *32767).astype(np.int16) n_frames =len(pcm16) // VAD_FRAME_LEN mask = np.zeros(n_frames, dtype=bool) for i inrange(n_frames): chunk = pcm16[i * VAD_FRAME_LEN:(i +1) * VAD_FRAME_LEN] raw = struct.pack("%dh"%len(chunk), *chunk) try: mask[i] = vad.is_speech(raw, sr) exceptException: mask[i] =False return mask, times
webrtcvad, Google'ın WebRTC projesinden elde edilen ses aktivite tespit aracıdır — bir kareye bir kareye sınıflandırıcı ("bu 30 ms'lik bölüm konuşma mı yoksa değil mi"). Bu nedenle, 16 bitlik PCM baytları, kayan noktalı sayılar yerine kullanılması gerekir, bu nedenle np.clip ve struct.pack dönüşümlerini kullanır.
4. librosa.feature — Müzik ve konuşmayı ayırt etme
flatness = librosa.feature.spectral_flatness(y=y, hop_length=hop)[0] chroma = librosa.feature.chroma_stft(y=y, sr=sr, hop_length=hop) onset_env = librosa.onset.onset_strength(y=y, sr=sr, hop_length=hop) ... chroma_diff = np.mean(np.linalg.norm(np.diff(chroma_win, axis=1), axis=0)) chroma_stability = 1.0 / (1.0 + chroma_diff) ... scores[w] = 0.4 * chroma_stability + 0.35 * periodicity + 0.25 * min(flat_mean * 3, 1.0)
Podcast'lerin giriş/çıkış müzikleri genellikle müziktir ve müzik, konuşmadan çok farklı bir frekans profiline sahiptir — bu da "monoton" ölçümünü etkileyecektir. Sınıflandırıcı eğitmek yerine, üç librosa özelliği, elle ayarlanmış ağırlıklarla birleştirildi: spektral düzlük (müzik, daha fazla tonal yapıya, daha az gürültü benzer bir spektruma sahiptir), chroma kararlılığı (süreklilikte harmonik vs.
(sürekli değişen konuşma frekansları) ve başlangıç periyodunu (düzenli bir ritim vs. konuşmanın düzensiz ritmi).
librosa.feature.mfcc + sklearn.cluster.KMeans + sklearn.metrics.silhouette_score — bir konuşmacı sayma denemesi
mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13, hop_length=hop)
MFCC'ler (Mel-frekans cepstral katsayıları), kısa bir ses penceresinin spektrumunun şeklini özetler — konuşma görevlerinde yaygın olarak kullanılan, yaklaşık bir "konuşma parmak izi". Fikir: Her bölümü 2 saniyelik parçalara ayırın, her birini bir parmak izi vektörüne dönüştürün, özellikleri standartlaştırın (z-skoru), ardından KMeans'i kullanarak parçaların doğal olarak 2+ kümeye (farklı konuşmacılar) bölünüp bölünmediğini veya 1'e (bir konuşmacı boyunca) kontrol edin. silhouette_score, kümelerin ne kadar iyi ayrıldığını puanlar ve en iyi k'yı seçer — veya minimum kalite çubuğu karşılamayan hiçbir kümeleme durumunda "1 konuşmacı"ya geri döner. Bu bölüm, başka bir konuşmacıyı algıladığı için işe yaramadı.
scipy.stats.mannwhitneyu + elle yazılmış bir Cliff's delta — normal dağılım varsayımı olmadan iki grup karşılaştırma
def cliffs_delta(a, b):
scipy.stats.mannwhitneyu, istatistiksel bir testtir: sayıların iki grubunu (HPR ile karşılaştırma podcast'leri, bir ölçüye göre) karşılaştırır ve bunlar normal dağılıma sahip olduğunu varsaymaz — eğimli, gerçek dünya verilerine, örneğin pitch-range ölçümlerine uygun. SciPy, bu testle birlikte bir etki büyüklüğü ölçüsü sağlamaz, bu nedenle Cliff'in delta'sı — "Mümkün olan tüm (HPR bölümü, karşılaştırma bölümü) çiftleri arasında, HPR'nin değeri daha sık hangisi daha küçük?" Bu eşleştirme (bir anlamlılık testi artı bir etki büyüklüğü sayısı) tüm boyunca kullanılmıştır, çünkü düşük bir p-değeri tek başına, farkın gerçekten önemli olup olmadığını söylemez.
7. pandas — sonuçları gruplama, sınıflandırma ve çapraz tablolama
print(df.groupby("corpus")["retained_fraction"].describe())
...
print(pd.crosstab(df["corpus"], df["register"]))
Bir kez data/results.jsonl (her bir analiz edilen bölüm için bir JSON nesnesi) bir pandas.DataFrame'ine yüklendikten sonra, iki satır komutu, genellikle özel kod gerektiren iki farklı soruya cevap verir: .groupby(...).describe() komutu, bir veri kümesi için ses kalitesi kapsamının dağılımı (sayım, ortalama, standart sapma, çeyrekler) hakkında bir özet sağlar ve pd.crosstab() komutu, HPR'yi erkeklik/kadınlık tipik konuşma tarzına karşı çapraz tablolar, iki podcast koleksiyonunun benzer cinsiyet konuşma tarzı karışımına sahip olup olmadığını hızlı bir şekilde kontrol etmek için kullanılır.
8. matplotlib — Box plot'lar, başlık karşılaştırması için
fig, ax = plt.subplots(figsize=(6, 4))
data = [df[(df.corpus == c) & (df[metric].notna())][metric].values for c in ["hpr", "comparison"]]
ax.boxplot(data, tick_labels=["HPR", "Comparison"], showmeans=True)
Box plot, pitch-range metriği, HPR, karşılaştırma podcast'leriyle birlikte, ortalama ve medyan değerleri.
9. spacy kelime vektörleri – sadece kelime seçimi değil, konu kaymasını ölçmek
nlp = get_nlp() # spacy.load("en_core_web_md")
...
chunk_docs = [nlp(c) for c in chunks]
chunk_vecs = []
for d in chunk_docs:
v = d.vector
norm = np.linalg.norm(v)
if norm > 1e-6:
chunk_vecs.append(v / norm)
...
adj_sims = [float(np.dot(V[i], V[i + 1])) for i in range(n - 1)]
Herkes ~130 kelimelik bir transkript parçası, spaCy'nin orta İngilizce modelini (en_core_web_md, içinde yerleşik kelime vektörleri olan) kullanarak tek bir vektöre dönüştürülür ve ardından L2 normalleştirilir, böylece iki vektör arasındaki nokta çarpımıisonlarının kosinüs benzerliği. Ardışık parçaların benzerliğini karşılaştırmak, "konu bir parçadan diğerine neredeyse hiç değişmedi" puanı verir.
10. sözlüce zenginliği – transkript uzunluğunu aşmadan, kelime çeşitliliğinin korunması
lr = LexicalRichness(text) try: mtld = lr.mtld(threshold=0.72) except Exception: mtld = None
Bir metnin uzunluğu arttıkça, kelime çeşitliliği puanı (benzersiz kelimeler ÷ toplam kelimeler) kötüleşir, çünkü bu ölçüm nasıl tanımlanmışsa tanımlanmış. Bu, konuşmacının aslında daha fazla tekrar etmesinden kaynaklanmaz.
MTLD (Measure of Textual Lexical Diversity) bu bu yöntemi kullanarak, metni tarar ve çeşitliliğin belirli bir eşik değerinin altına düşene kadar kaç kelime gerektiğini sayar, ardından ortalamayı alır — bu, 10 dakikalık ve 40 dakikalık bir bölüm arasındaki karşılaştırmaları mümkün kılmak için özel olarak tasarlanmış bir ölçüttür.
11. vaderSentiment — bir sözlük tabanlı duygu puanı
vader = get_vader() # SentimentIntensityAnalyzer() duygusal_değerlendirmeler = [vader.polarity_scores(c)["compound"] for c in parçalar] ... "sentiment_std": float(np.std(duygusal_değerlendirmeler)) eğer len(duygusal_değerlendirmeler) > 1 ise aksi taksa None,
VADER her bir bölümün duygu skorunu, -1 ile +1 arasında, elle oluşturulmuş bir sözlük ve kural seti kullanarak hesaplar (nöral ağ değil) — bu, hızlı, deterministik ve her bölüm için, yüzlerce bölüm üzerinde çalıştırılabilir kadar ucuz olması için seçilmiştir. Kullanılan değer, ortalama duygu değeri değildir, ancakstandart sapmaduygu yoğunluğunu bir bölümün bölümlerine yaymak: bir bölümün duygusal
Tonu sürekli değişiyor mu, yoksa düz bir şekilde kalıyor mu?
12. zlib (standart kütüphane) — sıkıştırma oranı, entropi ölçüsü olarak
def compression_ratio(text):
raw = text.encode("utf-8")
if len(raw) < 200:
return None
compressed = zlib.compress(raw, level=9)
return len(compressed) / len(raw)
Kullanılan üçüncü taraf NLP kütüphanesiyle hiçbir ilgisi yok — sadece standart kütüphanenin zlib modülü kullanılıyor. gzip tarzı bir sıkıştırma, tekrar eden kalıpları bulur ve kullanır; eğer transkripti önemli ölçüde sıkıştırabilirse, bu transkript nispeten tekrarlayıcı ve öngörülebilirdi ve eğer neredeyse hiç sıkıştıramazsa, kelime kullanımı daha çeşitliydi. Bu, kabaca "sözlü monotonluğu"nu gösteriyor.
13. re (standart kütüphane) — "HPR, tek sunucuları mı tercih ediyor" ifadesini kontrol edilebilir bir kurala dönüştürme
MULTI_PRESENTER_PATTERNS = [ r"\bco-?host(?:s|ed|ing)?\b", r"\bguest\b", r"\binterview(?:s|ed|ing)?\b", r"\btalks? with\b", r"\bjoins? me\b", ... ] CORRESPONDENT_LINK_RE = re.compile(r'correspondents/(\d+)\.html') def multi_presenter_score(summary, notes): text = (summary or"") +" "+ (notes or"") hits = [p for p in MULTI_PRESENTER_PATTERNS if re.search(p, text, re.IGNORECASE)] summary_links =set(CORRESPONDENT_LINK_RE.findall(summary or"")) return { "flagged_multi_presenter": bool(hits) or len(summary_links) >1, }
Esn yerine, daha güvenilir bir çözüm, basit metinden elde edilen HPR'nin kendi bölüm verilerinden (yerel bir bilgi tabanından çekilen) oluşturulan, sunucu tarafından yazılan özetlerden ve kısa bir regex kalıbı listesinden ("konuk", "röportaj", "birlikte", vb.) ve bağlantılı ilgili profillerin sayılmasından elde edilen bilgilerle, olası çok konuşmacı bölümleri belirlemek için yeterliydi.
14. multiprocessing.Pool — Aynı analizi yüzlerce dosya üzerinde çalıştırmak, yüzlerce kez beklemeden
work = [(r, local_paths[r["id"]]) for r in batch] with mp.Pool(args.workers) as pool, open(args.out, "a") as out_f: for result in pool.imap_unordered(_worker, work): out_f.write(json.dumps(result) +"\n") out_f.flush()
Her metot, her (akustik ton analiz, konuşmacı sayma) her bölümü aynı şekle kullanıyordu: Pool(workers).imap_unordered(...) ile birden fazla CPU çekirdeğinde aynı anda her bölüm için fonksiyonu çalıştırmak, her biri bittiğinde sonuçları JSON-satır formatında bir dosyaya akış yapmak yerine, tüm bölümün beklemesini önlemek. imap_unordered, map'ten tercih edildi çünkü tek bir yavaş bölüm, zaten tamamlanmış sonuçları yazmaktan alıkoyamazdı.
15. subprocess + yenilenebilir bir bölüm döngüsü — disk alanı sınırları içinde çalışma
def load_done_ids(results_path):
Tüm podcast'ler (~220GB), yerel diske (~54GB boş) sığmadı. Çözüm, bir döngü kullanmaktı: scp (subprocess aracılığıyla) bir ses bölümünü al, analiz et, sil, bir sonraki bölüme git. load_done_ids(), çıktıda zaten olanı okuyarak tüm bölümü yeniden başlatmayı sağlar, böylece bir arıza veya orta noktada kasıtlı bir durdurma, tamamlanmış verileri kaybetmez.
Bağlantılar
- Y Combinator, bir girişim sermayesi şirketinin, "The Morning" adlı podcast'i başlatmasıyla ilgili haber. Podcast, Y Combinator'un girişimcilerle düzenlediği günlük röportajları içeriyor. İlk bölüm, Y Combinator'un kurucusu Paul Graham'ın röportajıydı. Podcast, girişimciler ve yatırımcılar arasında bir iletişim platformu olarak hizmet etmeyi amaçlıyor. Y Combinator, podcast'i başlatarak, girişimcilerle daha yakından etkileşim kurmak ve onların deneyimlerini paylaşmak istiyor. Podcast, Y Combinator'un girişimcilik ekosistemindeki rolünü güçlendirmeyi hedefliyor. İlk bölüm, Paul Graham'ın girişimcilik yolculuğu ve Y Combinator'un başarısının ardındaki sırların detaylı bir analizini içeriyor. Podcast, hem yeni başlayan girişimciler hem de deneyimli girişimciler için değerli bilgiler sunuyor. Y Combinator, podcast'i düzenli olarak yayınlamayı planlıyor ve farklı alanlardaki girişimcilerle röportajlar yapmayı hedefliyor. Podcast, Y Combinator'un girişimcilik ekosistemindeki etkisini artırmayı ve daha geniş bir kitleye ulaşmayı amaçlıyor.
- ABD, Rusya ve Avrupa ülkelerinin, Ukrayna'ya yönelik askeri ve ekonomik desteğini artırması, Rusya'nın Ukrayna'daki varlığını sürdürmesi ve savaşın uzamasıyla birlikte, Ukrayna'nın askeri ve ekonomik kaynaklarının tükenme riski artıyor. Ukrayna hükümeti, Rusya'nın saldırılarını durdurmak ve ülkeyi yeniden inşa etmek için uluslararası desteğini artırma çağrısında bulunuyor. Ayrıca, Ukrayna ordusunun ve ekonomisinin yeniden güçlendirilmesi için uluslararası yardım ve finansman talep ediyor. Ukrayna'nın askeri ve ekonomik kaynaklarının tükenmesi, ülkenin geleceği için ciddi bir tehdit oluşturuyor. Bu durum, Ukrayna'nın Rusya ile müzakerelerde daha güçlü bir pozisyonda olmasını ve Rusya'nın Ukrayna'daki varlığını sürdürmesini zorlaştırabilir. Ukrayna'nın uluslararası desteğini artırma çabaları, Rusya'nın Ukrayna'daki varlığını sürdürmesi ve savaşın uzamasıyla birlikte, Ukrayna'nın askeri ve ekonomik kaynaklarının tükenme riskini azaltmaya yardımcı olabilir.
Evet, Hacker Public Radio'nun büyüleyici dünyası: teknoloji uzmanlarının ✨️, insanlığın bilmediği en büyüleyici tonlarda birbirlerine büyüleyici sırlarını açtığı, şirin bir köşe. Sonsuz "topluluk" podcast'lerinin bu kadar... tamamen büyüleyici olacağını kim tahmin edebilirdi? 📻️🎙️ Açıkçası, herkes bu karmaşaya yılda bir kez katkıda bulunmak için sabırsızlanıyor gibi görünüyor—ne büyük bir ayrıcalık! 😂
Hacker Public Radio, bir teknoloji ve siber güvenlik odaklı radyo istasyonu, çeşitli konuklarla ve uzmanlarla röportajlar yaparak, güncel konuları ve teknolojik gelişmeleri tartışıyor. Stüdyoları, genellikle Hacker Public Radio'nun web sitesi üzerinden canlı yayınlanıyor.
#HackerPublicRadio #teknolojiTopluluğu #podcast #MonotoneMagic #ilgiÇekenİçerik #HackerNews #ngated
