Soğan mı Soğan mı?


11

Soğan (uyarı: birçok makale NSFW'dir) geleneksel haber medyasını parodileri olan hicivli bir haber kuruluşudur. 2014 yılında, Soğan BuzzFeed gibi "clickbait" sitelerini parodize eden hicivli bir haber sitesi olan ClickHole'u (uyarı: ayrıca NSFW) başlattı . Sayesinde Poe'nun Kanun insanlar Soğan veya ClickHole makalelerin başlıklarını okumak değil onlar hiciv olması amaçlanmıştır bilerek onları doğru olduğuna inanmak için, oldukça yaygın bir durumdur. Sohbet aynı zamanda saçma gelen gerçek haberlerle de olur - insanlar genellikle değilken hiciv olduklarını düşünürler.

Bu karışıklık doğal olarak bir oyuna katkıda bulunur - bir haber başlığı verildiğinde, hiciv olup olmadığını tahmin etmeye çalışın. Bu zorluk, tam olarak bunu bir programla yapmakla ilgilidir.

Bir haber başlığı (yalnızca yazdırılabilir ASCII karakterleri ve boşluklarından oluşan bir dize) 1verildiğinde, başlık hiciv ise veya 0değilse. Puanınız, doğru çıktının sayısının toplam başlık sayısına bölünmesiyle elde edilir.

Her zaman olduğu gibi, standart boşluklara (özellikle test senaryoları için optimize etme ) izin verilmez. Bunu zorlamak için, programlarınızı bir dizi 200 gizli test vakasında çalıştıracağım (100 Soğan, 100 Soğan değil). Çözümünüzün geçerli olabilmesi için, açık test örneklerindeki puanınızdan en fazla 20 puan daha az puan alması gerekir.

Test Durumları

Bu meydan okuma için test durumları ile gelip için, ben 25 manşetlere aldı Soğan subreddit dan (ClickHole gibi Soğan ve alt sitelerinden makaleler, yayınlanır) ve 25 manşetleri Değil The Onion subreddit (burada gerçek haber makalelerini hiciv gibi sesler yayınlanır). Manşetlerde yaptığım tek değişiklik, "süslü" teklifleri normal ASCII teklifleriyle değiştirmek ve büyük harf kullanımını standartlaştırmaktı - diğer her şey orijinal makalenin başlığında değişmeden kaldı. Her başlık kendi satırındadır.

Soğan başlıkları

Trump Warns Removing Confederate Statues Could Be Slippery Slope To Eliminating Racism Entirely
'No Way To Prevent This,' Says Only Nation Where This Regularly Happens
My Doctor Told Me I Should Vaccinate My Children, But Then Someone Much Louder Than My Doctor Told Me I Shouldn't
Man At Park Who Set Up Table Full Of Water Cups Has No Idea How Passing Marathon Runners Got Impression They Can Take Them
This Child Would Have Turned 6 Today If His Mother Hadn't Given Birth To Him In October
Incredible Realism: The Campaign In The Next 'Call Of Duty' Will Begin At Your Avatar's High School Cafeteria When He's Being Tricked Into Joining The Military By A Recruiter
'Sometimes Things Have To Get Worse Before They Get Better,' Says Man Who Accidentally Turned Shower Knob Wrong Way
Report: Uttering Phrase 'Easy Does It' Prevents 78% Of Drywall Damage While Moving Furniture
Barbara Bush Passes Away Surrounded By Loved Ones, Jeb
Family Has Way Too Many Daughters For Them Not To Have Been Trying For Son
News: Privacy Win! Facebook Is Adding A 'Protect My Data' Button That Does Nothing But Feels Good To Press
Dalai Lama Announces Next Life To Be His Last Before Retirement
Researchers Find Decline In Facebook Use Could Be Directly Linked To Desire To Be Happy, Fully Functioning Person
Manager Of Combination Taco Bell/KFC Secretly Considers It Mostly A Taco Bell
Trump: 'It's My Honor To Deliver The First-Ever State Of The Union'
Daring To Dream: Jeff Bezos Is Standing Outside A Guitar Center Gazing Longingly At A $200 Billion Guitar
Area Dad Looking To Get Average Phone Call With Adult Son Down To 47.5 Seconds
Experts Warn Beef Could Act As Gateway Meat To Human Flesh
Jeff Bezos Named Amazon Employee Of The Month
Dad Suggests Arriving At Airport 14 Hours Early
Report: Only 3% Of Conversations Actually Need To Happen
Delta Pilot Refuses To Land Until Gun Control Legislation Passed
Family Wishes Dad Could Find Healthier Way To Express Emotions Than Bursting Into Full-Blown Musical Number
New Honda Commercial Openly Says Your Kids Will Die In A Car Crash If You Buy A Different Brand
Teacher Frustrated No One In Beginner Yoga Class Can Focus Chakras Into Energy Blast

Soğan başlıkları değil

Man Rescued From Taliban Didn't Believe Donald Trump Was President
Nat Geo Hires Jeff Goldblum To Walk Around, Being Professionally Fascinated By Things
Mike Pence Once Ratted Out His Fraternity Brothers For Having A Keg
Reddit CEO Tells User, "We Are Not The Thought Police," Then Suspends That User
Trump Dedicates Golf Trophy To Hurricane Victims
Uber's Search For A Female CEO Has Been Narrowed Down To 3 Men
ICE Director: ICE Can't Be Compared To Nazis Since We're Just Following Orders
Passenger Turned Away From Two Flights After Wearing 10 Layers Of Clothing To Avoid Luggage Fee
Somali Militant Group Al-Shabaab Announces Ban On Single-Use Plastic Bags
UPS Loses Family's $846k Inheritance, Offers To Refund $32 Shipping Fee
Teen Suspended From High School After Her Anti-Bullying Video Hurts Principal's Feelings
Alabama Lawmaker: We Shouldn't Arm Teachers Because Most Are Women
Cat Named After Notorious B.I.G. Shot Multiple Times - And Survives
EPA Head Says He Needs To Fly First Class Because People Are Mean To Him In Coach
Apology After Japanese Train Departs 20 Seconds Early
Justin Bieber Banned From China In Order To 'Purify' Nation
Alcohol Level In Air At Fraternity Party Registers On Breathalyzer
NPR Tweets The Declaration Of Independence, And People Freak Out About A 'Revolution'
Man Who Mowed Lawn With Tornado Behind Him Says He 'Was Keeping An Eye On It.'
After Eating Chipotle For 500 Days, An Ohio Man Says He's Ready For Something New
'El Chapo' Promises Not To Kill Any Jurors From Upcoming Federal Trial
After 4th DWI, Man Argues Legal Limit Discriminates Against Alcoholics
Palestinian Judge Bans Divorce During Ramadan Because 'People Make Hasty Decisions When They're Hungry'
Argentinian Officers Fired After Claiming Mice Ate Half A Ton Of Missing Marijuana
'Nobody Kill Anybody': Murder-Free Weekend Urged In Baltimore

6
Your score will be the number of correct outputs divided by the total number of headlinesBayt bir tie breaker mı?
Skidsdev

9
Biraz kafam karıştı. Ne tür bir çözüm bekliyorsunuz? Her çözüm biraz "test senaryoları için optimize etmek", İngilizce anlayabilen ve mizah duygusu olan bir AI yazma çubuğu olacak. Örneğin, Arnauld'un çözümü /ly\b/hangisinin işe yaradığını algılar , çünkü seçtiğiniz 25 Soğan başlığında daha fazla zarf bulunur, ancak bildiğim kadarıyla farklı bir test pili ile kolayca açabilirsiniz. Ve kim katsayılarını puanını optimize etmek için seçilmedi diyebilir ki? (Neden onları optimize etmiyor?)
Lynn

10
Bu test pili biraz sıra dışı görünüyor. Bu, bir fotoğraftaki köpekleri algılayabilen bir sınıflandırıcı istemek gibi, ancak pozitif test durumlarınızı köpeklerin fotoğrafları ve negatif test örnekleriniz olarak "Yemin Edeceğiniz Nesnelerin 25 Fotoğrafı Köpek, Ama Hayır, Dönüyor" başlıklı bir Buzzfeed makalesinden almak gibi Dışarıda değiller! (# 11 Aklını Uçuracak!)
Sophia Lechner

4
Zorluk sadece zor değil, aynı zamanda (benim için) farkın ne olduğu da belli değil. Bunu çözemezseniz (beni ikna o test durumları için hardcode değil yapar iken olduğunu), elbette programım bunu çözemezler
user202729

4
brain.jsBu konuda örnekler ve sağlanan bağlantılardan her türden 100 diğer örnekle yapay sinir ağını ve LSTM'yi kullanarak +36 saat harcadım , ancak sonuç eğitim setlerinde bulunmayan yeni başlıklarla yeterince iyi değildi .
Yaptım

Yanıtlar:


7

JavaScript (ES7), 39/50 (% 78)

Gizli test vakalarında% 63,5 (127/200)

Başlığın uzunluğuna, boşluk sayısına ve -lyson ekin kullanımına dayalı basit bir sezgisel tarama.

isOnion = str =>
  str.length ** 0.25 +
  str.split(' ').length ** 1.25 * 2 +
  str.split(/ly\b/).length ** 1.75 * 7
  > 76

Çevrimiçi deneyin!


Bu ne kadar basit olduğu için saçma bir şekilde etkilidir.
Don Bin

Bu çözüm gizli test senaryolarında% 63.5 puan almıştır, bu nedenle geçerlidir.
Mego

Korumalı alanın başlangıcında mümkün olduğu kadar basit değil (% 100, standartlaştırılmadan önce büyük harf kullanım farklılıklarını kullanmak) ama bu gerçekten basit.
Zacharý

@Mego Meraktan yeni çıkmış olan bu NSFW sürümü , gizli test senaryolarındaki puanı geliştiriyor mu? :)
Arnauld

@Arnauld% 66 bu versiyonla
Mego

6

Python 3,% 84

Gizli test senaryolarında denenmemiş.

Bu, çeşitli başlıklarda eğitilmiş Keras LSTM RNN kullanır. : Çalıştırmak için aşağıdakileri ve ben GitHub üzerinde hazırladığınız modeli keras gerek repo bağlantı . Modele ihtiyacınız olacak .h5ve kelime / vektör eşleşmeleri mevcut .pkl. En son

Bağımlılıklar:

import numpy as np
from pickle import load
from keras.preprocessing import sequence, text
from keras.models import Sequential
from keras.layers import Dense, Embedding, SpatialDropout1D, LSTM, Dropout
from keras.regularizers import l2
import re

Ayarlar:

max_headline_length = 70
word_count = 20740

Model:

model = Sequential()
model.add(Embedding(word_count, 32, input_length=max_headline_length))
model.add(SpatialDropout1D(0.4))
model.add(LSTM(64, kernel_regularizer=l2(0.005), dropout=0.3, recurrent_dropout=0.3))
model.add(Dropout(0.5))
model.add(Dense(32, kernel_regularizer=l2(0.005)))
model.add(Dropout(0.5))
model.add(Dense(2, kernel_regularizer=l2(0.001), activation='softmax'))

Şimdi modeli ve kelime düğünlerini yüklemek için:

model.load_weights('model.h5')
word_to_index = load(open('words.pkl', 'rb'))

Ve bir dize 'NotTheOnion' ya da 'TheOnion' olup olmadığını test etmek için kod dizeyi ilgili kelime düğünlere dönüştüren hızlı bir yardımcı işlevi yazdım:

def get_words(string):
  words = []
  for word in re.finditer("[a-z]+|[\"'.;/!?]", string.lower()):
    words.append(word.group(0))
  return words

def words_to_indexes(words):
  return [word_to_index.get(word, 0) for word in words]

def format_input(word_indexes):
  return sequence.pad_sequences([word_indexes], maxlen=max_headline_length)[0]

def get_type(string):
  words = words_to_indexes(get_words(string))
  result = model.predict(np.array([format_input(words)]))[0]

  if result[0] > result[1]:
    site = 'NotTheOnion'
  else:
    site = 'TheOnion'

  return site

açıklama

Bu kod, kelimeleri bir 'vektör' olarak temsil ederek kelimeler arasındaki ilişkileri analiz eden bir model çalıştırır. Sözcük yerleştirme hakkında daha fazla bilgiyi buradan edinebilirsiniz .

Bu manşetlerde eğitilmiş ancak test senaryoları hariç tutulmuştur .

Bu işlemler, biraz işlemden sonra otomatikleştirilir. Son işlenmiş kelime listesini bir dağıtım olarak .pkldağıttım, ancak kelime yerleştirmede olan şey, önce cümleyi analiz edip kelimeleri izole etmektir.

Şimdi kelimeleri sonra bir sonraki adım belirli kelimeler örn arasındaki farklılıkları ve benzerlikleri anlamaya muktedir olduğunu kingve queenkarşı dukeve duchess. Bu düğünler gerçek kelimeler arasında değil, .pkldosyada saklanan kelimeleri temsil eden sayılar arasında gerçekleşir . Makinenin anlamadığı kelimeler <UNK>, orada bir kelime olduğunu ancak anlamın tam olarak ne olduğunu bilmemizi sağlayan özel bir kelimeyle eşleştirilir .

Artık kelimeler anlaşılabildiğine göre, kelimeler dizisinin (başlık) analiz edilebilmesi gerekiyor. 'LSTM' bunu yapar, bir LTSM yok olan degrade etkisini önleyen bir tür 'RNN' hücresidir. Daha basit olarak, bir dizi kelimeyi alır ve aralarındaki ilişkileri bulmamıza izin verir.

Şimdi son katman, Densetemelde çıktının şöyle olduğu bir diziye benzediği anlamına gelir [probability_is_not_onion, probability_is_onion]. Hangisinin daha büyük olduğunu belirterek, verilen başlık için hangisinin en güvenli sonuç olduğunu seçebiliriz.


3

Python 3 + Keras, 41/50 =% 82

Gizli test vakalarında% 83 (166/200)

import json
import keras
import numpy
import re

from keras import backend as K

STRIP_PUNCTUATION = re.compile(r"[^a-z0-9 ]+")


class AttentionWeightedAverage(keras.engine.Layer):
    def __init__(self, return_attention=False, **kwargs):
        self.init = keras.initializers.get("uniform")
        self.supports_masking = True
        self.return_attention = return_attention
        super(AttentionWeightedAverage, self).__init__(**kwargs)

    def build(self, input_shape):
        self.input_spec = [keras.engine.InputSpec(ndim=3)]
        assert len(input_shape) == 3

        self.W = self.add_weight(shape=(input_shape[2], 1),
                                 name="{}_W".format(self.name),
                                 initializer=self.init)
        self.trainable_weights = [self.W]

        super(AttentionWeightedAverage, self).build(input_shape)

    def call(self, x, mask=None):
        logits = K.dot(x, self.W)
        x_shape = K.shape(x)
        logits = K.reshape(logits, (x_shape[0], x_shape[1]))

        ai = K.exp(logits - K.max(logits, axis=-1, keepdims=True))

        if mask is not None:
            mask = K.cast(mask, K.floatx())
            ai = ai * mask

        att_weights = ai / (K.sum(ai, axis=1, keepdims=True) + K.epsilon())
        weighted_input = x * K.expand_dims(att_weights)

        result = K.sum(weighted_input, axis=1)

        if self.return_attention:
            return [result, att_weights]

        return result

    def get_output_shape_for(self, input_shape):
        return self.compute_output_shape(input_shape)

    def compute_output_shape(self, input_shape):
        output_len = input_shape[2]

        if self.return_attention:
            return [(input_shape[0], output_len), (input_shape[0], input_shape[1])]

        return (input_shape[0], output_len)

    def compute_mask(self, input, input_mask=None):
        if isinstance(input_mask, list):
            return [None] * len(input_mask)
        else:
            return None


if __name__ == "__main__":
    model = keras.models.load_model("combined.h5", custom_objects={"AttentionWeightedAverage": AttentionWeightedAverage})
    with open("vocabulary.json", "r") as fh:
        vocab = json.load(fh)

    while True:
        try:
            headline = input()
        except EOFError:
            break

        tokens = STRIP_PUNCTUATION.sub("", headline.lower()).split()

        inp = numpy.zeros((1, 45))

        for i, token in enumerate(tokens):
            try:
                inp[0,i] = vocab[token]
            except KeyError:
                inp[0,i] = 1

        print(model.predict(inp)[0][0] > 0.3)

combined.h5ve buradan (çok büyük) ve buradanvocabulary.json alınabilir .

Yığılmış iki yönlü LSTM'ler ve dikkat mekanizmasından oluşan önceden eğitilmiş bir duygu analizi modeli DeepMoji'ye bağlı tam bağlantılı sınıflandırıcı. DeepMoji katmanlarını dondum ve son softmax katmanını çıkardım, sadece tamamen bağlı katmanları eğittim, sonra DeepMoji katmanlarını çözdüm ve finetuning için birlikte eğitdim. Dikkat mekanizması https://github.com/bfelbo/DeepMoji/blob/master/deepmoji/attlayer.py adresinden alınmıştır (özellikle kodlarını bir sınıf için bağımlılık olarak kullanmak istemedim, özellikle Python 2 ve bir modül olarak kullanmak için uygunsuz ...)

Bu, kendi daha büyük doğrulama setimde>% 90 elde edildiğini göz önünde bulundurarak Mego'nun test setinde şaşırtıcı derecede kötü performans gösteriyor. Bu yüzden henüz işim bitmedi.


Gizli test vakalarında% 83, doğru çalıştığımı varsayarsak
Mego

1

JavaScript ( Node.js ),% 98 (49/50)

Gizli test vakalarında% 96 (192/200)

const words = require('./words');
const bags = require('./bags');

let W = s => s.replace(/[^A-Za-z0-9 ]/g, '').toLowerCase().split(' ').filter(w => w.length > 3);

let M = b => {
    for (let i = 0; i < bags.length; i++) {
        let f = true;
        for (let j = 0; j < bags[i].length; j++) if (!b.includes(bags[i][j])) {
            f = false;
            break;
        }
        if (f) return true;
    }
    return false;
};

let O = s => {
    let b = [];
    W(s).forEach(w => {
        let p = words.indexOf(w);
        if (p >= 0) b.push(p);
    });
    return (b.length > 0 && M(b));
};

Bu, onları buraya veya "TiO" ya koyamayacağım iki büyük JSON dosyası gerektirir. Lütfen bunları aşağıdaki bağlantılardan indirin ve JS dosyasıyla aynı klasöre words.jsonve bags.jsonadlarıyla kaydedin . Ayrıca test senaryoları ve sonuç / yüzde yazdırma içeren bir JS dosyası için bir bağlantı vardır. Gizli test senaryolarınızı onionsve nonOnionsdeğişkenleri yerleştirebilirsiniz.

Tüm 3 dosyayı aynı dizine kaydettikten sonra çalıştırın node onion.js.

Oİşlev dönecektir trueo soğan ise ve falseeğer değilse. Giriş dizesinin soğan olup olmadığını tespit etmek için büyük bir kelime torbası listesi (sipariş vermeden) kullanır. Bir çeşit sabit kodlanmış, ancak çeşitli rastgele test vakalarında çok iyi çalışır.


Bu çözüm gizli test
senaryolarında

0

Arnauld'un çözümü üzerinde çalışmak

JavaScript (ES6), 41/50

Gizli test senaryolarında% 64 (128/200)

str.includes("Dad") || str.length ** .25 +
  str.split(' ').length ** 1.25 * 2 +
  str.split(/ly\b/).length ** 1.75 * 7
 > 76

JavaScript (ES6), 42/50

Gizli test senaryolarında% 62,5 (125/200) (geçersiz)

isOnion = str =>
  str.includes("Dad") || str.length ** .25 +
  str.split(' ').length ** 1.25 * 2 +
  str.split(' ').filter(w => w.length > 3 && w.split(/ly/).length > 1).length * 23.54 +
 /\d/.test(str) * 8
 > 76

Uzunluk + kelime sayısı + "ly" kavramı oldukça iyi çalışıyor, "Baba" kelimesini kontrol ederek birkaç nokta daha sıkabildim (gerçek makaleler başlıktaki üçüncü kişideki insanların babaları hakkında ne zaman konuşuyor?) Ve "ly" arama buluşsal yöntemini değiştirerek ve başlıktaki sayıların varlığını kontrol ederek ek bir nokta (testin dışındaki genel durumda daha az geçerli olabilir, bu yüzden her iki çözümü de bıraktım)


Baba bölümünü bilmiyorum ... bana test
Don

Ve evet, babalardan bahseden Soğan Değil makalelerini bol miktarda bulabilirim
Don Bin

Muhtemelen sezgisel bir parçası olarak yapmanın daha iyi bir yolu var ve eğer baba içeriyorsa sadece zor bir "kazanma" değil, ama test veritabanının dışında bile belirli bir "Baba" dan bahsettiğimi hayal ediyorum
TiKevin83

İlk çözümünüz gizli test senaryolarında% 64 puan aldı, bu yüzden geçerli. İkinci çözümünüz gizli test senaryolarında% 62.5 puan aldı, bu yüzden geçerli değil.
Mego

@Mego Ne yakın marj ...
user202729
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.