用WordNet实现中文情感分析

来源:互联网 发布:淘宝中我的试用在哪里 编辑:程序博客网 时间:2024/05/16 12:35

1.      分析

中文的情感分析可以用词林做,词林有一大类(G类)对应心理活动,但是相对于wordnet还是太简单了.因此使用nltk+wordnet的方案,如下:

1)       中文分词:结巴分词

2)       中英文翻译:wordnet汉语开放词网,可从以下网址下载:
http://compling.hss.ntu.edu.sg/cow/

3)       情感分析:wordnet的sentiwordnet组件

4)       停用词:参考以下网页,另外加入常用标点符号
http://blog.csdn.net/u010533386/article/details/51458591

2.      代码

[python] view plain copy
  1. # encoding=utf-8  
  2. import jieba  
  3. import sys  
  4. import codecs  
  5.   
  6. reload(sys)  
  7.   
  8. import nltk  
  9. from nltk.corpus import wordnet as wn  
  10. from nltk.corpus import sentiwordnet as swn  
  11.   
  12. sys.setdefaultencoding('utf8')  
  13.   
  14. def doSeg(filename) :  
  15.     f = open(filename, 'r+')  
  16.     file_list = f.read()  
  17.     f.close()  
  18.   
  19.     seg_list = jieba.cut(file_list)  
  20.   
  21.     stopwords = []    
  22.     for word in open("./stop_words.txt""r"):    
  23.         stopwords.append(word.strip())   
  24.   
  25.     ll = []  
  26.     for seg in seg_list :  
  27.         if (seg.encode("utf-8"not in stopwords and seg != ' ' and seg != '' and seg != "\n" and seg != "\n\n"):  
  28.             ll.append(seg)  
  29.     return ll  
  30.   
  31. def loadWordNet():  
  32.     f = codecs.open("./cow-not-full.txt""rb""utf-8")  
  33.     known = set()  
  34.     for l in f:  
  35.         if l.startswith('#'or not l.strip():  
  36.             continue  
  37.         row = l.strip().split("\t")  
  38.         if len(row) == 3:  
  39.             (synset, lemma, status) = row   
  40.         elif len(row) == 2:  
  41.             (synset, lemma) = row   
  42.             status = 'Y'  
  43.         else:  
  44.             print "illformed line: ", l.strip()  
  45.         if status in ['Y''O' ]:  
  46.             if not (synset.strip(), lemma.strip()) in known:  
  47.                 known.add((synset.strip(), lemma.strip()))  
  48.     return known  
  49.   
  50. def findWordNet(known, key):  
  51.     ll = [];  
  52.     for kk in known:  
  53.         if (kk[1] == key):  
  54.              ll.append(kk[0])  
  55.     return ll  
  56.   
  57. def id2ss(ID):  
  58.     return wn._synset_from_pos_and_offset(str(ID[-1:]), int(ID[:8]))  
  59.   
  60. def getSenti(word):  
  61.     return swn.senti_synset(word.name())  
  62.   
  63. if __name__ == '__main__' :  
  64.     known = loadWordNet()  
  65.     words = doSeg(sys.argv[1])  
  66.   
  67.     n = 0  
  68.     p = 0  
  69.     for word in words:  
  70.       ll = findWordNet(known, word)  
  71.       if (len(ll) != 0):  
  72.           n1 = 0.0  
  73.           p1 = 0.0  
  74.           for wid in ll:  
  75.               desc = id2ss(wid)  
  76.               swninfo = getSenti(desc)  
  77.               p1 = p1 + swninfo.pos_score()  
  78.               n1 = n1 + swninfo.neg_score()  
  79.           if (p1 != 0.0 or n1 != 0.0):  
  80.               print word, '-> n ', (n1 / len(ll)), ", p ", (p1 / len(ll))  
  81.           p = p + p1 / len(ll)  
  82.           n = n + n1 / len(ll)  
  83.     print "n", n, ", p", p  

3.      待解决的问题

1)       结巴分词与wordnet chinese中的词不能一一对应
结巴分词虽然可以导入自定义的词典,但仍有些结巴分出的词,在wordnet找不到对应词义,比如"太后","童子",还有一些组合词如"很早已前","黄山"等等.大多是名词,需要进一步"学习".
临时的解决方案是:将其当作"专有名词"处理

2)       一词多义/一义多词
无论是情感分析,还是语义分析,中文或者英文,都需要解决词和义的对应问题.
临时的解决方案是:找到该词的所有语义,取其平均的情感值.另外,结巴也可判断出词性作为进一步参考.

3)       语义问题
语义问题是最根本的问题,一方面需要分析句子的结构,另外也和内容也有关,尤其是长文章,经常会使用"先抑后扬""对比分析",这样就比较难以判断感情色彩了.

4.      参考

1)       Learning lexical scales:WordNet and SentiWordNet
http://compprag.christopherpotts.net/wordnet.html

2)       SentiWordNet Interface
http://www.nltk.org/howto/sentiwordnet.html


原创粉丝点击