import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; public class TFIDF { public static void main(String[] args) { List documents = new ArrayList(); for (File document: new File("texts").listFiles()) if (document.getName().endsWith(".txt")) documents.add(document); analysis(documents, 8); } public static void analysis(List documents, int number) { // computes raw frequency of terms in each document Map> frequency = new HashMap>(); for (File document: documents) try { frequency.put(document, frequency(document)); } catch (IOException e) { e.printStackTrace(); } // computes inverse document frequency over all documents Map inverseDocumentFrequency = inverseDocumentFrequency(frequency); for (File document: documents) { // computes term frequency of considered document Map termFrequency = termFrequency(frequency.get(document)); // computes TF-IDF of terms in considered document Map TFIDF = termFrequencyInverseDocumentFrequency(termFrequency, inverseDocumentFrequency); // finds top TF-IDF terms in considered document List terms = topTerms(TFIDF, number); // prints top TF-IDF terms in considered document System.out.format("%16s | '%s'\n", "Document", document.getName()); for (String term: terms) System.out.format("%16s | %.8f\n", "'" + term + "'", TFIDF.get(term)); System.out.println(); } } public static List topTerms(Map values, int number) { List terms = new ArrayList(values.keySet()); Collections.sort(terms, new Comparator() { @Override public int compare(String first, String second) { if (values.get(first).doubleValue() < values.get(second).doubleValue()) return 1; else if (values.get(first).doubleValue() == values.get(second).doubleValue()) return 0; return -1; } }); return terms.subList(0, number); } public static Map frequency(File document) throws IOException { Map frequency = new HashMap(); BufferedReader reader = new BufferedReader(new FileReader(document)); String line; while ((line = reader.readLine()) != null) { String[] terms = line.toLowerCase().replaceAll("[^a-zčšžA-ZČŠŽ]", " ").split(" "); for (String term: terms) if (term.length() > 0) if (frequency.containsKey(term)) frequency.put(term, frequency.get(term) + 1); else frequency.put(term, 1); } reader.close(); return frequency; } public static Map termFrequency(Map frequency) { int maximum = 0; for (int value: frequency.values()) if (value > maximum) maximum = value; Map termFrequency = new HashMap(); for (String term: frequency.keySet()) termFrequency.put(term, 0.5 + 0.5 * frequency.get(term) / maximum); return termFrequency; } public static Map inverseDocumentFrequency(Map> frequency) { Map inverseDocumentFrequency = new HashMap(); for (File file: frequency.keySet()) for (String term: frequency.get(file).keySet()) if (!inverseDocumentFrequency.containsKey(term)) { int documents = 0; for (File document: frequency.keySet()) if (frequency.get(document).containsKey(term)) documents++; inverseDocumentFrequency.put(term, Math.log(1.0 * frequency.size() / documents)); } return inverseDocumentFrequency; } public static Map termFrequencyInverseDocumentFrequency(Map termFrequency, Map inverseDocumentFrequency) { Map TFIDF = new HashMap(); for (String term: termFrequency.keySet()) TFIDF.put(term, termFrequency.get(term) * inverseDocumentFrequency.get(term)); return TFIDF; } }