Hành tây, hay không phải là hành tây?


11

Onion (cảnh báo: nhiều bài báo là NSFW) là một tổ chức tin tức châm biếm, nhại lại các phương tiện truyền thông tin tức truyền thống. Vào năm 2014, The Onion đã ra mắt ClickHole (cảnh báo: cũng thường xuyên là NSFW), một trang web tin tức châm biếm nhại lại các trang web "clickbait" như BuzzFeed. Nhờ Luật của Poe , mọi người thường đọc các tiêu đề của các bài báo từ The Onion hoặc ClickHole và tin rằng chúng là sự thật, không biết rằng chúng có ý định châm biếm. Cuộc trò chuyện cũng xảy ra với những câu chuyện tin tức nghe có vẻ vô lý - mọi người thường nghĩ rằng họ là châm biếm khi họ không.

Sự nhầm lẫn này tự nhiên cho vay vào một trò chơi - đưa ra một tiêu đề tin tức, cố gắng đoán xem nó có phải là châm biếm hay không. Thử thách này là về việc thực hiện chính xác điều đó với một chương trình.

Đưa ra một tiêu đề tin tức (một chuỗi chỉ bao gồm các ký tự và khoảng trắng ASCII có thể in được), xuất ra 1nếu tiêu đề là châm biếm hoặc 0nếu không. Điểm của bạn sẽ là số lượng đầu ra chính xác chia cho tổng số tiêu đề.

Như thường lệ, các lỗ hổng tiêu chuẩn (đặc biệt là tối ưu hóa cho các trường hợp thử nghiệm ) không được phép. Để thực thi điều này, tôi sẽ chạy các chương trình của bạn trên một bộ 200 trường hợp thử nghiệm ẩn (100 từ Hành tây, 100 từ Không phải Hành tây). Giải pháp của bạn phải đạt ít hơn 20 điểm phần trăm so với điểm của bạn trong các trường hợp kiểm tra công khai để có hiệu lực.

Các trường hợp thử nghiệm

Để đưa ra các trường hợp thử nghiệm cho thử thách này, tôi đã chọn 25 tiêu đề từ subreddit The Onion (nơi các bài viết từ The Onion và các trang web con của nó, như ClickHole, được đăng) và 25 tiêu đề từ subreddit Not The Onion (nơi các bài báo tin tức thực sự âm thanh như châm biếm được đăng). Những thay đổi duy nhất tôi đã thực hiện đối với các tiêu đề là thay thế các trích dẫn "ưa thích" bằng các trích dẫn ASCII thông thường và viết hoa chuẩn hóa - mọi thứ khác không thay đổi so với tiêu đề của bài viết gốc. Mỗi tiêu đề là trên dòng riêng của nó.

Các tiêu đề hành tây

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

Không phải tiêu đề Hành tây

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 headlinesLà bytecount một breaker tie?
Skidsdev

9
Tôi có đôi chút hoang mang. Bạn mong đợi loại giải pháp nào? Mọi giải pháp sẽ phải "tối ưu hóa cho các trường hợp thử nghiệm", bằng cách viết một AI có thể hiểu tiếng Anh và có ý nghĩa hài hước. Ví dụ: giải pháp của Arnauld chỉ phát hiện /ly\b/hoạt động nào vì 25 tiêu đề Hành tây bạn chọn có nhiều trạng từ hơn, nhưng với tất cả những gì tôi biết, bạn có thể dễ dàng sử dụng pin thử nghiệm khác. Và ai sẽ nói hệ số của anh ta không được chọn để tối ưu hóa điểm số của anh ta? (Tại sao anh ta không tối ưu hóa chúng?)
Lynn

10
Pin thử nghiệm này có vẻ hơi bất thường. Giống như yêu cầu một bộ phân loại có thể phát hiện ra chó trong một bức ảnh, nhưng lấy các trường hợp thử nghiệm dương tính của bạn làm ảnh của chó và các trường hợp thử nghiệm âm tính của bạn từ một bài báo trên Buzzfeed có tiêu đề "25 Ảnh về các đối tượng bạn sẽ thề là chó, nhưng không Hết họ không! (# 11 sẽ thổi bay tâm trí của bạn!) "Nó làm cho một vấn đề đủ khó trở nên khó khăn hơn.
Sophia Lechner

4
Thử thách không chỉ khó khăn mà còn không rõ ràng (đối với tôi) sự khác biệt. Nếu tôi không thể giải quyết nó, tất nhiên chương trình của tôi không thể giải quyết được (nghĩa là, trong khi thuyết phục tôi rằng nó không phải là mã cứng cho các trường hợp thử nghiệm)
user202729

4
Tôi đã dành hơn 36 giờ để đào tạo một mạng lưới thần kinh nhân tạo bằng cách sử dụng brain.jsvà LSTM, với các mẫu trong vấn đề này và 100 mẫu khác của mỗi loại từ các liên kết được cung cấp, nhưng kết quả không đủ với các tiêu đề mới không có trong các bộ huấn luyện . Tôi đã hoàn thành: P
Night2

Câu trả lời:


7

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

63,5% (127/200) đối với các trường hợp thử nghiệm ẩn

Một heuristic đơn giản dựa trên độ dài của tiêu đề, số lượng khoảng trắng và cách sử dụng -lyhậu tố.

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

Hãy thử trực tuyến!


Điều này là vô cùng hiệu quả cho cách đơn giản.
Don Ngàn

Giải pháp này đạt 63,5% trong các trường hợp kiểm tra ẩn, vì vậy nó là hợp lệ.
Mego

Không đơn giản như có thể khi bắt đầu hộp cát (100%, sử dụng chênh lệch viết hoa trước khi được chuẩn hóa) nhưng điều này thực sự đơn giản.
Zacharý

@Mego Vì tò mò, phiên bản NSFW này có cải thiện điểm số trong các trường hợp thử nghiệm ẩn không? :)
Arnauld

@Arnauld 66% với phiên bản đó
Mego

6

Trăn 3, 84%

Chưa được kiểm tra trên các trường hợp thử nghiệm ẩn.

Điều này sử dụng Keras LSTM RNN được đào tạo trên các tiêu đề khác nhau. Để chạy nó, bạn cần Keras như sau và mô hình mà tôi đã có sẵn trên GitHub: liên kết repo . Bạn sẽ cần mô hình .h5và ánh xạ từ / vector nằm trong .pkl. Mới nhất

Các phụ thuộc là:

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

Các cài đặt là:

max_headline_length = 70
word_count = 20740

Mô hình là:

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

Bây giờ để tải mô hình và các từ nhúng:

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

Và mã để kiểm tra xem một chuỗi là từ 'NotTheOnion' hay 'TheOnion' Tôi đã viết một hàm trợ giúp nhanh để chuyển đổi chuỗi thành các từ nhúng tương ứng:

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

Giải trình

Mã này chạy một mô hình phân tích các mối quan hệ giữa các từ bằng cách biểu diễn các từ dưới dạng "vectơ". Bạn có thể tìm hiểu thêm về nhúng từ ở đây .

Điều này được đào tạo trên các tiêu đề nhưng các trường hợp thử nghiệm được loại trừ .

Quá trình này được tự động sau một chút xử lý. Tôi đã phân phối danh sách từ được xử lý cuối cùng dưới dạng .pklnhưng những gì xảy ra trong việc nhúng từ trước tiên là chúng tôi phân tích câu và cô lập các từ.

Sau khi chúng ta có các từ, bước tiếp theo là có thể hiểu được sự khác biệt và tương đồng giữa các từ nhất định, ví dụ kingqueenso với dukeduchess. Các nhúng này không xảy ra giữa các từ thực tế mà giữa các số đại diện cho các từ được lưu trữ trong .pkltệp. Những từ mà máy không hiểu được ánh xạ tới một từ đặc biệt <UNK>cho phép chúng ta hiểu rằng có một từ ở đó nhưng nó không được biết chính xác nghĩa của nó là gì.

Bây giờ các từ có thể được hiểu, trình tự các từ (tiêu đề) cần phải có thể được phân tích. Đây là những gì 'LSTM' làm, LTSM là một loại tế bào 'RNN' để tránh hiệu ứng chuyển màu biến mất. Đơn giản hơn, nó cần một chuỗi các từ và nó cho phép chúng ta tìm mối quan hệ giữa chúng.

Bây giờ, lớp cuối cùng Densevề cơ bản có nghĩa là nó giống như một mảng có nghĩa là đầu ra giống như : [probability_is_not_onion, probability_is_onion]. Bằng cách tìm ra cái nào lớn hơn, chúng ta có thể chọn cái nào là kết quả tự tin nhất cho tiêu đề đã cho.


3

Python 3 + Kera, 41/50 = 82%

83% (166/200) về các trường hợp thử nghiệm ẩn

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.h5vocabulary.jsoncó thể được lấy từ đây (rất lớn)ở đây .

Trình phân loại được kết nối đầy đủ được kết nối với mô hình phân tích tình cảm được đào tạo trước DeepMoji, bao gồm các LSTM hai chiều xếp chồng lên nhau và một cơ chế chú ý. Tôi đóng băng các lớp DeepMoji và lấy ra lớp softmax cuối cùng, chỉ đào tạo các lớp được kết nối đầy đủ, sau đó tháo các lớp DeepMoji và huấn luyện chúng lại với nhau để hoàn thiện. Cơ chế chú ý được lấy từ https://github.com/bfelbo/DeepMoji/blob/master/deepmoji/attlayer.py (Tôi không muốn phải sử dụng tất cả mã của họ làm phụ thuộc cho một lớp, đặc biệt là vì nó Python 2 và khá khó sử dụng làm mô-đun ...)

Điều này thực hiện kém đáng ngạc nhiên trên bộ thử nghiệm của Mego, vì xét rằng trên bộ xác nhận lớn hơn của riêng tôi, nó đạt> 90%. Vì vậy, tôi chưa được thực hiện với điều này.


83% cho các trường hợp kiểm tra ẩn, giả sử tôi đã chạy đúng
Mego

1

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

96% (192/200) về các trường hợp kiểm tra ẩn

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));
};

Điều này đòi hỏi hai tệp JSON lớn mà tôi không thể đặt chúng ở đây hoặc trên "TiO". Vui lòng tải chúng từ các liên kết sau và lưu chúng với tên words.jsonbags.jsontên, trong cùng thư mục với tệp JS. Ngoài ra còn có một liên kết cho một tệp JS với các trường hợp thử nghiệm và in kết quả / phần trăm. Bạn có thể đặt các trường hợp kiểm tra ẩn của bạn trong onionsnonOnionscác biến.

Sau khi lưu cả 3 tệp trong cùng một thư mục, hãy chạy node onion.js.

Các Ochức năng sẽ trở lại truenếu nó là hành tây và falsenếu nó không. Sử dụng một danh sách lớn các túi từ (không có thứ tự) để phát hiện nếu chuỗi đầu vào là củ hành. Loại mã hóa cứng, nhưng hoạt động rất tốt trên nhiều trường hợp thử nghiệm ngẫu nhiên.


Giải pháp này nhận được 96% cho các trường hợp thử nghiệm ẩn
Mego

0

Làm việc với giải pháp của Arnauld

JavaScript (ES6), 41/50

64% (128/200) về các trường hợp kiểm tra ẩn

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

62,5% (125/200) đối với các trường hợp kiểm tra ẩn (không hợp lệ)

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

Khái niệm độ dài + số từ + "ly" hoạt động khá tốt, tôi có thể rút ra một vài điểm nữa bằng cách kiểm tra từ "Bố" (khi nào các bài báo thực sự nói về cha của người thứ ba trong tiêu đề?) Và một điểm bổ sung bằng cách thay đổi heuristic tìm kiếm "ly" và kiểm tra sự hiện diện của các số trong tiêu đề (có thể ít hợp lệ hơn trong trường hợp chung bên ngoài thử nghiệm, vì vậy tôi đã bỏ cả hai giải pháp)


Tôi không biết về phần của cha ... có vẻ hơi giống như tối ưu hóa trường hợp thử nghiệm với tôi ...
Don Ngàn

Và vâng, tôi có thể tìm thấy rất nhiều bài báo Không phải hành tây đề cập đến các ông bố
Don Ngàn

Có lẽ có một cách tốt hơn để làm điều đó như là một phần của heuristic và không chỉ là một "chiến thắng" khó khăn nếu nó chứa cha, nhưng tôi tưởng tượng ngay cả bên ngoài cơ sở dữ liệu thử nghiệm nói một cách trừu tượng về một "Bố" cụ thể là phổ biến hơn trên The Onion
TiKevin83

Giải pháp đầu tiên của bạn đạt 64% trong các trường hợp kiểm tra ẩn, vì vậy nó là hợp lệ. Giải pháp thứ hai của bạn đạt 62,5% trong các trường hợp kiểm tra ẩn, vì vậy nó không hợp lệ.
Mego

@Mego Thật là một biên độ gần ...
user202729
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.