最近在做文本匹配,想到了特征值的算法,自己写了一个文本计算算法。求批判。...


之前有个需求,就是比较2个文本是否相近。

 

最牛逼的方法就是用语义去分析,然后比较结果。可是这个性能是在不敢恭维,于是想起了以前做过的人脸识别,使用特征值去操作。

 

人脸识别当是时把图片转变为一维向量,然后计算特征值。最终发现,如果是文本计算特征值,把文本的字符串输入后,简单的简化为每个char自相乘,再相加 = 向量的模的平方。

 

例如:

 

HI = (char 72)(char 73). 

eigenValue = 72*72+73*73.

 

这样,IH的结果和HI就是一样了。 而且另外一个问题就是char的取值范围是0~255。如果对文本检测,那么很快就会超过了double的长度了。针对这些问题,我自己想到了一个算法。

 

ExpandedBlockStart.gif 代码
         public   static   double  GetStringEigenValue( string  value)
        {
            
if  ( string .IsNullOrEmpty(value))
                
return   0 ;

            
double  length  =  value.Length;

            
double  eigenvalue  =   0 ;

            
int  index  =   1 ;

            
foreach  ( char  str  in  value)
            {
                
double  strnum  =  ( double )str;

                eigenvalue 
+=  (strnum  *  strnum)  /   100000   *  index ++ ;
            }

            
// 计算由于每个位置添加了权重,导致最终值增加的值

            
double  weightfactor  =  (length  -   1 *   255   *   255   /   100000   +  (length  -   1 *  (length  -   2 *   255   *   255   /   2   /   100000 ;

            
if  (weightfactor  ==   0 )
                weightfactor 
=   1 ;

            weightfactor 
=  Math.Ceiling(Math.Log10(weightfactor));

            
if  (weightfactor  ==   0 )
                weightfactor 
=   1 ;

            eigenvalue 
/=  weightfactor;

            eigenvalue 
/=  length;

            
return  length  +  eigenvalue;
        }

 

 

 

这里简单说下原理,还是很简单白痴的。

 

1.  char的取值范围是0~255.那么 char相乘的最大值=  255*255 = 65025. 我为了每次都让特征值保持在小数,于是除以了10000.

eigenvalue += (strnum * strnum) / 100000 * index++

 

2. 考虑到字符串位置的问题,我每个字符串都乘以了位置权重 index,这样不同顺序的字符串结果就一定不同了。

eigenvalue += (strnum * strnum) / 100000 * index++

 

3. 可是由于每个字符运算的时候都添加了权重,导致了结果比没有添加权重的大了很多。大了多少?我就按照 65025这个等差数列去运算:

N* 65025 + N(N-1)* 65025 /2, N = length -1

double weightfactor = (length - 1* 255 * 255 / 100000 + (length - 1* (length - 2* 255 * 255 / 2 / 100000; 

4. 最后,我计算这个增加的额外值到底是10的多少次方(需要再缩小多少)。得到:

weightfactor = Math.Ceiling(Math.Log10(weightfactor));

 

5. 然后根据权重放大的倍数,就是特征值再缩小回小数部分:

eigenvalue /= weightfactor;

 

6. 由于特征值结果是每个位置的char相乘再相加,因此相加导致放大的倍数 = 255*255/100000*length的倍数。因此就是length。最终需要缩小到小数:

eigenvalue /= length; 

 

7. 为了保证不同长度的字符串可能计算出来的结果会一样,最终结果会再加上了字符串的长度。

return length + eigenvalue; 

 

最后这个值,就是代表了这个文本的特征值了。整数部分是长度,小数部分是相似度。

 

最后,请各位大牛们拍拍砖。。。。小弟数学不才,在此献丑了。 

转载于:https://www.cnblogs.com/zc22/archive/2010/09/05/1818540.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值