标签: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