#java #double #normalization
#java #двойной #нормализация
Вопрос:
Я пытаюсь вычислить значения tfidf для файлов и сохранить их в матрице, значения tfidf, которые я хочу сначала нормализовать между 0 и 1. Но у меня проблема, первое значение, вычисленное после нормализации, равно NAN, как я могу исправить эту проблему.
Это то, что я сделал
double tf; //term frequency
double idf; //inverse document frequency
double tfidf = 0; //term frequency inverse document frequency
double minValue=0.0;
double maxValue=0;
File output = new File("E:/hsqldb-2.3.2/hsqldb-2.3.2/hsqldb/hsqldb/matrix.txt");
FileWriter out = new FileWriter(output);
mat= new String[termsDocsArray.size()][allTerms.size()];
int c=0; //for files
for (String[] docTermsArray : termsDocsArray) {
int count = 0;//for words
for (String terms : allTerms) {
tf = new TfIdf().tfCalculator(docTermsArray, terms);
idf = new TfIdf().idfCalculator(termsDocsArray, terms);
tfidf = tf * idf;
//System.out.print(terms "t" tfidf "t");
//System.out.print(terms "t");
tfidf = Math.round(tfidf*10000)/10000.0d;
tfidfList.add(tfidf);
maxValue=Collections.max(tfidfList);
tfidf=(tfidf-minValue)/(maxValue-minValue); //Normalization here
mat[c][count]=Double.toString(tfidf);
count ;
}
c ;
}
Это результат, который я получил
NaN 1.0 0.0 0.021
0.0 1.0 0.0 0.365 ... and others
только первое число равно NAN, также это число изначально является числом, которое повторяется много раз в матрице, но его значение не равно NAN
Пожалуйста, дайте мне несколько идей по устранению этой проблемы.
Спасибо
Ответ №1:
Вы делите на ноль. Это произойдет, когда первое значение, которое добавляется к tfidflist
is 0.0
.
Чтобы выполнить реальную нормализацию, вам, вероятно, придется сначала вычислить все возможные значения, затем вычислить минимальное / максимальное значение этих значений, а затем нормализовать все значения на основе этих минимальных / максимальных значений. Примерно:
// First collect all values and compute min/max on the fly
double minValue=Double.MAX_VALUE;
double maxValue=-Double.MAX_VALUE;
double values = new String[termsDocsArray.size()][allTerms.size()];
int c=0; //for files
for (String[] docTermsArray : termsDocsArray) {
int count = 0;//for words
for (String terms : allTerms) {
double tf = new TfIdf().tfCalculator(docTermsArray, terms);
double idf = new TfIdf().idfCalculator(termsDocsArray, terms);
double tfidf = tf * idf;
tfidf = Math.round(tfidf*10000)/10000.0d;
minValue = Math.min(minValue, tfidf);
maxValue = Math.max(maxValue, tfidf);
values[c][count]=tfidf;
count ;
}
c ;
}
// Then, create the matrix containing the strings of the normalized
// values (although using strings here seems like a bad idea)
c=0; //for files
for (String[] docTermsArray : termsDocsArray) {
int count = 0;//for words
for (String terms : allTerms) {
double tfidf = values[c][count];
tfidf=(tfidf-minValue)/(maxValue-minValue); //Normalization here
mat[c][count]=Double.toString(tfidf);
count ;
}
c ;
}
Комментарии:
1. Спасибо @Marco13.. пожалуйста, посмотрите на редактирование. Я попробовал то, что вы предлагаете, и у меня все та же проблема
2. @user1488019 Вы изменили код для вычисления минимального / максимального значения перед нормализацией? Просто добавьте строку
System.out.println("Dividing by " (maxValue-minValue));
перед нормализацией и убедитесь, что она никогда не делится на 03. Спасибо в другой раз @Marco13, но проблема не в самой операции. Я заметил, что первое число не берется (игнорируется)
4. @user1488019 Я не уверен, что вы имеете в виду, и можно ли ответить на этот вопрос здесь. Если это так, вы, вероятно, можете отредактировать исходный вопрос и добавить более подробное описание фактического вопроса…
Ответ №2:
Мое первое предположение заключается в том, что вы делите 0.0 на 0.0 — возможно, MaxValue, MinValue и tfidf равны нулю. Мой совет — поместить оператор печати непосредственно перед шагом нормализации — я предполагаю, что вы увидите там некоторые неожиданные значения.
Комментарии:
1. Спасибо @Robert. Я уже распечатал результаты до и после шага нормализации, и в этом нет ничего ненормального. пожалуйста, посмотрите на редактирование, которое я сделал для вопроса