行为分类算法

根据两个用户的行为记录

[

[ 0, 1, 4, 9 ],
[ 8, 0, 7, 2 ]

]

,找出中间记录[4,0.5,5.5,5.5],生成特征

[

[ 0, 1, 0, 1 ],
[ 1, 0, 1, 0 ]

]

求出特征出现概率

[1/2,1/2,1/2,1/2]

输入新的行为,根据中间记录,生成特征,根据特征概率,求贝叶斯联合概率

const execMathExpress=require('exec-mathexpress');
//贝叶斯计算公式
function execByes(gArr){
const arr1=[]
const arr2=[]
const Obj={}
for(let i=0;i<gArr.length;i++){
arr1.push('P'+i)
arr2.push('(1-P'+i+')')
Obj['P'+i]=gArr[i];
}
const str1=arr1.join('*');
const str2=arr2.join('*');
const str=str1+'/('+str1+'+'+str2+')';
return execMathExpress(str,Obj).toString();
}

//已知数据中单个行为转化率 a 2/10 b 3/2
//未知用户的单个行为转化率 x 2 2
class People {
constructor(keys,data){
this.keys=keys;
this.data=data||[]
this.midArr=[]
this.fnArr=[]
}
learn(item){
this.data.push(item);
}
think(){
this.getMidArr();
this.getFnArr();
}
//获取特征的概率数据
getFnArr(){
const fnArr=[];
for(let i=0;i<this.keys.length;i++){
let fn=0;
for(let j=0;j<this.data.length;j++){
const d=this.data[j];
if(d[i]>=this.midArr[i]){
fn++;
}
}
fnArr.push(fn)
}
this.fnArr=fnArr;
}
//获取中间数,用中间数做特征分类
getMidArr(){
const midArr=[];
for(let i=0;i<this.keys.length;i++){
const arr=[];
for(let j=0;j<this.data.length;j++){
const d=this.data[j];
arr.push(d[i])
}
arr.sort(function (n,m) {
return n>m?1:-1;
})
if(this.data.length%2===0){
const midNum=(arr[this.data.length/2-1]+arr[this.data.length/2])/2
midArr.push(midNum)
}else{
const midNum=(arr[(this.data.length-1)/2])
midArr.push(midNum)
}
}
this.midArr=midArr;
}

getOrder(item){
const arr=[]
for(let i=0;i<this.keys.length;i++){
if(item[i]>=this.midArr[i]){
arr[i]=this.fnArr[i]+'/'+this.data.length;
}else{
arr[i]=(this.data.length-this.fnArr[i])+'/'+this.data.length
}
}
return execByes(arr);
}
}
function randomArr(){
const arr=[];
for(let i=0;i<10;i++){
const n=0|Math.random()*20;
arr.push(n)
}
return arr
}
const rect=[
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
randomArr(),
];

const d=new People(randomArr(),rect)

d.think()

console.log(d)
for(let i=0;i<10;i++){
const n=d.getOrder(rect[i]);
const arr=n.split('/');
if(arr[0]*2>arr[1]){
console.log('1')
}else{
console.log('0')
}

}

 输出

1
1
1
1
0
1
1
0
1
1

posted @ 2020-04-03 19:32  无工时代  阅读(450)  评论(0编辑  收藏  举报