用Python计算SentiWordNet得分

6

我一直在研究与Twitter情感分析相关的工作。我对Python编程有一些了解。由于我的研究涉及到编码,因此我已经对如何使用Python分析情绪进行了一些研究,以下是我所做的进展: 1. 对推文进行分词 2. 对分词进行词性标注 剩下的部分就是计算情感的积极和消极,这是我现在面临的问题,需要您的帮助。

以下是我的代码示例:

import nltk
sentence = "Iphone6 camera is awesome for low light "
token = nltk.word_tokenize(sentence)
tagged = nltk.pos_tag(token)

因此,我想问是否有人能帮助我展示/指导使用Python编写有关SentiWordNet的示例,以计算已经进行POS标记的推文的积极和消极得分。提前感谢。

嗨,我不知道这能有多大帮助,因此将其添加为注释。请尝试以下链接:http://www.nltk.org/howto/sentiment.html 和 http://www.nltk.org/api/nltk.sentiment.html - Vipul
4个回答

24

您的问题不太明确。您是需要使用Sentiwordnet的指南吗?如果是,请查看此链接,

http://www.nltk.org/howto/sentiwordnet.html

由于您已经对单词进行了分词和词性标注,现在您只需要使用以下语法即可,

swn.senti_synset('breakdown.n.03')

分解这个论点:

  • 'breakdown' = 您需要评分的单词。
  • 'n' = 词性
  • '03' = 用法(01 表示最常见用法,数字越高表示使用频率越低)

因此,对于标记数组中的每个元组,请创建上述字符串并将其传递给 senti_synset 函数,以获取该单词的正面、负面和客观得分。

注意:POS 标签器给出的标签与 senti_synset 接受的标签不同。请使用以下内容将其转换为 synset 符号。

n - NOUN 
v - VERB 
a - ADJECTIVE 
s - ADJECTIVE SATELLITE 
r - ADVERB 

(感谢Using Sentiwordnet 3.0提供以上标注)

话虽如此,使用Sentiwordnet进行Twitter情感分析通常不是一个好主意,以下是原因:

推特充满了拼写错误和非词典词语,而Sentiwordnet经常无法识别。为了解决这个问题,您可以在对推文进行pos标记之前对其进行词形还原/词干提取,或者使用机器学习分类器,例如朴素贝叶斯,其中NLTK具有内置函数。至于分类器的训练数据集,要么手动注释数据集,要么使用预先标记的数据集,例如Sentiment140语料库。

如果您不想实际执行情感分析但需要给定推文的情感标签,则始终可以使用Sentiment140 API来实现此目的。


1
关于如何使用分类器和Sentiment140数据集的好教程,请查看此链接:链接有关词干提取和词形还原,请查看此链接:https://dev59.com/HnRA5IYBdhLWcg3w8iol - Saravana Kumar
首先,非常感谢您详细的回答,Saravana。我很理解您在那里写的内容,但是我通常不太知道如何编写代码,因此我想请求您的帮助,如果可能的话,您可以帮我编写代码并在 POS 标记后运行该过程。这将对我进一步推进研究非常有启发性。import nltk sentence = "Iphone6 相机在低光下表现出色" token = nltk.word_tokenize(sentence) tagged = nltk.pos_tag(token) - pechdara

8

@Saravana Kumar有一个很好的回答。

为了添加详细的代码,我写下了这篇文章。我参考了链接https://nlpforhackers.io/sentiment-analysis-intro/

from nltk.corpus import wordnet as wn
from nltk.corpus import sentiwordnet as swn
from nltk.stem import PorterStemmer

def penn_to_wn(tag):
    """
    Convert between the PennTreebank tags to simple Wordnet tags
    """
    if tag.startswith('J'):
        return wn.ADJ
    elif tag.startswith('N'):
        return wn.NOUN
    elif tag.startswith('R'):
        return wn.ADV
    elif tag.startswith('V'):
        return wn.VERB
    return None

from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()

def get_sentiment(word,tag):
    """ returns list of pos neg and objective score. But returns empty list if not present in senti wordnet. """

    wn_tag = penn_to_wn(tag)
    if wn_tag not in (wn.NOUN, wn.ADJ, wn.ADV):
        return []

    lemma = lemmatizer.lemmatize(word, pos=wn_tag)
    if not lemma:
        return []

    synsets = wn.synsets(word, pos=wn_tag)
    if not synsets:
        return []

    # Take the first sense, the most common
    synset = synsets[0]
    swn_synset = swn.senti_synset(synset.name())

    return [swn_synset.pos_score(),swn_synset.neg_score(),swn_synset.obj_score()]


ps = PorterStemmer()
words_data = ['this','movie','is','wonderful']
# words_data = [ps.stem(x) for x in words_data] # if you want to further stem the word

pos_val = nltk.pos_tag(words_data)
senti_val = [get_sentiment(x,y) for (x,y) in pos_val]


print(f"pos_val is {pos_val}")
print(f"senti_val is {senti_val}")

输出

pos_val is [('this', 'DT'), ('movie', 'NN'), ('is', 'VBZ'), ('wonderful', 'JJ')]
senti_val is [[], [0.0, 0.0, 1.0], [], [0.75, 0.0, 0.25]]

如果使用CSV中的大数据,那么我只需要将CSV读入words_data吗? - Nadina
嗨,好问题。如果您的计算能力足够强大,则可以直接使用。如果遇到任何问题,我建议使用支持大数据的语言,如Python on Spark(PySpark)/ Scala等。 - shantanu pathak

0

这是我的解决方案:

from nltk.corpus import sentiwordnet as swn
from nltk.corpus import wordnet
from nltk.tag import pos_tag
from nltk.stem import WordNetLemmatizer

def get_wordnet_pos(word):
    tag = nltk.pos_tag([word])[0][1][0].upper()
    tag_dict = {"J": wordnet.ADJ,
                "N": wordnet.NOUN,
                "V": wordnet.VERB,
                "R": wordnet.ADV}
    return tag_dict.get(tag, wordnet.NOUN)

def get_sentiment_score_of_review(sentence):
    # 1. Tokenize
    tokens = nltk.word_tokenize(sentence)

    lemmatizer = WordNetLemmatizer()

    sentiment_score = 0.0
    for word in tokens:
        tag = get_wordnet_pos(word)
        item_res = lemmatizer.lemmatize(word, tag)
        if not item_res:
            continue
        
        synsets = wn.synsets(item_res, pos=tag)
        if len(synsets) == 0:
            print("Nope!", word)
            continue
        
        # Take the first, the most common
        synset = synsets[0]
        swn_synset = swn.senti_synset(synset.name())
        sentiment_score += swn_synset.pos_score() - swn_synset.neg_score()
        
    return sentiment_score

你的回答可以通过添加更多支持信息来改进。请[编辑]以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Ethan

-3

对于积极和消极情感,首先需要进行训练并训练模型。训练模型可以使用SVM,有一个开源库称为LibSVM可供使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接