Skip to content

Commit 2444b9e

Browse files
author
KWalkerNNK
committed
💤
0 parents  commit 2444b9e

File tree

5 files changed

+346
-0
lines changed

5 files changed

+346
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
*.js

README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Polynomial Regression
2+
**PolynomialRegression** là một class trong JavaScript để thực hiện việc khớp một phương trình đa thức với một tập hợp các điểm dữ liệu sử dụng phương pháp hồi quy đa thức. Class này cung cấp một số phương thức cho việc tính toán và xử lý ma trận, bao gồm:
3+
4+
**transpose(matrix: number[][]): number[][]**: Tính chuyển vị của một ma trận.
5+
6+
**multiplyMatrices(a: number[][], b: number[][]): number[][]**: Nhân hai ma trận lại với nhau.
7+
8+
**invertMatrix(matrix: number[][]): number[][]**: Tính nghịch đảo của một ma trận vuông sử dụng phép loại Gauss.
9+
10+
## Usage
11+
Bạn có thể sử dụng class **PolynomialRegression** bằng cách import hoặc require nó vào trong dự án của mình, sau đó khởi tạo một đối tượng và gọi các phương thức để thực hiện việc khớp đa thức với dữ liệu.
12+
```js
13+
import { PolynomialRegression } from './PolynomialRegression';
14+
15+
const xValues = [0, 1, 2, 3, 4];
16+
const yValues = [1, 2, 3, 4, 5];
17+
18+
// Khởi tạo đối tượng PolynomialRegression
19+
const polynomialRegression = new PolynomialRegression();
20+
21+
// Khớp đa thức bậc hai với dữ liệu
22+
const degree = 2;
23+
const coefficients = polynomialRegression.fit(xValues, yValues, degree);
24+
25+
// Tính giá trị dự đoán cho một giá trị x mới
26+
const newX = 5;
27+
const predictedY = polynomialRegression.predict(newX, coefficients);
28+
29+
console.log(predictedY); // 6
30+
31+
```
32+
33+
## API
34+
**fit(xValues: number[], yValues: number[], degree: number): number[]**
35+
Phương thức **fit** được sử dụng để khớp một đa thức bậc **degree** với dữ liệu được cung cấp bởi hai mảng **xValues****yValues** . Phương thức này trả về một mảng chứa các hệ số của đa thức khớp.
36+
```js
37+
const xValues = [0, 1, 2, 3, 4];
38+
const yValues = [1, 2, 3, 4, 5];
39+
const degree = 2;
40+
41+
const polynomialRegression = new PolynomialRegression();
42+
const coefficients = polynomialRegression.fit(xValues, yValues, degree);
43+
44+
console.log(coefficients); // [1, 0, 0]
45+
46+
```
47+
48+
**predict(xValue: number, coefficients: number[]): number**
49+
Phương thức **predict** được sử dụng để tính giá trị dự đoán cho một giá trị **xValue** mới, sử dụng các hệ số của đa thức đã được tính toán trước đó. Phương thức này trả về giá trị dự đoán cho **xValue**.
50+
```js
51+
const xValues = [0, 1, 2, 3, 4];
52+
const yValues = [0, 2, 4, 6, 8];
53+
54+
// Tính đa thức bậc 1
55+
const degree = 1;
56+
const coefficients = polynomialRegression(xValues, yValues, degree);
57+
58+
// Dự đoán giá trị y cho xValue = 5
59+
const xValue = 5;
60+
const predictedY = predict(xValue, coefficients);
61+
62+
console.log(predictedY); // Kết quả: 10
63+
64+
```
65+
66+
## Stay in touch
67+
Facebook - [Khanh Nguyen](https://www.facebook.com/KWalkerNNK)

package-lock.json

Lines changed: 58 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "learning",
3+
"version": "1.0",
4+
"description": "🤍",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1",
8+
"compile": "npx tsc --lib ES2022,dom src/PolynomialRegression.ts",
9+
"start": "node src/PolynomialRegression.js",
10+
"format": "prettier --write \"src/**/*.ts\"",
11+
"build": "npx tsc --lib ES2022,dom src/PolynomialRegression.ts && npx uglify-js src/PolynomialRegression.js -o dist/PolynomialRegression.min.js"
12+
},
13+
"author": "Khanh Nguyen",
14+
"license": "ISC",
15+
"dependencies": {
16+
"prettier": "^2.8.7",
17+
"typescript": "^5.0.4"
18+
},
19+
"devDependencies": {
20+
"uglify-js": "^3.17.4"
21+
}
22+
}

src/PolynomialRegression.ts

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
class PolynomialRegression {
2+
public static tolerance = 1e-10;
3+
4+
/**
5+
* Tính chuyển vị của ma trận
6+
* @param matrix Ma trận cần chuyển vị
7+
* @returns Ma trận chuyển vị
8+
*/
9+
private static transpose(matrix: number[][]): number[][] {
10+
// Khởi tạo ma trận chuyển vị với kích thước phù hợp
11+
const transposed: number[][] = [];
12+
for (let i = 0; i < matrix[0].length; i++) {
13+
transposed.push([]);
14+
}
15+
16+
// Điền giá trị vào ma trận chuyển vị
17+
for (let i = 0; i < matrix.length; i++) {
18+
for (let j = 0; j < matrix[i].length; j++) {
19+
transposed[j][i] = matrix[i][j];
20+
}
21+
}
22+
23+
return transposed;
24+
}
25+
26+
/**
27+
* Nhân hai ma trận lại với nhau
28+
* @param a Ma trận thứ nhất
29+
* @param b Ma trận thứ hai
30+
* @returns Kết quả của việc nhân hai ma trận lại với nhau
31+
*/
32+
private static multiplyMatrices(a: number[][], b: number[][]): number[][] {
33+
// Khởi tạo ma trận kết quả với kích thước phù hợp
34+
const result: number[][] = [];
35+
for (let i = 0; i < a.length; i++) {
36+
result.push([]);
37+
for (let j = 0; j < b[0].length; j++) {
38+
result[i].push(0);
39+
}
40+
}
41+
42+
// Tính toán giá trị của ma trận kết quả
43+
for (let i = 0; i < a.length; i++) {
44+
for (let j = 0; j < b[0].length; j++) {
45+
for (let k = 0; k < a[0].length; k++) {
46+
result[i][j] += a[i][k] * b[k][j];
47+
}
48+
}
49+
}
50+
51+
return result;
52+
}
53+
54+
/**
55+
* Tính nghịch đảo của ma trận vuông sử dụng phép loại Gauss
56+
* @param matrix Ma trận vuông cần tính nghịch đảo
57+
* @returns Nghịch đảo của ma trận đã cho
58+
*/
59+
private static invertMatrix(matrix: number[][]): number[][] {
60+
// Khởi tạo ma trận mở rộng với ma trận đã cho và một ma trận đơn vị cùng kích thước
61+
const augmented: number[][] = [];
62+
for (let i = 0; i < matrix.length; i++) {
63+
augmented.push([...matrix[i]]);
64+
for (let j = 0; j < matrix.length; j++) {
65+
augmented[i].push(i === j ? 1 : 0);
66+
}
67+
}
68+
69+
// Thực hiện phép loại Gauss trên ma trận mở rộng để chuyển đổi nó thành dạng hàng bậc thang rút gọn
70+
for (let i = 0; i < augmented.length; i++) {
71+
// Tìm phần tử chốt và hoán đổi hàng nếu cần thiết
72+
let pivotRow = i;
73+
for (let j = i + 1; j < augmented.length; j++) {
74+
if (Math.abs(augmented[j][i]) > Math.abs(augmented[pivotRow][i])) {
75+
pivotRow = j;
76+
}
77+
}
78+
[augmented[pivotRow], augmented[i]] = [augmented[i], augmented[pivotRow]];
79+
80+
// Chia hàng chốt cho phần tử chốt để làm cho nó bằng một
81+
const pivotElement = augmented[i][i];
82+
for (let j = i; j < augmented[i].length; j++) {
83+
augmented[i][j] /= pivotElement;
84+
}
85+
86+
// Trừ bội số của hàng chốt từ tất cả các hàng khác để làm cho tất cả các phần tử khác trong cột hiện tại bằng không
87+
for (let j = 0; j < augmented.length; j++) {
88+
if (j !== i) {
89+
const factor = augmented[j][i];
90+
for (let k = i; k < augmented[j].length; k++) {
91+
augmented[j][k] -= factor * augmented[i][k];
92+
}
93+
}
94+
}
95+
}
96+
97+
// Trích xuất ma trận nghịch đảo từ nửa bên phải của ma trận mở rộng
98+
const inverse: number[][] = [];
99+
for (let i = 0; i < augmented.length; i++) {
100+
inverse.push(augmented[i].slice(augmented.length));
101+
}
102+
103+
return inverse;
104+
}
105+
106+
/**
107+
* Khớp một phương trình đa thức với một tập hợp các điểm dữ liệu bằng cách sử dụng hồi quy đa thức
108+
* @param xValues Các giá trị x của các điểm dữ liệu
109+
* @param yValues Các giá trị y của các điểm dữ liệu
110+
* @param order Bậc của đa thức để khớp
111+
* @returns Một mảng chứa các hệ số của đa thức được khớp theo thứ tự tăng dần của bậc
112+
*/
113+
public static async polynomialRegression(
114+
xValues: number[],
115+
yValues: number[],
116+
order: number
117+
): Promise<number[]> {
118+
return new Promise((resolve) => {
119+
// Khởi tạo ma trận thiết kế với kích thước phù hợp
120+
const designMatrix: number[][] = [];
121+
for (let i = 0; i < xValues.length; i++) {
122+
designMatrix.push([]);
123+
for (let j = 0; j <= order; j++) {
124+
designMatrix[i].push(Math.pow(xValues[i], j));
125+
}
126+
}
127+
128+
// Tính chuyển vị của ma trận thiết kế
129+
const designMatrixTransposed =
130+
PolynomialRegression.transpose(designMatrix);
131+
132+
// Tính tích của chuyển vị của ma trận thiết kế và ma trận thiết kế
133+
const designMatrixProduct = PolynomialRegression.multiplyMatrices(
134+
designMatrixTransposed,
135+
designMatrix
136+
);
137+
138+
// Đảo ngược tích của chuyển vị của ma trận thiết kế và ma trận thiết kế
139+
const designMatrixProductInverse =
140+
PolynomialRegression.invertMatrix(designMatrixProduct);
141+
142+
// Định dạng lại các giá trị y thành một ma trận cột
143+
const yValuesColumnMatrix: number[][] = [];
144+
for (let i = 0; i < yValues.length; i++) {
145+
yValuesColumnMatrix.push([yValues[i]]);
146+
}
147+
148+
// Tính tích của chuyển vị của ma trận thiết kế và ma trận cột giá trị y
149+
const designMatrixYValuesProduct = PolynomialRegression.multiplyMatrices(
150+
designMatrixTransposed,
151+
yValuesColumnMatrix
152+
);
153+
154+
// Tính các hệ số của đa thức được khớp bằng cách nhân nghịch đảo của tích của chuyển vị của ma trận thiết kế và ma trận thiết kế với tích của chuyển vị của ma trận thiết kế và ma trận cột giá trị y
155+
const coefficientsColumnMatrix = PolynomialRegression.multiplyMatrices(
156+
designMatrixProductInverse,
157+
designMatrixYValuesProduct
158+
);
159+
160+
// Định dạng lại ma trận cột hệ số thành một mảng
161+
const coefficients: number[] = [];
162+
for (let i = 0; i < coefficientsColumnMatrix.length; i++) {
163+
coefficients.push(coefficientsColumnMatrix[i][0]);
164+
}
165+
166+
resolve(coefficients);
167+
});
168+
}
169+
}
170+
171+
// Kiểm tra
172+
(async () => {
173+
const xValues = [1, 2, 3];
174+
const yValues = [1, 4, 9];
175+
const order = 2;
176+
const coefficients = await PolynomialRegression.polynomialRegression(
177+
xValues,
178+
yValues,
179+
order
180+
);
181+
182+
// Kết quả của hồi quy đa thức
183+
console.log(coefficients);
184+
185+
// So sánh các hệ số được tính toán với các hệ số mong đợi bằng cách sử dụng giá trị dung sai
186+
const expectedCoefficients = [0, 0, 1];
187+
for (let i = 0; i < coefficients.length; i++) {
188+
if (
189+
Math.abs(coefficients[i] - expectedCoefficients[i]) <
190+
PolynomialRegression.tolerance
191+
) {
192+
console.log(`Hệ số ${i} gần đúng với giá trị mong đợi`);
193+
} else {
194+
console.log(`Hệ số ${i} không đúng với giá trị mong đợi`);
195+
}
196+
}
197+
})();

0 commit comments

Comments
 (0)