Hãy đánh giá một số cuốn sách bằng bìa của họ


47

Mọi người đều biết rằng nội dung làm cho câu hỏi. Nhưng một tiêu đề tốt cũng giúp, và đó là điều đầu tiên chúng ta thấy. Đã đến lúc biến ấn tượng đầu tiên đó thành một chương trình và tìm ra loại tiêu đề nào nhận được nhiều sự ủng hộ hơn.

Bạn được thử thách viết một chương trình hoặc chức năng lấy tiêu đề của câu hỏi PPCG làm đầu vào và trả về dự đoán về điểm số của nó.

Chẳng hạn, bạn có thể nhận Counting Grains of Ricelàm đầu vào và bạn sẽ cố gắng trả lại thứ gì đó gần với điểm số, 59trong trường hợp này. Đoán không nguyên là tốt, nhưng đoán ở hoặc dưới -20thì không.

Đây là dữ liệu, để thử nghiệm và cho điểm:

http://data.stackexchange.com/codegolf/query/244871/names-and-upvotes

Ghi điểm: Chương trình của bạn sẽ được chạy trên mọi câu hỏi trong lịch sử (PPCG) của trang web này, không tính các câu hỏi đóng. Hàm ln(score + 20)này sau đó sẽ được áp dụng cho từng điểm và cho từng lần đoán. Lỗi trung bình-bình phương-lỗi giữa hai bộ giá trị kết quả là điểm của bạn. Thấp hơn là tốt hơn.

Chẳng hạn, một chương trình đoán 0 mỗi lần sẽ đạt 0,577, trong khi một chương trình đoán 11 mỗi lần sẽ đạt 0,336.

Vui lòng tính điểm của bạn và đưa nó vào tiêu đề câu trả lời của bạn. Ngoài ra, vui lòng bao gồm dự đoán của chương trình của bạn về số lượng câu hỏi sẽ nhận được.

Những hạn chế:

  • Để ngăn chặn quá trình mã hóa cứng, không quá 1000 ký tự.

  • Phải chạy trên toàn bộ dữ liệu được đặt ở trên dưới một phút trên một máy hợp lý.

  • Lỗ hổng tiêu chuẩn được đóng lại.


Đây là một thử nghiệm được viết bằng Python, để bạn sử dụng và / hoặc để xóa đi sự mơ hồ:

import sys
import math
import csv

scores_dict = {}

with open(sys.argv[1], 'r') as csv_file:
    score_reader = csv.reader(csv_file)
    for score, title in score_reader:
        if score == 'Score':
            continue
        scores_dict[title] = int(score)

def rate_guesses(guesser):
    def transform(score):
        return math.log(score + 20) if score > -20 else 0
    off_by_total = 0
    lines_count = 0
    for title in scores_dict:
        guessed_score = guesser(title)
        real_score = scores_dict[title]
        off_by_total += (transform(real_score) - transform(guessed_score)) ** 2
    return (off_by_total/len(scores_dict)) ** .5

def constant11(title):
    return 11

print(rate_guesses(constant11))

19
Ý tưởng hay, nhưng thật xấu hổ khi bộ dữ liệu không ổn định, do đó điểm số sẽ trở nên không hợp lệ sau một thời gian. Ngoài ra còn có một khả năng bỏ phiếu chiến lược nhỏ: bất kỳ ai trả lời câu hỏi này và kiếm được huy hiệu vox-populi trong cùng một tuần nên được xem với sự nghi ngờ! ;-)
Cấp sông St

1
Tiêu đề sẽ bao gồm hoặc loại trừ những thứ như [closed][on hold], nếu áp dụng?
es1024

4
@steveverrill Chà, sự thất bại đó là khi thời gian trôi qua, chúng ta sẽ có thể xem liệu các chương trình có làm tốt trên các bài đăng trong tương lai cũng như các bài trước không.
isaacg

6
Thật khó để đánh bại mã hóa cứng. Mỗi câu hỏi được bình chọn hàng đầu được mã hóa cứng có thể giảm tới 0,4 điểm. Và dường như cũng không có nhiều mô hình chung, haha. Tôi dự đoán rằng các câu trả lời sẽ cạnh tranh về cách làm thế nào để phù hợp với nhiều kết quả được mã hóa cứng trong 1000 byte.
ngay

5
Bạn không nên sử dụng toàn bộ câu hỏi làm bộ kiểm tra của mình. Bạn nên chọn trước một số nhất định (10% -20%) một cách ngẫu nhiên và xác định chúng là tập kiểm tra của bạn (nhưng không cho ai biết đó là gì). Việc tạo ra một thuật toán dự đoán lịch sử trong quá khứ dễ dàng hơn nhiều so với thuật toán có giá trị dự đoán trong tương lai (nghĩa là thuật toán hoạt động tốt trên bất kỳ tập hợp con cụ thể nào). (Sẽ tốt hơn nữa nếu loại bỏ 10% đó khỏi những gì chúng ta có thể thấy, nhưng điều đó sẽ không thực sự hoạt động tốt.)
Joe

Câu trả lời:


9

Python 2, 991 ký tự, điểm 0,221854834221, dự đoán 11

import base64
e={}
d=base64.decodestring('vgAcRAEVDAIsqgQYalYaggcjQKwVXAoZWAsYQg0Ckg4VlWEX9hEDRhMe0hckCBkeuhsW3CAWQiEm\nSiMZMiwgTDAZZjIcSLMZfDQDnjwCe2AVaEQCYWEBIEgnDEoXzk0e3lQb5FYVKlkVZlwB+F0XwmI/\nGmRcuGUXWmYdVGkbzmwafG8eaHMdInkggHonRn5sKoMXgIkpbowVOI4cNJAubpQdYpcydJgVypkA\nZpweMp8ZsqEcRKMghKQYkKVPPXEWMqkWHKwbjrEdzLIBNLMf1LQivrYC99UV9rxNRsABNMEiPzob\npc0ActAhn3gcrNUZYNcWYNov/t8VgOEXAuMYqOUWsqUiCPIefPWNbvtKevwWvP0Cl9UsjQMdWwQb\nfQdpJQgWYwkCZRLBjxMWWdkqHRkWNxwB6x8p2SEZyyICSyYcgysaOS0CUy8hezAaGeEVpTRQ3zUz\nZzkZRzohizwwST4c8UAdF0OqG9AXIuEYYRN6208nU1AktVEVJ1IVWeMkIVQXdY4D2VYYD/cYb1om\nG1xA0zoY3uUaRWAhWpBSHWUXQTxGe+cad20CO3AZX3EBw3IiMXcef3gecXsVGXwhw30VbX4W24BD\n6qyQ45YaYYgZ4YobbYwauY4bMY82HZEdO5YmQ5cV35sVxaMbY6gYNas576ws+bADO7QpN7hdLJ8B\n4Eoks8EYX8VU68cYWfcar82QOdAaxdEfQ9UiW/kXL9k2ddwCW90m694enqUCkeEBE+IYWvsfA1FC\nJ+spMVIjhe4WEP0fAfYax/c3MfgbgfkqP/0DLf4V\n')
for i in range(0,600,3):
 e[ord(d[i])*256+ord(d[i+1])]=ord(d[i+2])*2-8
def p(t):
 return e.get(hash(t)%256**2,11)

Giải trình:

Đây là mã hóa không biết xấu hổ, nhưng cố gắng làm điều đó một cách hiệu quả.

Sơ chế:

Trong một mã riêng, tôi đã băm từng tiêu đề thành một giá trị trong khoảng từ 0 đến 256 ^ 2-1. Hãy gọi những thùng rác giá trị này. Đối với mỗi thùng, tôi tính điểm trung bình. (Trung bình là cần thiết vì đối với một phần nhỏ của các thùng, có sự va chạm - hơn 1 tiêu đề băm vào cùng một thùng. Nhưng đối với đại đa số mỗi tiêu đề ánh xạ vào một thùng của chính nó).

Ý tưởng đằng sau mã 2 byte cho mỗi tiêu đề là 1 byte là không đủ - chúng tôi nhận được quá nhiều xung đột, vì vậy chúng tôi thực sự không biết điểm nào sẽ được gán cho mỗi thùng 1 byte. Nhưng với các thùng 2 byte, hầu như không có xung đột và chúng tôi thực sự có được đại diện 2 byte cho mỗi tiêu đề.

Sau đó xếp hạng các thùng - tính toán mức tăng điểm nếu chúng ta gán cho thùng này giá trị tính toán của nó, thay vì chỉ đoán 11. Lấy các thùng N hàng đầu và mã hóa chúng thành một chuỗi (là d trong mã thực tế).

Mã hóa: khóa của thùng được mã hóa là 2 byte. giá trị được mã hóa bằng 1 byte. Tôi đã tìm thấy các giá trị trong khoảng từ -8 đến 300 + một cái gì đó, vì vậy phải ép một chút để có được nó thành 1 byte: x -> (x + 8) / 2.

Mã thực tế:

đọc d dưới dạng bộ ba byte, giải mã mã hóa được giải thích ở trên. Khi một tiêu đề được đưa ra, hãy tính băm của nó (modulo 256 ^ 2) và nếu khóa đó được tìm thấy trong dict, hãy trả về giá trị mà nó ánh xạ tới. Nếu không, trả lại 11.


3
Một gợi ý: Điểm trung bình không phải là tốt. Nhìn vào chức năng chấm điểm thử thách, nó phi tuyến tính.
Ded repeatator

1
@Ded repeatator Cảm ơn, tôi nhận ra rằng sau khi tôi đã hoàn thành. Vấn đề là, đối với 99% số thùng, không có va chạm, vì vậy trung bình thực sự chỉ là điểm số của tiêu đề duy nhất ánh xạ tới thùng đó.
Ofri Raviv

16

Javascript ES6

Điểm: 0,245663
Độ dài: 1000 byte
Dự đoán: 5

(Tôi đoán câu hỏi là do một đợt tuyết lở bất ngờ .: P)

Giảm thiểu

E="ABCDEFGHIJKLMNOPQRSTUVWXYZ";E=E+E.toLowerCase()+"0123456789!@#$%;*()";P="RCRHIFMGPGIDQKHMJLLRMLFJGKHEqHPOgJNKGPCHPJNUPOSGJQKKKMELMIJHLKIKNcKDOfSJLFHDILGKIOUKLMLLKMKIHGHJGIIJDGJKIHIIFIGMTIHFJMIKDJGQJKGMKJHPRJPLMGIOPIIIIPBYFMGLEIKIMMRUKFLFGJFKFTHPFODEQTGTHKIJDHNJGDGiHKNYLHHDLJHGILOEViKNEKGQZfHJMIISIJFRHKLJMLPIFJILKKKJKKJESHNLLIKIGKGJJJHKJRGULLSLRONJNEeLKIQGGPQIHPLEIHHIDXjQHNBKOGWWIENRbYoHINHNMKTNKHTGMIPXFJLLMLIHPPLDJJKFUMIQMOKJLJJKIJKNLHRILJIAIbJEZOGIELGHGLOINDPJMJeJWRIIJHSOZDOsOFRRIOIOTIJSGGJKFUIDOINGOcLQEJFEITLMNIIGIGIMG7LPSNLKVOKIFGHJITGOFUJIIRN";K={};"99r1501vz076mip077myv0733it280exx081gt9118i1g279dyx102uho203ejd07433z087uje097kdg1567ft2088rk275dmu1203ez106lih1763ei126f6q101aax084owh088aid161i9y179gvn236ptn3338vf132i55080fke101l4z3789ai281ulm081blm124euz074o5m07513z14117l095qdn092gl30757n5153".replace(/(...)(...)/g,(_,a,b)=>K[a]=1*b);D=40655;N=479;H=(s,T)=>(h=7,[...s].map(c=>h=~~(h*T+c.charCodeAt(0))),h);S=s=>(y=H(s,31),K[((y%D+D)%D).toString(36)]||E.indexOf(P[(H(s,48)%N+N)%N]));

Mở rộng

E = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
E = E + E.toLowerCase() + "0123456789!@#$%;*()";
K = {};
P = "RCRHIFMGPGIDQKHMJLLRMLFJGKHEqHPOgJNKGPCHPJNUPOSGJQKKKMELMIJHLKIKNcKDOfSJL" +
    "FHDILGKIOUKLMLLKMKIHGHJGIIJDGJKIHIIFIGMTIHFJMIKDJGQJKGMKJHPRJPLMGIOPIIIIP" +
    "BYFMGLEIKIMMRUKFLFGJFKFTHPFODEQTGTHKIJDHNJGDGiHKNYLHHDLJHGILOEViKNEKGQZfH" +
    "JMIISIJFRHKLJMLPIFJILKKKJKKJESHNLLIKIGKGJJJHKJRGULLSLRONJNEeLKIQGGPQIHPLE" +
    "IHHIDXjQHNBKOGWWIENRbYoHINHNMKTNKHTGMIPXFJLLMLIHPPLDJJKFUMIQMOKJLJJKIJKNL" +
    "HRILJIAIbJEZOGIELGHGLOINDPJMJeJWRIIJHSOZDOsOFRRIOIOTIJSGGJKFUIDOINGOcLQEJ" +
    "FEITLMNIIGIGIMG7LPSNLKVOKIFGHJITGOFUJIIRN";

   ("99r1501vz076mip077myv0733it280exx081gt9118i1g279dyx102uho203ejd07433z087u" +
    "je097kdg1567ft2088rk275dmu1203ez106lih1763ei126f6q101aax084owh088aid161i9" +
    "y179gvn236ptn3338vf132i55080fke101l4z3789ai281ulm081blm124euz074o5m07513z" +
    "14117l095qdn092gl30757n5153").
        replace( /(...)(...)/g, (_,a,b) => K[a] = 1*b );

D = 40655;
N = 479;
H = (s,T) => (
    h = 7,
    [...s].map( c => h = ~~(h*T + c.charCodeAt(0)) ),
    h
);

S = s => (
    y = H( s, 31 ),
    K[((y%D + D)%D).toString( 36 )] || E.indexOf( P[(H( s, 48 )%N + N)%N] )
);

Hàm Schấp nhận một chuỗi (tiêu đề) và trả về điểm số của nó.

Ghi chú về hành vi:

  • 70 danh hiệu phiếu bầu được xử lý riêng từ> 70 danh hiệu phiếu bầu
  • 70 tiêu đề phiếu bầu được sắp xếp vào các thùng bằng thuật toán tối ưu hóa tiềm năng theo dõi từ khóa tổng thể rất tinh vi mà không giống với hàm băm chuỗi
  • sau một chút tính toán vui vẻ, hóa ra dự đoán tối ưu cho mỗi thùng chỉ đơn giản là trung bình hình học của (phiếu + 20) cho tất cả các tiêu đề trong thùng, trừ 20
  • dự đoán tối ưu cho tất cả 479 thùng sau đó được mã hóa thành chuỗi ký tự cơ sở 479 ký tự
  • đối với> 70 danh hiệu phiếu bầu, các tiêu đề được gán mã cơ sở gồm 36 chữ số duy nhất được tạo bằng kỹ thuật băm hiện đại, đảm bảo không có xung đột với các tiêu đề bỏ phiếu khác> 70 và không phát hiện sai ≤ 70 tiêu đề phiếu bầu. Kỹ thuật tiên tiến này hoàn toàn không giống với việc thử đếm số thùng ngẫu nhiên cho đến khi không tạo ra va chạm.
  • > 70 mã tiêu đề phiếu bầu và số phiếu bầu của họ được mã hóa thành một chuỗi (6 byte cho mỗi tiêu đề), được chuyển đổi thành bảng tra cứu đơn giản. Do đó, thói quen không có lỗi cho tất cả> 70 danh hiệu bầu chọn.

10

Python 2, Điểm = 0.335027, 999 ký tự, Dự đoán 11.34828 cho câu hỏi này

Chỉ để có được quả bóng lăn. Đây là nơi tối ưu.

Điều SVM ưa thích chỉ là ý tưởng ngẫu nhiên của tôi và tôi cảm thấy muốn thực hiện nó, vì vậy đây là. Nó cải thiện đường cơ sở thêm 0,02 điểm, vì vậy tôi đủ hạnh phúc với điều đó. Nhưng để chỉ ra rằng đầu vào mã hóa cứng là nơi mà phần lớn sự cải tiến đến từ đó, tôi cũng khó mã hóa một số câu trả lời.

Nếu không có mã hóa cứng, điểm số là 0,360 (và thực tế tất cả các dự đoán là khoảng 11, haha)

Tôi đang sử dụng scikit-họcNLTK

import sys
import math
import csv
from sklearn.feature_extraction.text import TfidfVectorizer as TV
from sklearn.svm import SVR
from nltk.stem.porter import PorterStemmer as PS
sd = {}
lr = None
tv = None
with open(sys.argv[1], 'r') as cf:
    sr = csv.reader(cf)
    for sc, t in sr:
        if sc == 'Score':
            continue
        sd[t] = int(sc)
ts,scs = zip(*sd.items())
s = PS()
def analyzer(st):
    r = []
    for word in st.split():
        if word.isdigit():
            r.append('<NUM>')
        elif not word.isalnum():
            r.append('<PUNCT>')
        else:
            r.append(s.stem(word.lower()))
    return r
tv = TV(min_df=25, stop_words='english', analyzer=analyzer)
ti = tv.fit_transform(ts)
lr = SVR()
lr.fit(ti, scs)
d={'4 w':378,'y 42':333,'eeta':280,'an Got':279,'s 2 ':275,"e I'":208,'r CP':203,'? No':179,'B.O':156}
def c(t):
    for s in d.keys():
        if s in t:
            return d[s]
    t = tv.transform([t])
    r = lr.predict(t)[0]+1.5
    return r

Tôi không chắc là tôi hiểu - bạn đọc điểm từ một tệp bên ngoài? Vậy tại sao không chỉ dự đoán sd [t]? Điều này sẽ cho điểm 0 ...
Ofri Raviv

2
Bởi vì điều đó sẽ không vui = p
justhalf

4

Python 2, 986 ký tự, điểm 0,3480188, dự đoán 12

M,S=14.29,23.02
D=lambda x:[ord(y)-32 for y in x]
w='fiLoNoNuMiNoTiMoShOnLoGoLeThRantexgensuBaSqUnInPeReGaMuLinprOuThInThEvEnClOpExPyThADdiSoLiSiMaTrEqUsImAsCoManstARrePoWoReawhapoLandradeTyPaLOsoReCreprediVeReSpebeTiPrImPladaTrihelmakwhicolpaReValpaTrafoROsoumovfinfunpuzyoufaSeQuiwhecoDeChagivcouchehanpoStrdiGraconjavwricalfrowitbinbrafrabuipoi'
for i in range(26):w=w.replace(chr(65+i),chr(97+i)*2)
w=[w[i:i+3]for i in range(0,372,3)]
m=D("(+),+)+=*...+..++'(*)5)/2)*43++16+0,+33*4*/(0.'+>-)+13+(2?8+6;,3;43+4(+.('(,.*.*+56+6)0((++(B,))+E0,-7/)/*++),+***)2+(3(.*)'")
s=D("))'B)'*j+:51(*3+0')+)^'/<-+MG,-1=),-0:A+T&J&K1%,O*()4Y-%:_A.=A*C]MJ-N%)5(%%-0+).*3Q(M&0'%(+$p*)()a8:-T?%5(-*'/.'+)+@,'J&1'&&")
def G(x,m,s):s=s or 1e-9;return(.4/s)*(2.78**(-(x-m)**2./(2*s*s)))
d={w[i]:(m[i],s[i])for i in range(124)}
def Z(t,c):
 p=1
 for W in t.split():
  if len(W)>3:
   W=W[:3].lower()
   if W in d:p*=G(c,*d[W])
 return p*G(c,M,S)
def J(t):return max([(Z(t,r),r)for r in range(-9,99)])[1]

Các chức năng có liên quan là J.

Chương trình về cơ bản là Naive Bayes sử dụng các từ tiêu đề làm tính năng, nhưng nó cực kỳ hạn chế nhờ giới hạn char. Làm thế nào hạn chế? Tốt...

  • Đối với mỗi tiêu đề, chúng tôi chuyển đổi thành chữ thường và chỉ nhìn vào các từ dài ít nhất 4 chữ cái. Sau đó, chúng tôi lấy ba chữ cái đầu tiên của mỗi từ đó làm tính năng. Chúng tôi bỏ qua tước dấu chấm câu để tiết kiệm ký tự.
  • Chúng tôi chỉ chọn các bộ ba chữ cái bắt đầu ít nhất 19 từ (những từ này được lưu trữ ở wtrên). Quá trình nén được thực hiện bằng cách sắp xếp lại các bộ ba sao cho càng nhiều chữ cái nhân đôi càng tốt và các cặp này được thay thế bằng chữ hoa ASCII tương ứng của chúng (ví dụ: fiLoNoN ... → fil, lon, non, ...)
  • Đối với mỗi bộ ba, chúng tôi xem xét điểm số của các tiêu đề mà nó xuất hiện và tính toán độ lệch trung bình và tiêu chuẩn của điểm số. Sau đó chúng ta chuyển đổi những số nguyên và lưu trữ chúng trong m, strên, bằng cách sử dụng thực tế là / sd bình là tối đa 90 (cho phép mã hóa ASCII trực tiếp, kể từ khi có 95 mã ASCII in)
  • G là hàm phân phối bình thường - chúng ta làm tròn e đến 2dp và căn bậc hai nghịch đảo của 2 pi đến 1 dp để tiết kiệm ký tự.

Hoàn toàn giới hạn char cực kỳ khiến đây trở thành một trong những ý tưởng tồi tệ nhất mà tôi từng nghĩ ra, nhưng tôi khá hài lòng với việc tôi đã xoay sở được bao nhiêu (mặc dù nó không hoạt động tốt). Nếu bất cứ ai có ý tưởng tốt hơn để nén, xin vui lòng cho tôi biết :)

(Cảm ơn KennyTM vì đã chỉ ra sự nén vô nghĩa của tôi)


Trừ khi tôi đã thực thi mã sai, mã nén của bạn thậm chí còn dài hơn kết quả giải nén ... w='grge…scse';w=[w[i:i+2]for i in range(0,len(w),2)]là 165 byte trong khi của bạn C=lambda:…;w=C('…')là 179 byte.
kennytm

@KennyTM Oh cảm ơn - Tôi đã loay hoay với mã rất nhiều, cố gắng để phù hợp với giới hạn char mà tôi đã mất dấu vết của tất cả các nén. : P
Sp3000

4

Python 2, 535 ký tự, điểm 0,330910, dự đoán 11,35

Trung bình số điểm cho các tiêu đề chứa mỗi từ, sau đó sử dụng 50 từ trên cùng và dưới cùng để có thể sửa đổi điểm BASE trong guess(title)chức năng.

Mã Python:

BASE = 11.35
word={}
for sc,ti in csv.reader(open(sys.argv[1])):
    if sc == 'Score': continue
    parts = re.findall(r"[-a-zA-Z']+", ti.lower())
    for p in parts:
        a, c = word.get(p, (0.0,0))
        word[p] = (a+int(sc), c+1)

rank = sorted([(sc/ct,wd) for wd,(sc,ct) in word.items() if ct > 2])
adjust = rank[:50] + rank[-50:]

def guess(title):
    score = BASE
    parts = re.findall(r"[-a-zA-Z']+", title.lower())
    for sc,wd in adjust:
        if wd in parts:
            score *= 0.7 + 0.3*sc/BASE
    return score

3

C

Điểm: Không xác định
Độ dài: 5 byte
Dự đoán: 5

Chơi gôn

int s(char *p){return 5;}

Ung dung:

int s(char *p)
{
   return 5;
}

Một truy vấn về điểm số cho điểm trung bình là 5.

Tôi không có khả năng kiểm tra nó vào lúc này, những người khác được chào đón để chạy / chỉnh sửa.


Bay thêm: int s () {return 5;}
Joshua

"Bạn được thử thách viết một chương trình hoặc chức năng lấy tiêu đề của câu hỏi PPCG làm đầu vào và trả về dự đoán về điểm số của nó." - Xin lỗi nhưng không: 0
Joshpbarron

Tôi đã thấy một nền tảng mà nếu bạn quên main (), hàm đầu tiên của bạn là main (). Có lẽ anh ấy phụ thuộc vào điều đó.
Joshua
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.