タマネギ、またはタマネギではない?


11

The Onion(警告:多くの記事はNSFWです)は、伝統的なニュースメディアをパロディ化する風刺的なニュース組織です。2014年、The OnionはClickBole(警告:NSFWも頻繁に)を立ち上げました。これは、BuzzFeedのような「clickbait」サイトをパロディ化する風刺的なニュースWebサイトです。Poeの法則のおかげで、人々が風刺を意図していることを知らずに、The OnionまたはClickHoleの記事の見出しを読んで、それらが真実であると信じることはかなり一般的です。その逆は、ばかげて聞こえる本当のニュース記事でも起こります。

この混乱は自然にゲームに役立ちます-ニュースの見出しを考えれば、それが風刺であるかどうかを推測してみてください。この課題は、まさにそれをプログラムで行うことです。

ニュースの見出し(印刷可能なASCII文字とスペースのみで構成される文字列)が与えられた1場合、見出しが風刺であるか0、そうでない場合に出力します。スコアは、正しい出力の数を見出しの総数で割ったものになります。

通常どおり、標準の抜け穴(特にテストケースの最適化)は許可されていません。これを実施するために、200の隠されたテストケース(The Onionから100、Not The Onionから100)のセットでプログラムを実行します。ソリューションが有効であるためには、パブリックテストケースのスコアより20パーセントポイント以下しかスコアを取得してはなりません。

テストケース

このチャレンジのテストケースを考え出すために、The Onion subreddit(The OnionとClickHoleなどの子サイトからの記事が掲載されている)から25件の見出しを選び、Not The Onion subreddit(実際のニュース記事から)風刺のような音が掲載されています)。見出しに加えた唯一の変更は、「空想的な」引用を通常のASCII引用に置き換え、大文字を標準化することでした。他のすべては元の記事の見出しから変更されていません。各見出しは独自の行にあります。

オニオンの見出し

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

オニオンの見出しではない

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 headlinesバイトカウントはタイブレーカーですか?
Skidsdev

9
私は少し混乱しています。どのような解決策を期待していますか?すべてのソリューションは、「テストケースに最適化」する必要があります。英語を理解でき、ユーモアのセンスを備えたAIを書くことを禁止します。たとえば、アーナウルドのソリューションは/ly\b/、選択した25のオニオンヘッドラインに副詞が多いためにどちらが機能するかを検出しますが、別のテストバッテリーで簡単にトリップできることはわかっています。そして、彼の係数が彼のスコアを最適化するために選択されていないと言うのは誰ですか?(なぜ彼はそれらを最適化しないのですか?)
リン

10
このテスト用バッテリーは少し珍しいようです。写真で犬を検出できる分類器を求めるようなものですが、ポジティブなテストケースを犬の写真として、ネガティブなテストケースをBuzzfeedの記事「あなたが誓うオブジェクトの写真25枚は犬ですが、いや、ターンOut They Are n't!(#11 Will Blow Your Mind!)」これは、難しい問題をより難しくします。
ソフィア・レヒナー

4
挑戦が難しいだけでなく、違いは(私にとって)非自明でもあります。私がそれを解決できない場合、もちろん私のプログラムはそれを解決できません(つまり、テストケースをハードコードしないと確信している間)
-user202729

4
まあbrain.js、この問題のサンプルと提供されたリンクからの各タイプの他のサンプルで、LSTM を使用して人工神経回路網を+36時間費やしましたが、トレーニングセットにない新しいタイトルでは結果が十分ではありませんでした。完了です:P
Night2

回答:


7

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

非表示のテストケースで63.5%(127/200)

タイトルの長さ、スペースの数、および-ly接尾辞の使用に基づく単純な発見的方法。

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

オンラインでお試しください!


これは、それがどれほど簡単かというとてつもなく効果的です。
ドン・サウザンド・

このソリューションは、非表示のテストケースで63.5%を獲得したため、有効です。
メゴ

サンドボックスの冒頭で可能なほど単純ではありませんでした(100%、標準化される前に大文字の違いを利用)が、これは本当に単純です。
ザカリー

@Mego好奇心から、このNSFWバージョンは隠されたテストケースのスコアを改善しますか?:)
アーナウド

@Arnauldそのバージョンで66%
Mego

6

Python 3、84%

非表示のテストケースではテストされていません。

これは、さまざまな見出しでトレーニングされたKeras LSTM RNNを使用します。それを実行するには、Kerasに次のものと、GitHubで利用可能にしたモデル:repo linkが必要です。モデルが必要に.h5なり、単語/ベクトルマッピングはにあり.pklます。最新の

依存関係は次のとおりです。

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

設定は次のとおりです。

max_headline_length = 70
word_count = 20740

モデルは次のとおりです。

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

次に、モデルと単語の埋め込みをロードします。

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

そして、文字列が「NotTheOnion」または「TheOnion」からのものかどうかをテストするコードは、文字列をそれぞれの単語の埋め込みに変換するクイックヘルパー関数を作成しました。

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として配布しまし.pklたが、単語の埋め込みで何が起こるかは、最初に文を分析して単語を分離することです。

単語を取得したら、次のステップは、特定の単語、たとえばkingand queendukeand の違いと類似性を理解できるようにすることduchessです。これらの埋め込みは、実際の単語間ではなく、.pklファイルに保存されている単語を表す数字の間で行われます。マシンが理解<UNK>できない単語は特別な単語にマッピングされます。これにより、単語が存在するが、その意味が正確にはわからないことがわかります。

単語を理解できるようになったので、単語のシーケンス(見出し)を分析できる必要があります。これは「LSTM」が行うことであり、LTSMは消失勾配効果を回避する「RNN」セルの一種です。もっと簡単に言うと、一連の単語を取り込んで、単語間の関係を見つけることができます。

最後のレイヤーはDense、基本的には配列のようなものを意味し、出力は次のようになります[probability_is_not_onion, probability_is_onion]。どちらが大きいかを見つけることで、特定の見出しに対して最も信頼できる結果を選択できます。


3

Python 3 + Keras、41/50 = 82%

非表示のテストケースで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.h5以下とvocabulary.jsonから取得することができ、ここで(非常に大きい)、ここで

事前学習済みの感情分析モデルDeepMojiに接続された完全に接続された分類器。これは、積み重ねられた双方向LSTMとアテンションメカニズムで構成されています。DeepMojiレイヤーをフリーズし、最後のsoftmaxレイヤーを取り出し、完全に接続されたレイヤーのみをトレーニングし、DeepMojiレイヤーをフリーズ解除し、微調整のためにそれらを一緒にトレーニングしました。注意のメカニズムはhttps://github.com/bfelbo/DeepMoji/blob/master/deepmoji/attlayer.pyから取得されます(特に、すべてのコードを1つのクラスの依存関係として使用する必要はありませんでした。 Python 2であり、モジュールとして使用するにはかなり扱いにくい...)

これはMegoのテストセットでは驚くほどパフォーマンスが劣りますが、私自身のより大きな検証セットでは90%を超えることを考慮しています。だから私はまだこれで終わっていません。


正しく実行したと仮定すると、隠しテストケースの83%
Mego

1

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

非表示のテストケースで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));
};

これには2つの大きなJSONファイルが必要ですが、ここや「TiO」には配置できません。次のリンクからそれらをダウンロードし、JSファイルと同じフォルダにwords.jsonとのbags.json名前で保存してください。テストケースと結果/パーセントの印刷を含むJSファイルへのリンクもあります。隠しテストケースをonionsnonOnions変数に入れることができます。

3つのファイルすべてを同じディレクトリに保存したら、を実行しnode onion.jsます。

Oこの関数は戻りますtrue、それはタマネギの場合とfalseそうでない場合。入力文字列がタマネギであるかどうかを検出するために、ワードバッグの大きなリスト(順序なし)を使用します。一種のハードコーディングですが、さまざまなランダムテストケースで非常にうまく機能します。


このソリューションは、隠されたテストケースで96%を取得します
Mego

0

Arnauldのソリューションに取り組む

JavaScript(ES6)、41/50

非表示のテストケースで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

非表示のテストケースで62.5%(125/200)(無効)

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

長さ+単語数+ "ly"の概念は非常にうまく機能します。単語 "Dad"をチェックすることで、さらにいくつかのポイントを絞り出すことができました(実際の記事では、タイトルの3番目の人の父親について話しますか?) 「ly」検索ヒューリスティックを変更し、タイトル内の数字の存在を確認することによる追加ポイント(テスト外の一般的なケースでは有効性が低い可能性があるため、両方のソリューションを残しました)


Iお父さんの一部について知らない...少し私にはテストケースを最適化するように思える...
ドン・サウザンド・

そして、はい、私は父親に言及されないタマネギの記事をたくさん見つけることができます
ドン・サウザンド・

パパが含まれている場合、単なる「
勝者

最初のソリューションは非表示のテストケースで64%を獲得したため、有効です。2番目のソリューションは、非表示のテストケースで62.5%を獲得したため、有効ではありません。
Mego

@Megoなんて近いマージン
...-user202729
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.