码迷,mamicode.com
首页 > 其他好文 > 详细

简易智能自动问答机器人

时间:2015-08-15 15:01:01      阅读:193      评论:0      收藏:0      [点我收藏+]

标签: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])&&regw.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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!