Add File
This commit is contained in:
146
src/main/java/org/dromara/easyai/tools/LVQ.java
Normal file
146
src/main/java/org/dromara/easyai/tools/LVQ.java
Normal file
@@ -0,0 +1,146 @@
|
||||
package org.dromara.easyai.tools;
|
||||
|
||||
import org.dromara.easyai.matrixTools.Matrix;
|
||||
import org.dromara.easyai.matrixTools.MatrixOperation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author lidapeng
|
||||
* @description LVQ 向量量化
|
||||
* @date 5:36 下午 2020/2/4
|
||||
*/
|
||||
public class LVQ {
|
||||
private int typeNub;//原型聚类个数,即分类个数(需要模型返回)
|
||||
private MatrixBody[] model;//原型向量(需要模型返回)
|
||||
private final List<MatrixBody> matrixList = new ArrayList<>();
|
||||
private final float studyPoint;//量化学习率
|
||||
private int length;//向量长度(需要返回)
|
||||
private boolean isReady = false;
|
||||
private final int lvqNub;
|
||||
private final MatrixOperation matrixOperation = new MatrixOperation();
|
||||
|
||||
public void setTypeNub(int typeNub) {
|
||||
this.typeNub = typeNub;
|
||||
}
|
||||
|
||||
public void setModel(MatrixBody[] model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
public void setReady(boolean ready) {
|
||||
isReady = ready;
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return isReady;
|
||||
}
|
||||
|
||||
public int getTypeNub() {
|
||||
return typeNub;
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public LVQ(int typeNub, int lvqNub, float studyPoint) {
|
||||
this.typeNub = typeNub;
|
||||
this.lvqNub = lvqNub;
|
||||
this.studyPoint = studyPoint;
|
||||
model = new MatrixBody[typeNub];
|
||||
}
|
||||
|
||||
public MatrixBody[] getModel() throws Exception {
|
||||
if (!isReady) {
|
||||
throw new Exception("not study");
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
public void insertMatrixBody(MatrixBody matrixBody) throws Exception {
|
||||
if (matrixBody.getMatrix().isVector() && matrixBody.getMatrix().isRowVector()) {
|
||||
Matrix matrix = matrixBody.getMatrix();
|
||||
if (matrixList.size() == 0) {
|
||||
matrixList.add(matrixBody);
|
||||
length = matrix.getY();
|
||||
} else {
|
||||
if (length == matrix.getY()) {
|
||||
matrixList.add(matrixBody);
|
||||
} else {
|
||||
throw new Exception("vector length is different");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Exception("this matrix is not vector or rowVector");
|
||||
}
|
||||
}
|
||||
|
||||
private void study() throws Exception {
|
||||
for (MatrixBody matrixBody : matrixList) {
|
||||
Matrix matrix = matrixBody.getMatrix();//特征向量
|
||||
long type = matrixBody.getId();//类别
|
||||
float distEnd = 0;
|
||||
int id = 0;
|
||||
for (int i = 0; i < typeNub; i++) {
|
||||
MatrixBody modelBody = model[i];
|
||||
Matrix modelMatrix = modelBody.getMatrix();
|
||||
//修正矩阵与原矩阵的范数差
|
||||
float dist = vectorEqual(modelMatrix, matrix);
|
||||
if (distEnd == 0 || dist < distEnd) {
|
||||
id = modelBody.getId();
|
||||
distEnd = dist;
|
||||
}
|
||||
}
|
||||
MatrixBody modelBody = model[id];
|
||||
Matrix modelMatrix = modelBody.getMatrix();
|
||||
boolean isRight = id == type;
|
||||
Matrix matrix1 = op(matrix, modelMatrix, isRight);
|
||||
modelBody.setMatrix(matrix1);
|
||||
}
|
||||
}
|
||||
|
||||
//比较两个向量之间的范数差
|
||||
public float vectorEqual(Matrix matrix1, Matrix matrix2) throws Exception {
|
||||
Matrix matrix = matrixOperation.sub(matrix1, matrix2);
|
||||
return matrixOperation.getNorm(matrix);
|
||||
}
|
||||
|
||||
private Matrix op(Matrix matrix, Matrix modelMatrix, boolean isRight) throws Exception {
|
||||
Matrix matrix1 = matrixOperation.sub(matrix, modelMatrix);
|
||||
matrixOperation.mathMul(matrix1, studyPoint);
|
||||
Matrix matrix2;
|
||||
if (isRight) {
|
||||
matrix2 = matrixOperation.add(modelMatrix, matrix1);
|
||||
} else {
|
||||
matrix2 = matrixOperation.sub(modelMatrix, matrix1);
|
||||
}
|
||||
return matrix2;
|
||||
}
|
||||
|
||||
public void start() throws Exception {//开始向量量化聚类
|
||||
Random random = new Random();
|
||||
for (int i = 0; i < typeNub; i++) {
|
||||
MatrixBody matrixBody = new MatrixBody();
|
||||
Matrix matrix = new Matrix(1, length);
|
||||
matrixBody.setMatrix(matrix);
|
||||
matrixBody.setId(i);
|
||||
for (int j = 0; j < length; j++) {
|
||||
matrix.setNub(0, j, random.nextFloat());
|
||||
}
|
||||
model[i] = matrixBody;
|
||||
}
|
||||
//初始化完成
|
||||
for (int i = 0; i < lvqNub; i++) {
|
||||
//System.out.println("================================");
|
||||
study();
|
||||
}
|
||||
isReady = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user