2013-03-27 10 views
5

Ho bisogno di fare analisi del sentimento su alcuni file CSV contenenti tweet. Sto usando SentiWordNet per fare l'analisi dei sentimenti.Come utilizzare SentiWordNet

Ho ottenuto il seguente codice di esempio java che hanno fornito sul loro sito. Non sono sicuro di come usarlo. Il percorso del file csv che voglio analizzare è C:\Users\MyName\Desktop\tweets.csv. Il percorso di SentiWordNet_3.0.0.txt è C:\Users\MyName\Desktop\SentiWordNet_3.0.0\home\swn\www\admin\dump\SentiWordNet_3.0.0_20130122.txt. Sono nuovo di java, pls help, grazie! Il collegamento al codice java di esempio riportato di seguito è this.

import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Set; 
import java.util.Vector; 

public class SWN3 { 
    private String pathToSWN = "data"+File.separator+"SentiWordNet_3.0.0.txt"; 
    private HashMap<String, String> _dict; 

    public SWN3(){ 

     _dict = new HashMap<String, String>(); 
     HashMap<String, Vector<Double>> _temp = new HashMap<String, Vector<Double>>(); 
     try{ 
      BufferedReader csv = new BufferedReader(new FileReader(pathToSWN)); 
      String line = "";   
      while((line = csv.readLine()) != null) 
      { 
       String[] data = line.split("\t"); 
       Double score = Double.parseDouble(data[2])-Double.parseDouble(data[3]); 
       String[] words = data[4].split(" "); 
       for(String w:words) 
       { 
        String[] w_n = w.split("#"); 
        w_n[0] += "#"+data[0]; 
        int index = Integer.parseInt(w_n[1])-1; 
        if(_temp.containsKey(w_n[0])) 
        { 
         Vector<Double> v = _temp.get(w_n[0]); 
         if(index>v.size()) 
          for(int i = v.size();i<index; i++) 
           v.add(0.0); 
         v.add(index, score); 
         _temp.put(w_n[0], v); 
        } 
        else 
        { 
         Vector<Double> v = new Vector<Double>(); 
         for(int i = 0;i<index; i++) 
          v.add(0.0); 
         v.add(index, score); 
         _temp.put(w_n[0], v); 
        } 
       } 
      } 
      Set<String> temp = _temp.keySet(); 
      for (Iterator<String> iterator = temp.iterator(); iterator.hasNext();) { 
       String word = (String) iterator.next(); 
       Vector<Double> v = _temp.get(word); 
       double score = 0.0; 
       double sum = 0.0; 
       for(int i = 0; i < v.size(); i++) 
        score += ((double)1/(double)(i+1))*v.get(i); 
       for(int i = 1; i<=v.size(); i++) 
        sum += (double)1/(double)i; 
       score /= sum; 
       String sent = "";    
       if(score>=0.75) 
        sent = "strong_positive"; 
       else 
       if(score > 0.25 && score<=0.5) 
        sent = "positive"; 
       else 
       if(score > 0 && score>=0.25) 
        sent = "weak_positive"; 
       else 
       if(score < 0 && score>=-0.25) 
        sent = "weak_negative"; 
       else 
       if(score < -0.25 && score>=-0.5) 
        sent = "negative"; 
       else 
       if(score<=-0.75) 
        sent = "strong_negative"; 
       _dict.put(word, sent); 
      } 
     } 
     catch(Exception e){e.printStackTrace();}   
    } 

    public String extract(String word, String pos) 
    { 
     return _dict.get(word+"#"+pos); 
    } 
} 

Nuovo codice:

public class SWN3 { 
     private String pathToSWN = "C:\\Users\\MyName\\Desktop\\SentiWordNet_3.0.0\\home\\swn\\www\\admin\\dump\\SentiWordNet_3.0.0.txt"; 
    private HashMap<String, String> _dict; 

    public SWN3(){ 

     _dict = new HashMap<String, String>(); 
     HashMap<String, Vector<Double>> _temp = new HashMap<String, Vector<Double>>(); 
     try{ 
      BufferedReader csv = new BufferedReader(new FileReader(pathToSWN)); 
      String line = "";   
      while((line = csv.readLine()) != null) 
      { 
       String[] data = line.split("\t"); 
       Double score = Double.parseDouble(data[2])-Double.parseDouble(data[3]); 
       String[] words = data[4].split(" "); 
       for(String w:words) 
       { 
        String[] w_n = w.split("#"); 
        w_n[0] += "#"+data[0]; 
        int index = Integer.parseInt(w_n[1])-1; 
        if(_temp.containsKey(w_n[0])) 
        { 
         Vector<Double> v = _temp.get(w_n[0]); 
         if(index>v.size()) 
          for(int i = v.size();i<index; i++) 
           v.add(0.0); 
         v.add(index, score); 
         _temp.put(w_n[0], v); 
        } 
        else 
        { 
         Vector<Double> v = new Vector<Double>(); 
         for(int i = 0;i<index; i++) 
          v.add(0.0); 
         v.add(index, score); 
         _temp.put(w_n[0], v); 
        } 
       } 
      } 
      Set<String> temp = _temp.keySet(); 
      for (Iterator<String> iterator = temp.iterator(); iterator.hasNext();) { 
       String word = (String) iterator.next(); 
       Vector<Double> v = _temp.get(word); 
       double score = 0.0; 
       double sum = 0.0; 
       for(int i = 0; i < v.size(); i++) 
        score += ((double)1/(double)(i+1))*v.get(i); 
       for(int i = 1; i<=v.size(); i++) 
        sum += (double)1/(double)i; 
       score /= sum; 
       String sent = "";    
       if(score>=0.75) 
        sent = "strong_positive"; 
       else 
       if(score > 0.25 && score<=0.5) 
        sent = "positive"; 
       else 
       if(score > 0 && score>=0.25) 
        sent = "weak_positive"; 
       else 
       if(score < 0 && score>=-0.25) 
        sent = "weak_negative"; 
       else 
       if(score < -0.25 && score>=-0.5) 
        sent = "negative"; 
       else 
       if(score<=-0.75) 
        sent = "strong_negative"; 
       _dict.put(word, sent); 
      } 
     } 
     catch(Exception e){e.printStackTrace();}   
    } 

    public Double extract(String word) 
    { 
     Double total = new Double(0); 
     if(_dict.get(word+"#n") != null) 
      total = _dict.get(word+"#n") + total; 
     if(_dict.get(word+"#a") != null) 
      total = _dict.get(word+"#a") + total; 
     if(_dict.get(word+"#r") != null) 
      total = _dict.get(word+"#r") + total; 
     if(_dict.get(word+"#v") != null) 
      total = _dict.get(word+"#v") + total; 
     return total; 
    } 

    public String classifytweet(){ 
     String[] words = twit.split("\\s+"); 
     double totalScore = 0, averageScore; 
     for(String word : words) { 
      word = word.replaceAll("([^a-zA-Z\\s])", ""); 
      if (_sw.extract(word) == null) 
       continue; 
      totalScore += _sw.extract(word); 
     } 
     Double AverageScore = totalScore; 

     if(averageScore>=0.75) 
      return "very positive"; 
     else if(averageScore > 0.25 && averageScore<0.5) 
      return "positive"; 
     else if(averageScore>=0.5) 
      return "positive"; 
     else if(averageScore < 0 && averageScore>=-0.25) 
      return "negative"; 
     else if(averageScore < -0.25 && averageScore>=-0.5) 
      return "negative"; 
     else if(averageScore<=-0.75) 
      return "very negative"; 
     return "neutral"; 
    } 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
    } 

risposta

7

Prima di tutto dall'inizio cancellando tutti i "spazzatura" in occasione della prima del file (che include la descrizione, l'istruzione, ecc ..)

Un possibile utilizzo è quello di cambiare SWN3 un rendere il metodo extract in esso restituisce un Double:

public Double extract(String word) 
{ 
    Double total = new Double(0); 
    if(_dict.get(word+"#n") != null) 
     total = _dict.get(word+"#n") + total; 
    if(_dict.get(word+"#a") != null) 
     total = _dict.get(word+"#a") + total; 
    if(_dict.get(word+"#r") != null) 
     total = _dict.get(word+"#r") + total; 
    if(_dict.get(word+"#v") != null) 
     total = _dict.get(word+"#v") + total; 
    return total; 
} 

Quindi, assegnando una stringa che si desidera taggare, è possibile dividerla in modo che abbia solo parole (senza segni e caratteri sconosciuti) e utilizzando il risultato restituito dal metodo extract su ogni parola, è possibile decidere qual è il peso medio della stringa:

String[] words = twit.split("\\s+"); 
double totalScore = 0, averageScore; 
for(String word : words) { 
    word = word.replaceAll("([^a-zA-Z\\s])", ""); 
    if (_sw.extract(word) == null) 
     continue; 
    totalScore += _sw.extract(word); 
} 
verageScore = totalScore; 

if(averageScore>=0.75) 
    return "very positive"; 
else if(averageScore > 0.25 && averageScore<0.5) 
    return "positive"; 
else if(averageScore>=0.5) 
    return "positive"; 
else if(averageScore < 0 && averageScore>=-0.25) 
    return "negative"; 
else if(averageScore < -0.25 && averageScore>=-0.5) 
    return "negative"; 
else if(averageScore<=-0.75) 
    return "very negative"; 
return "neutral"; 

Ho trovato questo modo più semplice e funziona bene per me.


UPDATE:

ho cambiato _dict-_dict = new HashMap<String, Double>(); quindi avrà una chiave e un valore StringDouble.

Così ho sostituito _dict.put(word, sent); auguro _dict.put(word, score);

+0

Ciao, grazie per la risposta, non sono ancora chiaro su alcune parti. Cosa significa questo? if (_dict.get (word + "# r")! = null) # n, # a, # r, # v? Grazie! – Belgarion

+1

Se osservate la prima colonna del file, noterete queste lettere (che sta per * noun *, * verb * ..) quindi dovreste coprire tutti i casi. – Maroun

+1

Ah capisco. Ho ancora bisogno di un po 'più di aiuto, dove posso inserire il mio link nel mio file tweet.csv? C: \ Users \ MyName \ Desktop \ tweets.csv Ho incollato il mio codice aggiornato sopra, sentitevi liberi di modificarlo, grazie! – Belgarion

0

per questo si dovrebbe scrivere la funzione principale, in quanto forniscono il percorso di csv, parole estratto da esso. e quindi chiama la funzione di estrazione inviando la parola e la sua posizione.