查看原文
其他

PMI点互信息计算

2018-03-12

作者 大邓

点互信息PMI(Pointwise Mutual Information)这个指标来衡量两个事物之间的相关性(比如两个词)。

在概率论中,我们知道,如果x跟y相互独立,则p(x,y)=p(x)p(y)

二者相关性越大,则p(x,y)就相比于p(x)p(y)越大。用后面的式子可能更好理解,在y出现的情况下x出现的条件概率p(x|y)除以x本身出现的概率p(x),自然就表示x跟y的相关程度。

 

例子:

举个自然语言处理中的例子来说,我们想衡量like这个词的极性(正向情感还是负向情感)。我们可以预先挑选一些正向情感的词,比如good。然后我们算like跟good的PMI,即: 

其中,

公式中的变量含义
p(like)表示like在语料库中出现的概率(出现次数除以总词数N)
p(like,good)表示like跟good在一句话中同时出现的概率(like跟good同时出现的次数除以N的平方)。
PMI(like,good)该式子越大表示like的正向情感倾向就越明显。

在stackoverflow中找到pmi实现的代码

from nltk.collocations import BigramAssocMeasures,BigramCollocationFinder

from
nltk.tokenize import word_tokenize text = "this is a foo bar bar black sheep  foo bar bar black sheep foo bar bar black sheep shep bar bar black sentence"

words = word_tokenize(text)

bigram_measures = BigramAssocMeasures()

finder = BigramCollocationFinder.from_words(words)

for row in finder.score_ngrams(bigram_measures.pmi):
   print(row)
(('is', 'a'), 4.523561956057013) (('this', 'is'), 4.523561956057013) (('a', 'foo'), 2.938599455335857) (('sheep', 'shep'), 2.938599455335857) (('black', 'sheep'), 2.5235619560570135) (('black', 'sentence'), 2.523561956057013) (('sheep', 'foo'), 2.3536369546147005) (('bar', 'black'), 1.523561956057013) (('foo', 'bar'), 1.523561956057013) (('shep', 'bar'), 1.523561956057013) (('bar', 'bar'), 0.5235619560570131)

好了,下面写一个完整的代码

实现以下功能:

  1. 读取txt、xls、xlsx文件的数据(其中excel形式的数据,其数据是存储在某一列)

  2. 对文本数据进行分词、英文小写化、英文词干化、去停用词

  3. 按照两元语法模式,计算所有文本两两词语的pmi值

  4. 将pmi值保存到csv文件中

完整代码

import re
import csv
import jieba
import pandas as pd
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.collocations import BigramAssocMeasures, BigramCollocationFinder


def chinese(text):    """    对中文数据进行处理,并将计算出的pmi保存到"中文pmi计算.csv"    """    content = ''.join(re.findall(r'[\u4e00-\u9fa5]+', text))        words = jieba.cut(content)        words = [w for w in words if len(w)>1]        bigram_measures = BigramAssocMeasures()        finder = BigramCollocationFinder.from_words(words)        with open('中文pmi计算.csv','a+',encoding='gbk',newline='') as csvf:            writer = csv.writer(csvf)                writer.writerow(('word1','word2','pmi_score'))                for row in finder.score_ngrams(bigram_measures.pmi):                    data = (*row[0],row[1])            try:                writer.writerow(data)            except:                pass



def english(text):    """    对英文数据进行处理,并将计算出的pmi保存到"english_pmi_computer.csv"    """        stopwordss = set(stopwords.words('english'))
   stemmer = nltk.stem.snowball.SnowballStemmer('english')        tokenizer = nltk.tokenize.RegexpTokenizer('\w+')        words = tokenizer.tokenize(text)        words = [w for w in words if not w.isnumeric()]        words = [w.lower() for w in words]        words = [stemmer.stem(w) for w in words]        words = [w for w in words if w not in stopwordss]        bigram_measures = BigramAssocMeasures()        finder = BigramCollocationFinder.from_words(words)        with open('english_pmi_computer.csv','a+',encoding='gbk',newline='') as csvf:            writer = csv.writer(csvf)                writer.writerow(('word1','word2','pmi_score'))                for row in finder.score_ngrams(bigram_measures.pmi):                    data = (*row[0],row[1])            try:                writer.writerow(data)            except:                pass



def pmi_score(file,lang,column='数据列'):    """    计算pmi    :param file: 原始文本数据文件    :param lang: 数据的语言,参数为chinese或english    :param column: 如果文件为excel形式的文件,column为excel中的数据列    """    #读取数据    text = ''    if 'csv' in file:        df = pd.read_csv(file)        rows = df.iterrows()        for row in rows:            text += row[1][column]    elif ('xlsx' in file) or ('xls' in file):        df = pd.read_excel(file)        rows = df.iterrows()        for row in rows:            text += row[1][column]    else:        text = open(file).read()    #对该语言的文本数据计算pmi    globals()[lang](text)



#计算pmi
pmi_score(file='test.txt',lang='chinese')

test.txt数据来自4000+场知乎live的简介,pmi部分计算结果截图。

pmi计算结果是从大到小输出的。从中可以看到,pmi越大,两个词语更有感情,更搭。

 而当翻看最后面的组合,pmi已经沦为负值,两个词语间关系已经不大了。 


文本处理分析

文本数据相似度的度量

对于中文,nltk能做哪些事情

gensim:用Word2Vec进行文本分析 

RAKE:快速自动抽取关键词算法

基于共现发现人物关系的python实现

用pyecharts制作词云图

留在网上的每个字,都在泄露你的身份


数据采集

【视频讲解】Scrapy递归抓取简书用户信息

【实战视频】使用scrapy写爬虫-爬知乎live

如何将html中的表格数据保存下来

美团商家信息采集神器

gevent:异步理论与实战  

轻盈高效的异步访问库grequests库

selenium驱动器配置详解

爬虫神器PyQuery的使用方法

简易SQLite3数据库学习

当爬虫遭遇验证码,怎么办  

js2xml:将javascript字符串转换为xml  

extruct提取结构化数据


数据结构

优雅简洁的列表推导式

Get小技巧等分列表

如何对数据进行各种排序?

数据结构:队列与堆栈 

else除了跟if很搭,你还知道其他的关键词吗?

杂文

Python通过字符串调用函数

Python圈中的符号计算库-Sympy

Python中处理日期时间库的使用方法 

三分钟掌握文件格式识别

为什么你要为2019,而不是2018做计划?

2017年度15个最好的数据科学领域Python库

迅雷不给力,我DIY了个下载器

计算运行时间-装饰器实现

花十分钟,给爱机安装个MongoDB

使用Python登录QQ邮箱发送QQ邮件

WTF Python: 开启你的懵逼模式

8行代码实现微信聊天机器人


代码及数据下载

链接: https://pan.baidu.com/s/1PvZMA9tkrL2BSccv15Eqmw 密码: yp9j




    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存