Bir Dize Doğrusal Regresyon


25

Bu meydan okuma bir dizi verilen, biraz zor ama oldukça basittir s:

meta.codegolf.stackexchange.com

Dizedeki karakterin konumunu bir xkoordinat olarak ve ascii değerini bir ykoordinat olarak kullanın. Yukarıdaki dize için, sonuçta elde edilen koordinat kümesi şöyle olacaktır:

0, 109
1, 101
2, 116
3, 97
4, 46
5, 99
6, 111
7, 100
8, 101
9, 103
10,111
11,108
12,102
13,46
14,115
15,116
16,97
17,99
18,107
19,101
20,120
21,99
22,104
23,97
24,110
25,103
26,101
27,46
28,99
29,111
30,109

Daha sonra, Linear Regression kullanarak topladığınız setin hem eğimini hem de y-kesişimini hesaplamanız gerekir , işte yukarıda çizilen set:

Arsa

Hangi sonuçta en uygun çizgiye (0 indeksli):

y = 0.014516129032258x + 99.266129032258

İşte 1 indeksli en uygun çizgi:

y = 0.014516129032258x + 99.251612903226

Böylece programınız geri dönecekti:

f("meta.codegolf.stackexchange.com") = [0.014516129032258, 99.266129032258]

Veya (Diğer herhangi bir mantıklı format):

f("meta.codegolf.stackexchange.com") = "0.014516129032258x + 99.266129032258"

Veya (Diğer herhangi bir mantıklı format):

f("meta.codegolf.stackexchange.com") = "0.014516129032258\n99.266129032258"

Veya (Diğer herhangi bir mantıklı format):

f("meta.codegolf.stackexchange.com") = "0.014516129032258 99.266129032258"

Sadece açık değilse neden bu şekilde döndüğünü açıklayın.


Bazı açıklama kuralları:

- Strings are 0-indexed or 1 indexed both are acceptable.
- Output may be on new lines, as a tuple, as an array or any other format.
- Precision of the output is arbitrary but should be enough to verify validity (min 5).

Bu en düşük bayt sayısı kazanır.


3
Eğimi ve y-kesişimini hesaplamak için herhangi bir bağlantınız / formülünüz var mı?
Rod

16
Sevgili Belirsiz seçmenler: Formüle sahip olmanın güzel olduğu konusunda hemfikir olduğum halde, hiçbir şekilde gerekli değildir. Lineer regresyon, matematik dünyasında iyi tanımlanmış bir şeydir ve OP, denklemi okuyucuyu bulmaktan bırakmak isteyebilir.
Nathan Merrill


2
Gibi en uygun çizginin gerçek denklemini döndürmek uygun 0.014516129032258x + 99.266129032258mudur?
Greg Martin,

2
Bu yarışmanın başlığı, günün geri kalanında kafamda bu harika şarkıyı ortaya koydu
Luis Mendo

Yanıtlar:


2

MATL , 8 bayt

n:G3$1ZQ

1 tabanlı dize indeksleme kullanılır.

Çevrimiçi deneyin!

açıklama

n:     % Input string implicitly. Push [1 2 ... n] where n is string length.
       % These are the x values
G      % Push the input string. A string is an array of chars, which is
       % equivalent to an array of ASCII codes. These are the y values
3$     % The next function will use 3 inputs
1      % Push 1
ZQ     % Fit polynomial of degree 1 to those x, y data. The result is an
       % array with the polynomial coefficients. Implicitly display

7

Octave, 29 26 24 20 bayt

@(s)s/[!!s;1:nnz(s)]

Çevrimiçi Deneyin!

Biz model var

y= intercept *x^0 + slope * x
 = intercept * 1  + slope * x

İşte ydize ASCII değeris

Kesişim ve eğim parametrelerini bulmak için aşağıdaki denklemi oluşturabiliriz:

s = [intercept slope] * [1 X]

yani

[intercept slope] = s/[1 x]

!!sBir dizgiyi, dize ile aynı uzunlukta olan bir vektöre dönüştürür.
Bunların vektörü, kesişim kestirimi için kullanılır.
1:nnz(s)1 olarak kullanılan dizgenin elementleri arasındaki değerler aralığıdır x.

Önceki cevap

@(s)ols(s'+0,[!!s;1:nnz(s)]')

Test için aşağıdaki kodu Octave Online'a yapıştırın.

(@(s)ols(s'+0,[!!s;1:nnz(s)]'))('meta.codegolf.stackexchange.com')

Dizeyi girdi olarak kabul eden ve modelin en küçük kareler tahminini uygulayan işlev y = x*b + e

Ols'ın ilk argümanı, yonun dizgesini çevirip sASCII kodunu elde etmek için 0 rakamı eklediğimizdir.


/, iyi fikir!
Luis Mendo

6

TI-Basic, 51 (+ 141) bayt

Dizeler TI-Basic'te 1 tabanlıdır.

Input Str1
seq(I,I,1,length(Str1->L1
32+seq(inString(Str2,sub(Str1,I,1)),I,1,length(Str1->L2
LinReg(ax+b)

Diğer örnek gibi, bu da X cinsinden en uygun çizginin denklemini verir. Ayrıca, Str2'de TI-Basic'te 141 bayt olan bu dizgeye sahip olmanız gerekir:

! "# $% & '() * +, - / 0123456789:;. <? => @ ABCDEFGHIJKLMNOPQRSTUVWXYZ [] ^ _abcdefghijklmnopqrstuvwxyz{|}~

Bunun programın bir parçası olmamasının nedeni, TI-Basic'te iki karakterin otomatik olarak bir dizgeye eklenememesidir. Birincisi STO->ok, ama bu bir problem değil çünkü ASCII'nin bir parçası değil. Diğeri, "yalnızca bir Y=denklem yazarak ve kullanarak dize edilebilecek, literal ( ) dizesidir Equ>String(.


Bunun için eski hesap makinelerini patlatabilecek birini merak ediyorum :). Bunu düşündüğümde eski TI-83'üm aklımdaydı.
Magic Octopus Urn

@carusocomputing Hey, güzel! TI-Basic programlama dilini çok seviyorum ve birçok kod golfü için kullanıyorum. Keşke ASCII destekliyse ...
Timtech

İki yorum: 1, "bir programdaki kullanıcı girişi olarak bunu isteyip istemediğinizi belirleyebilir, burada size yardımcı olmaz, ama ben sadece bu gerçeği belirtmek istedim. 2, hesap makinesi üzerinde mevcut olan bu karakterlerin bazılarını tanımıyorum. Yanılıyor olabilirim, ama örneğin, nereye alabilirim @ve ~? Sıra gibi #, $ve &.
Patrick Roberts

Yorumunuz için teşekkürler, @PatrickRoberts. Bunlar 0xBB ile başlayan iki baytlık jetonlardır. Tibasicdev.wikidot.com/miscellaneous-tokens
Timtech

6

R, 46 45 bayt

x=1:nchar(y<-scan(,""));lm(utf8ToInt(y)~x)$co

Stdin'den ve verilen test durumu iadesi için girişi okur (tek indeksli):

(Intercept)           x 
99.25161290  0.01451613 

Biraz daha kısa (ancak test edilmemiş, muhtemelen formülü ayrıştırmada bazı değerlendirme problemleri):lm(utf8ToInt(y<-scan(,""))~1:nchar(y))$co
rturnbull

@ rturnbull İlk başta bunu denedim, ancak xdeğişkenin çalışması için önceden tanımlanmış olması gerekiyor gibi görünüyor lm.
Billywob

@ rturnbull Değişken uzunluklarda bu konuda farklı hatalar alıyorum. Biz verilmiştir syüzden x=1:nchar(s);lm(charToRaw(s)~x)$cobazı bayt kaydeder. Ayrıca $coteknik olarak gerekli olup olmadığını da bilmiyorum , çünkü hala onsuz + katsayısını elde edersiniz
Chris

@Chris Oldukça kesin bir cevap olmadığından emin olun. Stdin'den veya fonksiyon argümanından bir miktar girdi olmalı.
Billywob

Yeterince adil, sadece sorularımı okudum - python + oktav cevaplarıyla daha adil bir karşılaştırma yapıyor
Chris

5

Python, 82 80 bayt

@Mego sayesinde -2 bayt

Kullanarak scipy:

import scipy
lambda s:scipy.stats.linregress(range(len(s)),list(map(ord,s)))[:2]

Adsız kuzuların girmesine izin verilir, böylece onu bırakabilirsiniz f=.
Mego

@DigitalTrauma numpy.linalg.lstsqgörünüşte argümanlarda farklılık gösterir scipy.stats.linregressve daha karmaşıktır.
dfernan

4

Mathematica, 31 bayt

Fit[ToCharacterCode@#,{1,x},x]&

Adsız işlev, giriş olarak bir dize alarak ve söz konusu en uygun çizginin gerçek denklemini döndürür. Örneğin, f=Fit[ToCharacterCode@#,{1,x},x]&; f["meta.codegolf.stackexchange.com"]geri döner 99.2516 + 0.0145161 x.

ToCharacterCodeASCII dizesini karşılık gelen ASCII değerlerinin listesine dönüştürür; Gerçekten de, daha genel olarak UTF-8'e varsayılandır. (Çok üzgün, bu bağlamda, bir işlev adı kod uzunluğunun% 48'inden fazlasını içeriyor ...) Ve Fit[...,{1,x},x]doğrusal regresyon hesaplamak için yerleşiktir.


1
1 indeksli satır örneği için teşekkürler, haha ​​nedeniyle hesaplamak zorunda değildi.
Magic Octopus Urn

4

Node.js, 84 bayt

Kullanarak regression:

s=>require('regression')('linear',s.split``.map((c,i)=>[i,c.charCodeAt()])).equation

gösteri

// polyfill, since this is clearly not Node.js
function require(module) {
  return window[module];
}
// test
["meta.codegolf.stackexchange.com"].forEach(function test(string) {
  console.log(string);
  console.log(this(string));
},
// submission
s=>require('regression')('linear',s.split``.map((c,i)=>[i,c.charCodeAt()])).equation
);
<script src="https://cdn.rawgit.com/Tom-Alexander/regression-js/master/src/regression.js"></script>


3

Adaçayı, 76 bayt

var('m','c')
y(x)=m*x+c
f=lambda x:find_fit(zip(range(len(x)),map(ord,x)),y)

Neredeyse golf oynamak, muhtemelen golf oynamak için Python cevaplarından daha uzun, ama evet ...


2

J , 11 bayt

3&u:%.1,.#\

Bu tek tabanlı bir indeksleme kullanır.

Çevrimiçi deneyin!

açıklama

3&u:%.1,.#\  Input: string S
         #\  Get the length of each prefix of S
             Forms the range [1, 2, ..., len(S)]
      1,.    Pair each with 1
3&u:         Get the ASCII value of each char in S
    %.       Matrix divide

2

JavaScript, 151 148 bayt

s=>([a,b,c,d,e]=[].map.call(s,c=>c.charCodeAt()).reduce(([a,b,c,d,e],y,x)=>[a+1,b+x,c+x*x,d+y,e+x*y],[0,0,0,0,0]),[k=(e*a-b*d)/(c*a-b*b),(d-k*b)/a])

Daha okunabilir:


Sen kaldırarak bir bayt kaydedebilirsiniz 0gelen c.charCodeAt(0)ve hareket ettirerek başka 2 byte k=...virgül grubu ve benzeri döndürülen dizinin ilk endekste doğrudan koyarak[k=...,(d-k*b)/a]
Patrick Roberts

2

Javascript (ES6), 112 bayt

s=>[m=(a=b=c=d=0,([...s].map((u,x)=>{a+=n=x,b+=y=u.charCodeAt(),c+=x*x,d+=x*y}),++n)*d-a*b)/(n*c-a*a),b/n-m*a/n]

F=s=>[m=(a=b=c=d=0,([...s].map((u,x)=>{a+=n=x,b+=y=u.charCodeAt(),c+=x*x,d+=x*y}),++n)*d-a*b)/(n*c-a*a),b/n-m*a/n]

const update = () => {
  console.clear();
  console.log(F(input.value));
};
input.oninput = update;
update();
#input {
  width: 100%;
  box-sizing: border-box;
}
<input id="input" type="text" value="meta.codegolf.stackexchange.com" length=99/>
<div id="output"></div>


2

Haskell, 154 142 bayt

import Statistics.LinearRegression
import Data.Vector
g x=linearRegression(generate(Prelude.length x)i)$i.fromEnum<$>fromList x
i=fromIntegral

İthalatlar ve uzun işlev adları nedeniyle beğenilerim için çok uzun, ama iyi. Golf ithalatı konusunda uzman olmasam da, başka bir Golf yöntemi kaldığını düşünemedim.

Nimi sayesinde değiştirerek 12 byte ile FromEnum'dan ordithal Data.Charederek çıkardık.


1
Sen değiştirebilir ordile fromEnumve kurtulmak import Data.Char.
nimi

1

SAS Makro Dili, 180 bayt

1 tabanlı indeksleme kullanır. Çıktı sadece eğim ve kesişme olduğunda çözüm oldukça endişe verici hale geliyor.

%macro t(a);data w;%do i=1 %to %length(&a);x=&i;y=%sysfunc(rank(%substr(&a,&i,1)));output;%end;run;proc reg outtest=m;model y=x/noprint;run;proc print data=m;var x intercept;%mend;

1

Clojure, 160 bayt

Hiçbir yerleşik, Perceptron makalesinde açıklanan yinelemeli algoritmayı kullanır . Diğer girdilerde bir araya gelmeyebilir, bu durumda öğrenme oranını düşürün 2e-4ve yineleme sayısını artırın 1e5. Yinelemeli olmayan algoritmanın uygulanması daha kısa süreceğinden emin değil.

#(nth(iterate(fn[p](let[A apply e(for[x(range(count %))](-(int(get % x))(*(p 1)x)(p 0)))](mapv(fn[p e](+(* e 2e-4)p))p[(A + e)(A +(map *(range)e))])))[0 0])1e5)

Örnek:

(def f #( ... ))
(f "meta.codegolf.stackexchange.com")

[99.26612903225386 0.014516129032464659]

1

Akçaağaç, 65 bayt

Statistics:-LinearFit(b*x+a,[$(1..length(s))],convert(s,bytes),x)

Kullanımı:

s := "meta.codegolf.stackexchange.com";
Statistics:-LinearFit(b*x+a,[$(1..length(s))],convert(s,bytes),x);

İade:

99.2516129032259+0.0145161290322573*x

Notlar: Bu, a * x + b formundaki bir polinomu verilere sığdırmak için Fit komutunu kullanır . Dize ilişkin ASCII değerleri, bayt değerine dönüştürülerek bulunur .

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.