You shall know a word by the company it keeps.就是说我们人类可以通过上下文的含义来理解某一单词含义。 比如下边两个句子,人类看完之后就能直接知道两个杜鹃指的是哪个。
所以John Rupert Firth提出我们可以使用词的上下文分布进行词的表示。
import numpy as np
M = np.array([[0, 2, 1, 1, 1, 1, 1, 2, 1, 3],
[2, 0, 1, 1, 1, 0, 0, 1, 1, 2],
[1, 1, 0, 1, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 1, 0, 1, 0, 1],
[2, 1, 0, 0, 0, 1, 1, 0, 1, 1],
[1, 1, 0, 0, 0, 0, 0, 1, 0, 1],
[3, 2, 1, 1, 1, 1, 1, 2, 1, 0]])
np.set_printoptions(3)
def pmi(M, positive=True):
# 计算出每个词出现的次数,得到一个向量,每个值都是一个词出现的次数
single = M.sum(axis=0)
# 计算元素出现的总次数
total = single.sum()
# 这样计算得到的是 A次数*B次数/总次数
expected = np.outer(single,single) / total
# 这一步看代码后边的解析
M = M / expected
# 计算log2
with np.errstate(divide='ignore'):
M = np.log(M)
# 将M中的负无穷设置为0
M[np.isinf(M)] = 0.0
#PPMI 将M中的负数设置为0
if positive:
M[M < 0] = 0.0
return M
M_pmi = pmi(M)
print(M_pmi)
补充解析:
expected = np.outer(row_totals, col_totals) / total这一步中得到的是$\frac{A出现的次数\times B出现次数}{所有元素数量}$ 。
小学知识 除以一个分数等于乘以它的倒数,所以这一步是M = M / expected。
也是这两行代码借助矩阵实现并行计算,不用for循环挨个元素算。
np.outer是计算两个向量的外积。
给你两个向量a = [a0, a1, ..., aM] 和b = [b0, b1, ..., bN]
内积计算是一个数,等于a0*b0 + a1*b1 + ... + aN*bN
外积是一个矩阵:
[[a0*b0 a0*b1 ... a0*bN ]
[a1*b0 ...
[ ...
[aM*b0 .......... aM*bN ]]
比如
vec = np.array([1,2,3])
inn = np.vdot(vec,vec)
out = np.outer(vec,vec)
print('vec = ', vec)
print('内积 = ',inn)
print('外积 = ',out)
结果是:
vec = [1 2 3] 内积 = 14 外积 = [[1 2 3] $\quad\quad\quad$[2 4 6] $\quad\quad\quad$[3 6 9]]
with np.errstate(divide='ignore')
因为我们的矩阵中有0,因为$\log(0)=-\infty$,所以计算log的时候会有一个警告divide by zero encountered in log。
这里用with np.errstate(divide='ignore')包裹住M = np.log(M)就是让他忽略这一步操作的警告。
np改torch即可。主要区别在于做log计算那里。
pytorch中不会有这个log(0)的警告,pytorch 中也没有errstate方法。
import torch
M = torch.Tensor([[0, 2, 1, 1, 1, 1, 1, 2, 1, 3],
[2, 0, 1, 1, 1, 0, 0, 1, 1, 2],
[1, 1, 0, 1, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 1, 0, 1, 0, 1],
[2, 1, 0, 0, 0, 1, 1, 0, 1, 1],
[1, 1, 0, 0, 0, 0, 0, 1, 0, 1],
[3, 2, 1, 1, 1, 1, 1, 2, 1, 0]])
torch.set_printoptions(3)
def pmi(M, positive=True):
single = M.sum(axis=0)
total = single.sum()
expected = torch.outer(single, single) / total
M = M / expected
# pytorch中不会有这个log(0)的警告,pytorch 中也没有errstate方法
M = torch.log(M)
M[torch.isinf(M)] = 0.0
if positive:
M[M < 0] = 0.0
return M
M_pmi = pmi(M)
print(M_pmi)
import numpy as np
M = np.array([[0, 2, 1, 1, 1, 1, 1, 2, 1, 3],
[2, 0, 1, 1, 1, 0, 0, 1, 1, 2],
[1, 1, 0, 1, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 0, 1, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 0, 0, 0, 0, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 1, 0, 1, 0, 1],
[2, 1, 0, 0, 0, 1, 1, 0, 1, 1],
[1, 1, 0, 0, 0, 0, 0, 1, 0, 1],
[3, 2, 1, 1, 1, 1, 1, 2, 1, 0]])
np.set_printoptions(3)
def pmi(M, positive=True):
# 因为是对称矩阵,其实这俩的值完全是一样的。
col_totals = M.sum(axis=0)
row_totals = M.sum(axis=1)
# 计算元素出现的总次数
total = col_totals.sum()
# 这样计算得到的是 A次数*B次数/总次数
expected = np.outer(row_totals, col_totals) / total
# 实现并行计算,不用for挨个元素算了
M = M / expected
# 计算log2
with np.errstate(divide='ignore'):
M = np.log(M)
M[np.isinf(M)] = 0.0
if positive:
M[M < 0] = 0.0
return M
M_pmi = pmi(M)
print(M_pmi)
左边是M,右边是M_pmi。
用个例子计算一下相似度:
可以看到在PPMI之前 语言 和 机器 的相似度为0.671,PPMI之后变为0.207。
使用PPMI明显降低了不相干词汇的相似度。
def cos(a,b):
f1 = np.vdot(a,b)
f2 = np.vdot(a,a)**(1/2)
f3 = np.vdot(b,b)**(1/2)
return f1/(f2*f3)
print('\nPPMI前:')
print('语言 = ', M[3])
print('机器 = ', M[8])
print('余弦相似度 = ', cos(M[3], M[8]))
print('\nPPMI后:')
print('语言 = ', M_pmi[3])
print('机器 = ', M_pmi[8])
print('余弦相似度 = ', cos(M_pmi[3], M_pmi[8]))
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和
相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声
首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有, 也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我遇到了这个奇怪的错误.../Users/gideon/Documents/ca_ruby/rubytactoe/lib/player.rb:13:in`gets':Isadirectory-spec(Errno::EISDIR)player_spec.rb:require_relative'../spec_helper'#theuniverseisvastandinfinite...itcontainsagame....butnoplayersdescribe"tictactoegame"docontext"theplayerclass"doit"musthaveahumanplay
原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,
我有两个文本文件,master.txt和926.txt。如果926.txt中有一行不在master.txt中,我想写入一个新文件notinbook.txt。我写了我能想到的最好的东西,但考虑到我是一个糟糕的/新手程序员,它失败了。这是我的东西g=File.new("notinbook.txt","w")File.open("926.txt","r")do|f|while(line=f.gets)x=line.chompifFile.open("master.txt","w")do|h|endwhile(line=h.gets)ifline.chomp!=xputslineendende