应用R语言实现信息熵距离算法.docx
《应用R语言实现信息熵距离算法.docx》由会员分享,可在线阅读,更多相关《应用R语言实现信息熵距离算法.docx(16页珍藏版)》请在冰豆网上搜索。
应用R语言实现信息熵距离算法
R语言实现46种距离算法
前言
距离算法是做数据挖掘常用的一类算法,距离算法有很多种,比如欧式距离、马氏距离、皮尔逊距离,距离算法主要应用在计算数据集之间关系。
本文用R语言来philentropy包,实现多种距离的算法,很多可能是大家完全没有听过的,让我们在开拓一下知识领域吧。
1.距离算法包philentropy
2.46种距离算法详解
3.距离函数的使用
1.距离算法包philentropy
在做距离算法调研时,无意中发了philentropy包。
它实现了46个不同距离算法和相似性度量,通过不同数据的相似度比较,为基础研究提供了科学基础。
philentropy包,为聚类、分类、统计推断、拟合优度、非参数统计、信息理论和机器学习提供了核心的计算框架,支持基于单变量或者多变量的概率函数的计算。
philentropy包主要包括了2种度量的计算方法,距离度量和信息度量。
本文介绍距离度量的使用,对于信息度量的使用,请参考文章R语言实现信息度量。
philentropy项目github地址:
本文的系统环境为:
∙Win1064bit
∙R:
3.4.2x86_64-w64-mingw32
安装philentropy包,非常简单,一条命令就可以了。
~R
>install.packages("philentropy")
>library(philentropy)
查看距离算法列表
>getDistMethods()
[1]"euclidean""manhattan""minkowski""chebyshev"
[5]"sorensen""gower""soergel""kulczynski_d"
[9]"canberra""lorentzian""intersection""non-intersection"
[13]"wavehedges""czekanowski""motyka""kulczynski_s"
[17]"tanimoto""ruzicka""inner_product""harmonic_mean"
[21]"cosine""hassebrook""jaccard""dice"
[25]"fidelity""bhattacharyya""hellinger""matusita"
[29]"squared_chord""squared_euclidean""pearson""neyman"
[33]"squared_chi""prob_symm""divergence""clark"
[37]"additive_symm""kullback-leibler""jeffreys""k_divergence"
[41]"topsoe""jensen-shannon""jensen_difference""taneja"
[45]"kumar-johnson""avg"
46个距离算法,有一些是我们常用的比如:
euclidean,manhattan,minkowski,pearson,cosine,squared_chi,其他的我也不知道,正好拓宽知识,好好学习一下。
philentropy包的函数,其实很简单,只有14个,大量的算法其实都已经被封装到distance()函数中,直接使用distance()函数就行完成各种算法的计算,让我们使用起来会非常方便。
我们来看一下,函数列表:
∙distance():
计算距离
∙getDistMethods(),获得距离算法列表
∙dist.diversity(),概率密度函数之间的距离差异
∙estimate.probability(),从计数向量估计概率向量
∙lin.cor(),线性相关性判断
∙H():
香农熵,Shannon’sEntropyH(X)
∙JE():
联合熵,Joint-EntropyH(X,Y)
∙CE():
条件熵,Conditional-EntropyH(X|Y)
∙MI():
互信息,Shannon’sMutualInformationI(X,Y)
∙KL():
KL散度,Kullback–LeiblerDivergence
∙JSD():
JS散度,Jensen-ShannonDivergence
∙gJSD():
通用JS散度,GeneralizedJensen-ShannonDivergence
∙binned.kernel.est(),实现了KernSmooth包提供的核密度估计函数的接口
从函数列表来看,主要分为3种类别的函数,第一类是距离测量的函数,包括distance(),
getDistMethods(),dist.diversity(),lin.cor()和estimate.probability()。
第二类是相关性分析,包括lin.cor()函数。
第三类是信息度量函数H(),JE(),CE(),MI(),KL(),JSD(),gJSD()。
信息度量函数的使用,请参考文章R语言实现信息度量。
2.46种算法详解
接下来,就让我们深入每个算法吧,从名字到公式,再到函数使用,最后到使用场景。
距离算法列表:
∙euclidean:
欧式距离,是一个通常采用的距离定义,在m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。
∙manhattan:
曼哈顿距离,用于几何空间度量,表示两个点在标准坐标系上的绝对轴距距离总和。
∙minkowski:
闵可夫斯基距离,是欧氏空间中的广义距离函数,其参数p值的不同代表着对空间不同的度量。
∙chebyshev:
切比雪夫距离,是向量空间中的一种度量,二个点之间的距离定义是其各坐标数值差绝对值的最大值。
∙sorensen:
测量每个样本单位,对单位总数的距离测量贡献度,广告用于生态学。
∙gower:
高尔距离,将向量空间缩放为规范化空间,可计算逻辑值,数字,文本的距离,距离结果为0到1之间的数字。
∙soergel:
测量每个样本单位,对最大值总数的距离测量贡献度。
∙kulczynski:
与soergel相反,测量每个样本单位,对最小值总数的距离测量贡献度。
∙canberra:
堪培拉距离,是矢量空间中的点对之间的距离的数值度量,它是L_1距离的加权版本。
∙lorentzian:
洛伦兹距离,绝对的差异并应用自然对数。
∙intersection:
交叉距离,最小轨道交叉距离,是天文学中用于评估天文物体之间潜在的近距离接近和碰撞风险的度量。
它被定义为两个物体的密切轨道的最近点之间的距离。
∙non-intersection:
非交叉距离
∙wavehedges:
波浪距离,
∙czekanowski:
∙motyka:
莫蒂卡方程,是czekanowski的一半。
∙kulczynski_s:
∙tanimoto:
是标准化内积的另一种变体。
∙ruzicka:
∙inner_product:
内部产品空间,计算两个向量的内积产生标量,有时称为标量积或点积。
∙harmonic_mean:
调和平均值。
∙cosine:
余弦距离,是用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小的度量。
∙hassebrook(PCE):
利用P•Q来测量能量的峰值,简称PCE。
∙jaccard:
杰卡德距离,用于计算样本间的相似度,分子是A和B的交集大小,分母是A和B的并集大小。
∙dice:
骰子
∙fidelity:
保真度,在量子信息理论中,保真度是两个量子态“接近”的度量。
∙bhattacharyya:
巴氏距离,测量两个概率分布的相似性。
∙hellinger:
海林格,用来度量两个概率分布的相似度,它是F散度的一种。
∙matusita:
∙squared_chord:
∙squared_euclidean:
欧式距离的平方
∙pearson:
皮尔森距离,分子是两个集合的交集大小,分母是两个集合大小的几何平均值,是余弦距离的一种变型。
∙neyman:
奈曼,
∙squared_chi:
∙prob_symm:
∙divergence:
散度,
∙clark:
克拉克,
∙additive_symm:
算术和几何平均散度.
∙kullback-leibler:
KL散度,用于计算相熵或信息偏差,是衡量两个分布(P、Q)之间的距离,越小越相似。
∙jeffreys:
杰弗里斯,J分歧。
∙k_divergence:
K散度,
∙topsoe:
托普索,是k_divergence加法的对称形式。
∙jensen-shannon:
詹森香农,是topsoe距离的一半。
∙jensen_difference:
∙taneja:
塔内加,计算算术和几何平均偏差。
∙kumar-johnson:
库马尔-约翰逊,
∙avg:
平均
由于精力和基础知识有限,对每一种算法还没有更深入的理解和使用,后面会继续补充。
这些距离的详细解释,请参考文章 http:
//csis.pace.edu/ctappert/dps/d861-12/session4-p2.pdf
这么多种的距离算法,其实可以分成8大距离家族,每个家族中不同的算法思路是类似的,可以通过变形或参数不同赋值,进行算法的相互转换。
L_pMinkowski家族,通过对Minkowski算法p值的不同赋值,可以转换成不同的算法,当p=1时Minkowski距离转为曼哈顿距离;当p=2变Minkowski距离转为欧氏距离;当p接近极限最大值时,Minkowski距离是转为切比雪夫距离。
L_1家族,用于准确的测量绝对差异的特征。
Intersection交叉距离家族,用于交叉点之间的相似度变换。
InterProduct 家族,几何空间的相似性度量,用于特定的P•Q 变量来计算。
Squared-chord 家族,在量子信息理论中,量子态“接近”的度量。
SquaredL_2 家族(X^2Squared 家族),以平方的欧几里得距离做为被除数。
香浓信息熵家族,信息熵偏差测量。
组合公式,利用多种算法思路,进行组合的距离测量方法。
3.距离函数的使用
了解了这么多的距离算法后,让我们来使用一下philentropy包强大的功能函数,把算法落地。
3.1distance()函数使用
distance()函数,用来计算两个概率密度函数之间的距离和相似度,上面所列出的所有的距离算法都被封装在了这个函数里。
distance()函数定义:
distance(x,method="euclidean",p=NULL,test.na=TRUE,unit="log",est.prob=NULL)
参数列表:
∙x,数值类型的向量或数据集
∙method,算法的名称
∙p,minkowski闵可夫斯基距离的p值,p=1为曼哈顿距离,p=2为欧氏距离,p取极限时是切比雪夫距离
∙test.na,检测数据集是否有NA值,不检测为FALSE,计算会快。
∙unit,对数化的单位,依赖于日志计算的距离
∙est.prob从计数估计概率,默认值为NULL
计算euclidean距离,用iris的数据集。
>library(magrittr)
#查看iris数据集
>head(iris)
Sepal.LengthSepal.WidthPetal.LengthPetal.WidthSpecies
15.13.51.40.2setosa
24.93.01.40.2setosa
34.73.21.30.2setosa
44.63.11.50.2setosa
55.03.61.40.2setosa
65.43.91.70.4setosa
计算第1个点(第1行)和第2个点(第2行)的euclidean距离,分别使用philentropy包的distance(),Stats包的dist(),和自己通过公式计算。
#使用distance()函数
>dat1<-iris[1:
2,-5]
>distance(dat1,method="euclidean")
Metric:
'euclidean'usingunit:
'log'.
euclidean
0.5385165
#再使用系统自带的dist()函数
>dist(dat1)
1
20.5385165
#公式计算
>(dat1[1,]-dat1[2,])^2%>%sum%>%sqrt
[1]0.5385165
3种方法,计算的结果是完全一致。
接下来,我们构建一个iris的距离矩阵,为了展示清楚,我们选iris的前6个点来计算距离。
分别使用distance()和dist()函数。
>dat2<-head(iris[,-5])
#距离矩阵
>distance(dat2)
Metric:
'euclidean'usingunit:
'log'.
v1v2v3v4v5v6
v10.00000000.53851650.5099020.64807410.14142140.6164414
v20.53851650.00000000.3000000.33166250.60827631.0908712
v30.50990200.30000000.0000000.24494900.50990201.0862780
v40.64807410.33166250.2449490.00000000.64807411.1661904
v50.14142140.60827630.5099020.64807410.00000000.6164414
v60.61644141.09087121.0862781.16619040.61644140.0000000
#下三角距离矩阵
>dist(dat2)
12345
20.5385165
30.50990200.3000000
40.64807410.33166250.2449490
50.14142140.60827630.50990200.6480741
60.61644141.09087121.08627801.16619040.6164414
验证后,我们就可以放心使用distance()函数。
通过对比实验,我们可以很快的学习并使用各种距离算法。
3.2dist.diversity()函数
dist.diversity()函数,用来计算所有距离的值。
由于有一些距离有对于数据集本身的要求,所以我们需要构建一个能适应所有距离算法的数据集。
#生成数据集,2个点,10个维度
>P<-1:
10/sum(1:
10)
>Q<-20:
29/sum(20:
29)
>x<-rbind(P,Q)
#打印数据集
>head(x)
[,1][,2][,3][,4][,5][,6][,7][,8]
P0.018181820.036363640.054545450.072727270.090909090.10909090.12727270.1454545
Q0.081632650.085714290.089795920.093877550.097959180.10204080.10612240.1102041
[,9][,10]
P0.16363640.1818182
Q0.11428570.1183673
使用dist.diversity()函数计算所有的距离。
>dist.diversity(x,p=2)
euclideanmanhattanminkowskichebyshevsorensen
0.128071300.352504640.128071300.063450830.17625232
gowersoergelkulczynski_dcanberralorentzian
0.035250460.299684540.427927932.099270950.34457827
intersectionnon-intersectionwavehedgesczekanowskimotyka
0.823747680.176252323.166578870.176252320.58812616
kulczynski_stanimotoruzickainner_productharmonic_mean
2.336842110.299684540.700315460.106122450.94948528
cosinehassebrookjaccarddicefidelity
0.934276410.866131030.133868970.071736110.97312397
bhattacharyyahellingermatusitasquared_chordsquared_euclidean
0.027243790.327878190.231844890.053752050.01640226
pearsonneymansquared_chiprob_symmdivergence
0.168144180.367424650.101029430.202058861.49843905
clarkadditive_symmkullback-leiblerjeffreysk_divergence
0.865574680.535568830.096529670.220150960.02922498
topsoejensen-shannonjensen_differencetanejakumar-johnson
0.052578670.026289330.026289330.028748410.62779644
avg
0.20797774
3.3estimate.probability()函数
estimate.probability()函数,采用数字计数来计算向量的估计概率。
estimate.probability()函数方法实现,目前只有一个方法实现,计算每个值占合计的比率,其实就是一种数据标准归的计算方法。
>estimate.probability
function(x,method="empirical")
{
if(!
is.element(method,c("empirical")))
stop("Pleasechooseavalidprobabilityestimationmethod.")
if(method=="empirical"){
return(x/sum(x))
}
}
>environment:
namespace:
philentropy<
我们新建一个向量,用estimate.probability()函数,来计算向量的估计概率。
#新建x1向量
>x1<-runif(100);head(x1)
[1]0.65987750.25884410.53299650.52948420.83313550.3326702
#计算估计概率
>x2<-estimate.probability(x1);head(x2)
[1]0.0138286750.0054244470.0111697020.0110960970.0174595430.006971580
#打印统计概率
>summary(x2)
Min.1stQu.MedianMean3rdQu.Max.
0.00021810.00448820.00963180.01000000.01535690.0206782
#画散点图
>plot(x1,x2)
从图中看到,整个数据分布在对角线上,x1为均匀分布生成的向量,x2为x1的估计概率,仅仅做了做数据值域进行了缩放,并没有影响数据的分布变化和线性特征,其实就是对数据做了一个标准化的过程。
3.4lin.cor()函数
lin.cor()函数,用来计算两个向量之间的线性相关,或计算矩阵的相关矩阵。
函数定义:
lin.cor(x,y=NULL,method="pearson",test.na=FALSE)
参数列表:
∙x,变量1
∙y,变量2,与x进行比较
∙method,相关性算法的名称,默认为pearson距离算法,支持5种算法分为是pearson,pearson2,sq_pearson,kendall,spearman
∙test.na,检测数据集是否有NA值,不检测为FALSE,计算会快。
相关性计算,最大值1为完全正相关,最小值-1为完全负相关,0为不相关。
我们来创建数据集,进行相关性的测试。
#创建向量x1,x2,x3
>x1<-runif(100)
>x2<-estimate.probability(x1)
>x3<-rnorm(100)
#判断x1,x2的相关性,pearson皮尔森相关系数
>lin.cor(x1,x2)
pearson
1
#判断x1,x3的相关性,pearson皮尔森相关系数
>lin.cor(x1,x3)
pearson
0.0852527
#判断x1,x3的相关性,pearson2皮尔森非集中的相关系数
>lin.cor(x1,x3,method='pearson2')
pearson2
0.01537887
#判断x1,x3的相关性,sq_pearson皮尔森平方的相关系数
>lin.cor(x1,x3,method='sq_pearson')
sq_pearson
0.00151915
#判断x1,x3的相关性,kendall肯德尔相关系数
>lin.cor(x1,x3,method='kendall')
kendall
0
#判断x1,x3的相关性,spearman斯皮尔曼相关系数
>lin.cor(x1,x3,method='spearman')
spearman
0
通过lin.cor()函数,可以快速进行线性相关性的验证,非常方便。
本文重点介绍了philentropy包,对于距离算法的定义和距离测量的函数的使用。
很多的距离算法我也是第一次学习,知识需要积累和总结,本文不完善的内容,后面我们