2017-09-18 7 views
0
に変換します。

私はMathサイトの親切にも(Python形式の)hereという共有サイトのコードを変換しようとしています。私は数学では大したことではありませんが、元のPythonコードではなく、直線的に出力が上がっているように私はここで何か間違っていると思います。何が間違っているのですか?この種の微積分を経験した方がJavascriptに変換するのに役立ちますか?ありがとう!PythonからJSへの加重線形回帰コードを

Pythonコード:

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

マイコード(fiddlehereから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));