2

我正在存储一个在网站上的所有搜索中都使用过的关键字列表,并且在关键字字段中得到了很多随机字符串。这是我要返回的数据示例:

fRNPRXiPtjDrfTDKH
boom
Mule deer
gVXOFEzRWi
cbFXZcCoSiKcmrvs
Owner Financed ,owner Financed

我试图在 SQL 或 ColdFusion 中找到一种方法来确定某些内容是否具有有效的英文单词,或者它是否是一组随机字符。我已经尝试对 n-gram 分析进行一些挖掘,但似乎无法提出任何可以直接在我的服务器上运行的有用解决方案。

4

4 回答 4

3

更新:代码现在在 jsFiddle 上:http: //jsfiddle.net/ybanrab/s6Bs5/1/复制并粘贴一页新闻复制并粘贴到您的测试数据中可能会很有趣

我建议尝试分析各个角色相互跟随的概率。下面是一个我用 JavaScript 编写的示例,但应该很容易转换为 T-SQL 或 ColdFusion。

这个想法是你输入好的短语(语料库)并分析字母跟随其他字母的频率。如果你喂它“这么薄”,你会得到这样的东西:

{
 t:{h:3},
 h:{i:2,e:1},
 i:{s:1,n:1},
 s:{},
 n:{}
}

通过从您正在分析的数据中提供精心挑选的已知良好输入,您将获得最大的准确性,但您也可以通过简单的英语提供良好的结果。在下面的示例中,我正在计算它,但是一旦您对它感到满意,您显然可以存储它。

然后,您根据概率运行示例字符串以对其进行评分。此版本忽略大小写、单词首字母、长度等,但您也可以根据需要使用它们。然后,您只需要确定一个阈值分数并像这样进行过滤。

我相当肯定这种分析有一个名字,但我的 google-fu 今天很弱。您可以将下面的代码粘贴到脚本块中,以了解它的工作情况(或不工作)。

var corpus=["boom","Mule Deer", "Owner Financed ,owner Financed", "This is a valid String","The quick brown fox jumped over the lazy dog"];

var probs={};
var previous=undefined;

//Compute the probability of one letter following another
corpus.forEach(function(phrase){
    phrase.split(" ").forEach(function(word){
        word.toLowerCase().split("").forEach(function(chr){
            //set up an entry in the probabilities table
            if(!probs[chr]){
                probs[chr]={};
            }
            //If this isn't the first letter in the word, record this letter as following the previous one
            if(previous){
                if(!probs[previous][chr]){
                    probs[previous][chr]=0; 
                }
                probs[previous][chr]++;
            }
            //keep track of the previous character
            previous=chr;

        });
        //reset previous as we're moving onto a different word
        previous=undefined;
    })
});


function calculateProbability(suspect){
    var score=0;
    var previous=undefined;
    suspect.toLowerCase().split("").forEach(function(chr){
        if(previous && probs[previous] && probs[previous][chr]){
            //Add the score if there is one, otherwise zero
            score+=probs[previous][chr];
        }
        previous=chr;
    });
    return score/suspect.length;
}

console.log(calculateProbability("boom"));
console.log(calculateProbability("Mood"));
console.log(calculateProbability("Broom"));
console.log(calculateProbability("sajkdkas dak"));
于 2012-11-26T15:51:10.440 回答
2

最好的办法是对照频率列表检查你的单词:字典不起作用,因为它们不包含语法变形、专有名词、复合词和一大堆其他有效的东西。

对 n-gram 数据进行简单检查的问题是低频词中有很多噪音。在绝大多数情况下应该给你正确答案的最简单的事情是从前 50,000 或 100,000 个单词的适当大的地方(Google n-gram、Wikipedia 等)截断频率计数单词列表。根据需要调整阈值以获得您正在寻找的结果,但随后您可以检查是否有任何/所有查询词出现在此列表中。

如果您想知道查询是否符合语法,或者作为一个单元而不是其组成部分是否合理,那当然是另一个问题。

于 2012-11-26T16:26:06.097 回答
1

有一些非字典词可以是有效搜索(例如gethostbyname,在 SO 上是有效且有意义的搜索,但不是字典词)。另一方面,有些字典单词与您的网站完全无关。

您可以简单地检查搜索查询是否产生非空结果,而不是试图猜测什么是单词,什么不是。那些结果为空的必须完全偏离主题或胡言乱语。

于 2012-11-26T15:07:59.657 回答
0

听起来你正在寻找一个

贝叶斯滤波器

于 2012-11-26T15:53:12.180 回答