2017-09-18 14 views
0

수학 사이트 user3658307이 (Python 형식의) Python 형식으로 나에게 친절하게 공유 된 코드 here으로 변환하려고합니다. 필자는 수학에별로 좋지 않지만 원래 파이썬 코드가 수행해야하는 작업 대신 선형 적으로 출력이 늘어나는 것처럼 여기에서 뭔가 잘못하고 있다고 생각합니다. 내가 뭘 잘못하고 있거나 이런 종류의 미적분으로 더 경험이 많은 사람이 자바 스크립트로 변환하는 데 도움이 될까요? 감사!가중치 선형 회귀 코드를 Python에서 JS로 변환

파이썬 코드 :

import os, sys, numpy as np 
from sklearn import linear_model 
x = np.array([13,14,15,16,17,18]).reshape((6,1)) 
yRaw = [0.015,0.01,0.005,0.002,0.001,0.0005] 
y = np.array([ np.log(v) for v in yRaw ]) 
w = [100] + ([1]*4) + [10] # Weight the various data points 
print("Transformed data\n"+str(x)+"\n"+str(y)) 
# Fit linear function to transformed data 
regr = linear_model.LinearRegression() 
regr.fit(x,y,sample_weight=w) 
print('Coefficient: \n', regr.coef_) 
print('Intercept: \n', regr.intercept_) 
# Look at function explicitly 
a,b = regr.coef_[0],regr.intercept_ 
f = lambda x: np.exp(a*x + b) 
print('Outputs of function') 
for x in range(1,19): print(str(x)+": "+str(f(x))) 

내 코드 (fiddle (here에서 num.js)의 선형 함수를 사용하여)

var code = function() { 
    var x = nj.array([13, 14, 15, 16, 17, 18]).reshape(6, 1); 
    var yRaw = [0.015, 0.01, 0.005, 0.002, 0.001, 0.0005]; 
    var y = nj.array(nj.log(yRaw)); 
    //var w = 100 + (1 * 4) + 10 // Weight the various data points   
    var w = [100, 1, 1, 1, 1, 10]; 
    console.log('Transformed data', x.selection.data, y.selection.data); 

    var array = []; 
    for (var i = 0; i < 6; i++) 
     array.push([x.selection.data[i], y.selection.data[i]]); 

    var regr = weightedLinearRegression(array, w); 

    var a = regr.equation[0]; 
    var b = regr.equation[1]; 
    var f = (x) => { return a * x + b }; 
    for (var i = 1; i <= 19; i++) 
     console.log(i, f(i)); 
} 

var weightedLinearRegression = function (data, weights) { 

    var sums = { xw: 0, x: 0, yw: 0, y: 0, a: 0, b: 0 }; 

    // compute the weighted averages 
    for (var i = 0; i < data.length; i++) { 
     sums.xw += data[i][0] * weights[i]; 
     sums.yw += data[i][1] * weights[i]; 
     sums.x += data[i][0]; 
     sums.y += data[i][1]; 
    } 

    var weightedX = sums.xw/sums.x; 
    var weightedY = sums.yw/sums.y; 

    // compute the gradient and intercept 
    for (var i = 0; i < data.length; i++) { 
     sums.a += (data[i][1] - weightedY) * (data[i][0] - weightedX) * weights[i]; 
     sums.b += (data[i][0] - weightedX) * (data[i][0] - weightedX) * weights[i]; 
    } 

    var gradient = sums.a/sums.b; 
    var intercept = (weightedY - weightedX) * gradient; 
    var string = 'y = ' + Math.round(gradient * 100)/100 + 'x + ' + Math.round(intercept * 100)/100; 
    var results = []; 

    //interpolate result 
    for (var i = 0, len = data.length; i < len; i++) { 
     var coordinate = [data[i][0], data[i][0] * gradient + intercept]; 
     results.push(coordinate); 
    } 

    return { equation: [gradient, intercept], points: results, string: string }; 

} 

code(); 

올바른 출력 대를 내 출력 : 어떤 도움이 입니다

MY OUTPUT (WRONG)  | CORRECT OUTPUT 
------------------------------------------- 
1 -3.4140439207888633 | 1 51.2498600531 
2 1.6212123570552457 | 2 26.0231972143 
3 6.656468634899355 | 3 13.2138271705 
4 11.691724912743464 | 4 6.70959940293 
5 16.726981190587573 | 5 3.40694059086 
6 21.76223746843168 | 6 1.72994593159 
7 26.797493746275787 | 7 0.878416528378 
8 31.8327500241199 | 8 0.446034516593 
9 36.868006301964016 | 9 0.226483431909 
10 41.903262579808114 | 10 0.115001738702 
11 46.93851885765223 | 11 0.0583945580167 
12 51.97377513549634 | 12 0.0296510682748 
13 57.00903141334045 | 13 0.0150559552071 
14 62.04428769118455 | 14 0.00764497876085 
15 67.07954396902866 | 15 0.00388189918541 
16 72.11480024687278 | 16 0.00197111617404 
17 77.15005652471689 | 17 0.00100087580485 
18 82.185312802561 | 18 0.00050821579668 

크게 감사합니다. 감사! :)

답변

0

좋아, 많은 연구 후 나는 마침내 그것을 할 수 있었다! 고맙게도, 다른 누군가가 내가했던 것처럼 똑같은 문제가있어서 JS로 변환 한 C# here에 대한 수업을 만들었습니다. 나는 외부 라이브러리의 종류없이 JS에서 가중 된 선형 회귀 함수를 원할 미래의 독자들을 위해 여기에 남겨 둘 것이다. 내부가 옳은지 나는 잘 모르겠다. (필자는 수학을 잘한다.) 그러나 내가 필요한 결과를 준다. :)

let linearRegressionWeighted = (values) => { 

    let sumFn = (input) => { 
     var total = 0; 
     for (var i = 0; i < input.length; i++) { 
      if (isNaN(input[i])) { 
       continue; 
      } 
      total += Number(input[i]); 
     } 
     return total; 
    } 

    let sum = sumFn(values.map(x => x.weight)); 
    let xAvg = sumFn(values.map(x => x.x * x.weight))/sum; 
    let yAvg = sumFn(values.map(x => x.y * x.weight))/sum; 
    let sumXY = sumFn(values.map(x => (x.x - xAvg) * (x.y - yAvg) * x.weight)); 
    let sumXX = sumFn(values.map(x => Math.pow(x.x - xAvg, 2) * x.weight)); 

    let m = sumXX == 0 ? 0 : (sumXY/sumXX); 
    let b = yAvg - m * xAvg; 
    return { 
     coefficient: m, 
     intercept: b 
    }; 
} 

let r = linearRegressionWeighted(
    [ 
     { x: 13, y: Math.log(0.015), weight: 100 }, 
     { x: 14, y: Math.log(0.01), weight: 1 }, 
     { x: 15, y: Math.log(0.005), weight: 1 }, 
     { x: 16, y: Math.log(0.002), weight: 1 }, 
     { x: 17, y: Math.log(0.001), weight: 1 }, 
     { x: 18, y: Math.log(0.0005), weight: 10 }, 
    ] 
); 

let a = r.coefficient; 
let b = r.intercept; 
let f = (x) => Math.exp(a * x + b); 

for (let i = 1; i < 19; i++) 
    console.log(i, f(i));