我强烈怀疑它与本地错误有关,这似乎总是-1
。
我的github page可以找到完整的代码。
我已根据this tutorial实施了感知器算法。
我的输入是一个单词特征向量,形式为:
示例:
Document 1 = ["I", "am", "awesome"]
Document 2 = ["I", "am", "great", "great"]
字典是:
["I", "am", "awesome", "great"]
因此,作为矢量的文档看起来像:
Document 1 = [1, 1, 1, 0]
Document 2 = [1, 1, 0, 2]
然而,当我运行算法时,我始终得到0.0
,1.0
或0.7071067811865476
作为均方根误差的值,即Math.sqrt(globalError / inputSize)
。< / p>
这不可能是正确的正弦我每次都会将权重初始化为不同的随机变量。另外我认为迭代次数相当低,因为我有数百个单词作为我的全局字典。
我一直在网上搜索,并通过调试器仔细挑选代码,我认为我已经正确地实现了算法,但是必须有一些我没有抓住的东西,也许你们其中一个人可以发现它。
这是三种不同执行的输出结果:
首先:
Iteration 1 : RMSE = 1.0
Iteration 2 : RMSE = 1.0
Iteration 3 : RMSE = 1.0
Iteration 4 : RMSE = 1.0
Iteration 5 : RMSE = 0.7071067811865476
Iteration 6 : RMSE = 0.0
=======
Decision boundary equation:
bias: 4.9148000000000005
class = 1
第二
Iteration 1 : RMSE = 0.7071067811865476
Iteration 2 : RMSE = 1.0
Iteration 3 : RMSE = 0.7071067811865476
Iteration 4 : RMSE = 1.0
Iteration 5 : RMSE = 1.0
Iteration 6 : RMSE = 1.0
Iteration 7 : RMSE = 1.0
Iteration 8 : RMSE = 0.7071067811865476
Iteration 9 : RMSE = 0.0
=======
Decision boundary equation:
bias: -4.8511
class = 1
第三
Iteration 1 : RMSE = 1.0
Iteration 2 : RMSE = 1.0
Iteration 3 : RMSE = 1.0
Iteration 4 : RMSE = 1.0
Iteration 5 : RMSE = 0.7071067811865476
Iteration 6 : RMSE = 0.0
=======
Decision boundary equation:
bias: 9.7544
class = 1
代码如下所示:
public static void perceptron(Set<String> globoDict,
Map<String, int[]> trainingPerceptronInput,
Map<String, int[]> testPerceptronInput)
{
final int globoDictSize = globoDict.size(); // number of features (x, y, z)
// weights total 32 (31 for input variables and one for bias)
double[] weights = new double[globoDictSize + 1];
for (int i = 0; i < weights.length; i++)
{
//weights[i] = Math.floor(Math.random() * 10000) / 10000;
weights[i] = randomNumber(-10 , 10);
}
int inputSize = trainingPerceptronInput.size();
int[] outputs = new int[inputSize];
final double[][] a = initializeOutput(trainingPerceptronInput, globoDictSize, outputs);
double globalError;
int iteration = 0;
do
{
iteration++;
globalError = 0;
// loop through all instances (complete one epoch)
for (int p = 0; p < inputSize; p++)
{
// calculate predicted class
int output = Prcptrn_CalcOutpt.calculateOutput(THETA, weights, a, p);
// difference between predicted and actual class values
double localError = outputs[p] - output;
int i;
for (i = 0; i < a.length; i++)
{
weights[i] += LEARNING_RATE * localError * a[i][p];
}
weights[i] += LEARNING_RATE * localError;
// summation of squared error (error value for all instances)
globalError += localError * localError;
}
/* Root Mean Squared Error */
System.out.println("Iteration "
+ iteration + " : RMSE = " + Math.sqrt(globalError / inputSize));
}
while (globalError != 0 && iteration <= MAX_ITER);
System.out.println("\n=======\nDecision boundary equation:");
int i;
for (i = 0; i < a.length; i++)
{
System.out.print(" a");
if (i < 10) System.out.print(0);
System.out.println( i + " * " + weights[i]);
}
System.out.println(" bias: " + weights[i]);
inputSize = testPerceptronInput.size();
outputs = new int[inputSize];
double[][] z = initializeOutput(testPerceptronInput, globoDictSize, outputs);
test_output = Prcptrn_CalcOutpt.calculateOutput(THETA, weights, z, 1);
System.out.println("class = " + test_output);
}
static double[][] initializeOutput( Map<String, int[]> perceptronInput,
int size,
int[] outputs)
{
final int inputSize = perceptronInput.size();
final double[][] a = new double[size][inputSize];
// 2d array for features
int[][] feature_matrix = new int[inputSize][size];
String[] output_label = new String[inputSize];
int x = 0;
for (Entry<String, int[]> entry : perceptronInput.entrySet())
{
int[] container = entry.getValue();
for (int j = 0; j < container.length; j++)
{
feature_matrix[x][j] = container[j];
output_label[x] = String.valueOf(entry.getKey());
}
x++;
}
for (x = 0; x < inputSize; x++)
{
for (int i = 0; i < a.length; i++)
{
a[i][x] = feature_matrix[x][i];
}
outputs[x] = output_label[x].equals(FILEPATH) ? 1 : 0;
}
return a;
}
public static double randomNumber(int min , int max) {
DecimalFormat df = new DecimalFormat("#.####");
double d = min + Math.random() * (max - min);
String s = df.format(d);
double x = Double.parseDouble(s);
return x;
}
这是Prcptrn_CalcOutpt.calculateOutput
:
static int calculateOutput(int theta, double[] weights, double[][] a, int index)
{
double sum = 0;
int i;
for (i = 0; i < a.length; i++)
{
sum += weights[i] * a[i][index];
}
sum += weights[i];
return (sum >= theta) ? 1 : 0;
}