문자열에 대한 선형 회귀


25

이 도전은 문자열을 감안할 때 약간 까다 롭지 만 다소 간단합니다 s.

meta.codegolf.stackexchange.com

문자열에서 문자의 위치를 x좌표로 사용하고 ASCII 값을 y좌표로 사용하십시오. 위의 문자열에서 결과 좌표 세트는 다음과 같습니다.

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

다음으로 Linear Regression 을 사용하여 획득 한 세트의 기울기와 y 절편을 모두 계산해야합니다 . 위의 세트는 다음과 같습니다.

음모

(0 인덱스)의 가장 적합한 줄은 다음과 같습니다.

y = 0.014516129032258x + 99.266129032258

다음은 1- 인덱싱 된 가장 적합한 행입니다.

y = 0.014516129032258x + 99.251612903226

따라서 프로그램은 다음을 반환합니다.

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

또는 (다른 합리적인 형식) :

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

또는 (다른 합리적인 형식) :

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

또는 (다른 합리적인 형식) :

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

명확하지 않은 경우 왜 해당 형식으로 반환되는지 설명하십시오.


몇 가지 명확한 규칙 :

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

이것은 최저 바이트 수 승리입니다.


3
기울기와 y 절편을 계산하기위한 링크 / 공식이 있습니까?
Rod

16
친애하는 유권자님께 : 공식을 갖는 것이 좋다는 데 동의하지만 반드시 필요한 것은 아닙니다. 선형 회귀는 수학 세계에서 잘 정의 된 것이며 OP는 독자에게 방정식을 찾는 것을 남기고 싶을 수도 있습니다.
Nathan Merrill


2
?와 같이 가장 적합한 선의 실제 방정식을 반환해도 괜찮 0.014516129032258x + 99.266129032258습니까?
Greg Martin

2
이 도전의 제목은 하루 종일 이 멋진 노래 를 내 머리 속에
Luis Mendo

답변:


2

MATL , 8 바이트

n:G3$1ZQ

1 기반 문자열 인덱싱이 사용됩니다.

온라인으로 사용해보십시오!

설명

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

옥타브, 29 26 24 20 바이트

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

온라인으로 사용해보십시오!

우리는 모델이

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

다음 y은 문자열의 ASCII 값입니다s

매개 변수 절편 및 기울기를 찾으려면 다음 방정식을 구성 할 수 있습니다.

s = [intercept slope] * [1 X]

그래서

[intercept slope] = s/[1 x]

!!s문자열을 문자열과 길이가 같은 벡터로 변환합니다.
1의 벡터는 절편의 추정에 사용됩니다.
1:nnz(s)로 사용되는 문자열의 요소 수는 1에서 수까지입니다 x.

이전 답변

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

Octave Online에 다음 코드를 테스트 붙여 넣기

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

문자열을 입력으로 받아들이고 모델의 보통 최소 제곱 추정을 적용하는 함수 y = x*b + e

ols의 첫 번째 주장은 y문자열 을 바꾸고 s숫자 0을 더해 ASCII 코드를 얻는다는 것입니다.


/좋은 생각입니다!
루이스 멘도

6

TI 기본, 51 (+ 141) 바이트

문자열은 TI-Basic에서 1 기반입니다.

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)

다른 예제와 마찬가지로 X에 따라 가장 적합한 선의 방정식을 출력합니다. 또한 Str2에는 TI-Basic에서 141 바이트 인이 문자열이 있어야합니다.

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

이것이 프로그램의 일부가 될 수없는 이유는 TI-Basic의 두 문자를 자동으로 문자열에 추가 할 수 없기 때문입니다. 하나는 STO->화살표이지만 ASCII의 일부가 아니기 때문에 문제가되지 않습니다. 다른 하나는 문자열 리터럴 ( ")이며 Y=방정식 에 입력하고을 사용 하여 문자열 화할 수 있습니다 Equ>String(.


나는 누군가가 이것에 대해 오래된 계산기를 터뜨릴 것인지 진지하게 궁금했다. 나는 이것을 생각했을 때 오래된 TI-83을 염두에 두었다.
Magic Octopus Urn

@carusocomputing 안녕하세요! TI-Basic 프로그래밍 언어를 많이 좋아하며 많은 코드 골프에 사용합니다. ASCII 만 지원한다면 ...
Timtech

두 의견 : 1, "프로그램에서 사용자 입력으로 메시지를 표시하여 문자열 화 할 수 는 있지만 여기서는 도움이되지 않지만 그 사실을 지적하고 싶었습니다. 2, 나는 계산기에 존재하는 문자를 인식하지 못합니다. 내가 틀릴 수도 있지만, 예를 들어, 당신은 어디에서받을 수 있나요 @~? 뿐만 아니라로서 #, $&.
Patrick Roberts

의견을 보내 주셔서 감사합니다. @PatrickRoberts. 이것들은 0xBB로 시작하는 2 바이트 토큰입니다. tibasicdev.wikidot.com/miscellaneous-tokens의
Timtech

6

R, 46 45 바이트

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

stdin에서 입력을 읽고 주어진 테스트 케이스 리턴에 대해 (1 인덱스) :

(Intercept)           x 
99.25161290  0.01451613 

: 약간 짧은 (수식을 파싱하지만 검증되지 않은, 아마도 몇 가지 평가 문제)lm(utf8ToInt(y<-scan(,""))~1:nchar(y))$co
rturnbull을

@ rturnbull 나는 이것을 처음 시도했지만 x변수가 lm작동하려면 미리 정의 된 것처럼 보입니다 .
Billywob

@ rturnbull 나는 가변 길이에 다른 오류가 발생합니다. 우리는 주어진 s그래서 x=1:nchar(s);lm(charToRaw(s)~x)$co일부 바이트를 저장합니다. 나는 또한 $co당신이 여전히 그것없이 가로 채기 + 계수를 얻음으로써 기술적으로 필요한지 모르겠다
Chris

@Chris 당연히 이것이 실제적인 대답이 아니라는 것을 확신하십시오. stdin 또는 함수 인수로 입력해야합니다.
Billywob

공정한 충분히 질문의 단지 내 독서는 - 그것은뿐만 아니라 파이썬 + 옥타브 답변에 대한보다 공정한 비교를 제공합니다
크리스

5

파이썬, 82 80 바이트

@Mego 덕분에 -2 바이트

사용 scipy:

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

이름이없는 람다는 허용되므로 드롭 할 수 있습니다 f=.
Mego

@DigitalTrauma의 numpy.linalg.lstsq주장은 분명히 다르고 scipy.stats.linregress더 복잡합니다.
dfernan

4

Mathematica, 31 바이트

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

이름이없는 함수를 입력으로 문자열을 가져 와서 가장 적합한 행의 실제 방정식을 반환 예를 f=Fit[ToCharacterCode@#,{1,x},x]&; f["meta.codegolf.stackexchange.com"]들어을 반환합니다 99.2516 + 0.0145161 x.

ToCharacterCodeASCII 문자열을 해당 ASCII 값 목록으로 변환합니다. 실제로 기본적으로 UTF-8이 더 일반적입니다. (이 맥락에서 하나의 함수 이름이 코드 길이의 48 % 이상을 차지한다는 것은 슬픈 일이다 ....) Fit[...,{1,x},x]선형 회귀 계산을위한 내장 함수 이다.


1
1 인덱싱 된 행의 예에 감사드립니다. 하하 때문에 계산할 필요가 없었습니다.
Magic Octopus Urn

4

Node.js, 84 바이트

사용 regression:

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

데모

// 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

세이지, 76 바이트

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

골프를 치르는 파이썬보다 더 긴 골프는 아니지만 거의 그렇습니다.


2

J , 11 바이트

3&u:%.1,.#\

이것은 하나의 기반 인덱싱을 사용합니다.

온라인으로 사용해보십시오!

설명

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

자바 스크립트, 151 148 바이트

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

더 읽기 쉬운 :


당신은 제거하여 바이트를 저장할 수 있습니다 0에서 c.charCodeAt(0), 그리고 이동하여 또 다른 2 바이트 k=...쉼표 그룹과 같이 반환 된 배열의 첫 번째 인덱스에 직접 넣어[k=...,(d-k*b)/a]
패트릭 로버츠

2

자바 스크립트 (ES6), 112 바이트

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

하스켈, 154142 바이트

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

가져 오기와 긴 함수 이름으로 인해 취향에 비해 너무 길지만 잘 나타납니다. 골프 수입 분야의 전문가는 아니지만 다른 골프 방법을 떠 올릴 수 없었습니다.

nimi 덕분에 fromEnum 으로 대체 ord하고 가져 오기 하여 12 바이트를 제거했습니다 Data.Char.


1
로 대체 ord하여 fromEnum제거 할 수 있습니다 import Data.Char.
nimi

1

SAS 매크로 언어, 180 바이트

1 기반 인덱싱을 사용합니다. 출력이 기울기와 절편 일 때 솔루션이 매우 어려워집니다.

%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

클로저, 160 바이트

내장 기능이 없으며 Perceptron 기사에 설명 된 반복 알고리즘을 사용합니다 . 다른 입력에 수렴하지 않을 수도 있습니다.이 경우 학습 속도를 낮추고 2e-4반복 횟수를 늘리십시오 1e5. 반복적이지 않은 알고리즘이 구현하기에 더 짧은 지 확실하지 않습니다.

#(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)

예:

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

[99.26612903225386 0.014516129032464659]

1

메이플, 65 바이트

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

용법:

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

보고:

99.2516129032259+0.0145161290322573*x

참고 : Fit 명령을 사용하여 a * x + b 형식의 다항식을 데이터에 맞 춥니 다. 문자열의 ASCII 값은 을 바이트 로 변환 하여 찾습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.