标签:javascript 机器人 中文分词 自动问答 人工智能
很简易的一个智能自动问答机器人,应用了中文句子分词、多关键词句子匹配技术。
<!DOCTYPE HTML>
<HTML>
<HEAD>
<meta charset="utf-8">
<TITLE>CHATTING</TITLE>
<STYLE TYPE="TEXT/CSS">
body{
background-color:#cccccc;
color:#eee;
text-align:center;
}
#dialogDisplay{
position:relative;
max-width:600px;
height:300px;
margin-left:auto;
margin-right:auto;
margin-top:50px;
background-color:#111111;
overflow:auto;
padding:30px;
}
#question{
min-width:600px;
margin-left:auto;
margin-right:auto;
margin-top:10px;
height:75px;
border-radius:10px;
background-color:#EEEEEE;
}
.questionbox{
text-align:right;
color:#FF0000;
font-size:10px;
}
.answerbox{
text-align:left;
color:#00FF00;
font-size:10px;
}
.speech{
background-color:#333333;
border-radius: 5px;
font-size:18px;
display:inline;
padding:10px;
line-height:200%;
}
</STYLE>
<SCRIPT TYPE="TEXT/JAVASCRIPT" SRC="ChineseDictionary.js"></SCRIPT>
<SCRIPT TYPE="TEXT/JAVASCRIPT" SRC="QuestionAndAnswer.js"></SCRIPT>
<SCRIPT TYPE="TEXT/JAVASCRIPT">
function found(keyword){
//判断关键词是否存在词典中
//词典以JSON格式存储在ChineseDictionary.js文件的W对象内
if(W[keyword]==1){
return true;
}else{
return false;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function parseChinese(inputSentence){
//正向关键词最长匹配法分词
//输入任意一句话,最终产生分词字符串resultString和分词数组resultArray
//删除待处理字符串头部的空格
inputSentence=inputSentence.replace(/(^\s+)/,"");
var inputSentenceLength=inputSentence.length;
var wordMaxLength=7;
var resultArray=new Array();
var resultString="";
var recognizedWords="";
//如果输入句长度小于词典词汇长度则令最大长度等于句子长度
if(inputSentenceLength<=wordMaxLength){
wordMaxLength=inputSentenceLength;
}
//增加三个空格方便尾部处理,空格数=wordMaxLength-1
inputSentence+=" ";
for(var i=0;i<inputSentenceLength;i++){
//尾部还需特殊处理
for(var j=wordMaxLength;j>0;j--){
var checkword=inputSentence.substr(i,j);
if(found(checkword)){
//alert(checkword);
recognizedWords+=checkword+",";
resultArray.push(checkword);
//注意后面需要-1,因为FOR循环会自动加1
i=i+j-1;
break;
}else{
if(j==1){
resultArray.push(checkword);
}
}
}
}
//处理所得到的结果数组
//由于前面的过程会把英文单词分割成字母,现在需要连接起来
for(var i=0;i<resultArray.length-1;i++){
var regw=/\w/;
if(regw.test(resultArray[i])&®w.test(resultArray[i+1])){
resultArray[i+1]=resultArray[i]+resultArray[i+1];
resultArray[i]="";
}
}
//结果数组转换成结果字符串
resultString=resultArray.join(" ");
//替换掉里面多余的空格
resultString=resultString.replace(/\s{2,}/g," ");
//替换掉多余的逗号去除尾部空元素
resultString=resultString.replace(/,$/,"");
//重新将字符串转换回数组
//去除识别字符串里的重复元素
if(resultString==""){
resultArray=new Array();
}else{
resultArray=resultString.split(" ").reverse().join(",").match(/([^,]+)(?!.*\1)/ig).reverse();
}
//本分词函数对象各个属性最终值
recognizedWords=recognizedWords.replace(/,$/,"");
this.recognizedWords=recognizedWords;
//注意输入值为空或者不匹配的情况
if(this.recognizedWords==""){
this.recognizedWordsArray=new Array();
}else{
this.recognizedWordsArray=recognizedWords.split(",").reverse().join(",").match(/([^,]+)(?!.*\1)/ig).reverse();
//ar.reverse().join(",").match(/([^,]+)(?!.*\1)/ig).reverse()//删除数组中重复元素
}
//将分词结果存在本对象的字符串和数组中
this.resultString=resultString;
this.resultArray=resultArray;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function matchRate(string1,string2){
//任意两句话的话题匹配程度(只考虑二者的关键词)
var matchScore1=0;
var matchScore2=0;
var chineseWords1=new parseChinese(string1);
var chineseWords2=new parseChinese(string2);
var keywordsArray1=chineseWords1.recognizedWordsArray;
var keywordsArray2=chineseWords2.recognizedWordsArray;
var keywordsString1="#"+keywordsArray1.join("##")+"#";
var keywordsString2="#"+keywordsArray2.join("##")+"#";
var keywordsStringRegX1="/"+"#"+keywordsArray1.join("#|#")+"#/gi";
var keywordsStringRegX2="/"+"#"+keywordsArray2.join("#|#")+"#/gi";
//用string2的关键词去匹配string1
var matchArray1=new Array();
matchArray1=keywordsString1.match(eval(keywordsStringRegX2));
//用string1的关键词去匹配string2
var matchArray2=new Array();
matchArray2=keywordsString2.match(eval(keywordsStringRegX1));
if(matchArray1!=null){
matchScore1=matchArray1.length;
}else{
matchScore1=0;
}
if(keywordsArray2.length>0){
matchScore1=matchScore1/keywordsArray2.length*100;
}else{
matchScore1=0;
}
if(matchArray2!=null){
matchScore2=matchArray2.length;
}else{
matchScore2=0;
}
if(keywordsArray1.length>0){
matchScore2=matchScore2/keywordsArray1.length*100;
}else{
matchScore2=0;
}
//取互相匹配的值的平均值为最终结果
var averageScore=(matchScore1+matchScore2)*0.5;
return averageScore;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function matchAllRate(string1,string2){
//任意两句话的话题匹配程度(只考虑二者的关键词)
var matchScore1=0;
var matchScore2=0;
var chineseWords1=new parseChinese(string1);
var chineseWords2=new parseChinese(string2);
var keywordsArray1=chineseWords1.resultArray;
var keywordsArray2=chineseWords2.resultArray;
var keywordsString1="#"+keywordsArray1.join("##")+"#";
var keywordsString2="#"+keywordsArray2.join("##")+"#";
var keywordsStringRegX1="/"+"#"+keywordsArray1.join("#|#")+"#/gi";
var keywordsStringRegX2="/"+"#"+keywordsArray2.join("#|#")+"#/gi";
//用string2的关键词去匹配string1
var matchArray1=new Array();
matchArray1=keywordsString1.match(eval(keywordsStringRegX2));
//用string1的关键词去匹配string2
var matchArray2=new Array();
matchArray2=keywordsString2.match(eval(keywordsStringRegX1));
if(matchArray1!=null){
matchScore1=matchArray1.length;
}else{
matchScore1=0;
}
if(keywordsArray2.length>0){
matchScore1=matchScore1/keywordsArray2.length*100;
}else{
matchScore1=0;
}
if(matchArray2!=null){
matchScore2=matchArray2.length;
}else{
matchScore2=0;
}
if(keywordsArray1.length>0){
matchScore2=matchScore2/keywordsArray1.length*100;
}else{
matchScore2=0;
}
//取互相匹配的值的平均值为最终结果
var averageScore=(matchScore1+matchScore2)*0.5;
return averageScore;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function talk(){
//智能应答对话主程序
//应用了前面的分词和匹配技术
var bestAnswerIndex=0;
var bestMatchScore=0;
var questionString=document.getElementById("question").value;
document.getElementById("question").value="";
var now=new Date().toLocaleTimeString();
//显示问题到屏幕上
var outputString="<div class='questionbox'><br />"+now+" 冰豆小李<br /><br /><div class='speech'>"+questionString+"</div><br /></div>";
document.getElementById("dialogDisplay").innerHTML+=outputString;
document.getElementById("dialogDisplay").scrollTop=document.getElementById("dialogDisplay").scrollHeight;
//去除特殊符号以免后续匹配出错
questionString=questionString.replace(/\^|\.|\*|\?|\!|\/|\\|\$|\#|\&|\||,|\[|\]|\{|\}|\(|\)|\-|\+|\=/g," ");
//遍历问答库,搜寻最接近的问答
for(var i=0;i<QA_Count;i++){
var answerQ=QA[i].Q;
answerQ=answerQ.replace(/\^|\.|\*|\?|\!|\/|\\|\$|\#|\&|\||,|\[|\]|\{|\}|\(|\)|\-|\+|\=/g," ");
//matchAllRate才能匹配英文
var matchScore=matchAllRate(questionString,answerQ);
//优选出匹配度最高的
if(matchScore>=bestMatchScore){
bestMatchScore=matchScore;
bestAnswerIndex=i;
}
//如果遇到全匹配则跳出搜索循环
if(matchScore==100){
break;
}
//如果识别率为零则生成一个随机应答索引
//问答知识库头10条记录是为这种情况设定的
if(bestMatchScore==0){
bestAnswerIndex=Math.floor(Math.random()*10);
}
}
//依据所获的索引号提取出问题的最佳答案
var answerString=QA[bestAnswerIndex].A;
//不能显示太快,否则机器人的痕迹太明显,所以要延迟显示
var delayTimer=setTimeout(showAnswer,1);
//显示问题的答案到屏幕上
function showAnswer(){
var now=new Date().toLocaleTimeString();
var outputString="<div class='answerbox'><br />一粒马豆 "+now+"<br /><br /><div class='speech'>"+answerString+"</div><br /></div>";
document.getElementById("dialogDisplay").innerHTML+=outputString;
document.getElementById("dialogDisplay").scrollTop=document.getElementById("dialogDisplay").scrollHeight;
}
}
</SCRIPT>
</HEAD>
<BODY>
<div id="dialogDisplay"></div>
<input id="question" type="text" onkeypress="if(event.keyCode==13){talk()}" />
</BODY>
</HTML>版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:javascript 机器人 中文分词 自动问答 人工智能
原文地址:http://blog.csdn.net/maillibin/article/details/47681549