协同过滤算法代码

2023-11-20

此算法主要用来推荐的.

 //找出ui,uj两个用户同时打过分的课程集合
   function getPSet($uid, $ujd)
    {
        //"select 课程编号 from 评分 where 用户编号=@ui and 课程编号 in (select 课程编号 from 评分 where 用户编号=@uj)";
        $db=M('videoscore');
        $result=$db->where(array('uid'=>$ujd))->field('tid')->select();
        
        //将二维数组 转为一位数组  并将字符串转化为intval
        foreach($result as $k=>$v){
            $result[$k]=intval($v['tid']) ;
        }
        $map['tid']=array('in',$result);
        $result=$db->where($map)->distinct(true)->Field('tid')->select();
         foreach($result as $k=>$v){
            $result[$k]=intval($v['tid']);
        }
        
        
        return $result;
    }
 //取用户ui对课程pj第k个评价指标的评分,k=1,2,3分别表示 才艺满意度、看满意度、信誉度
    function getPScore($ui, $pj, $k)
    {
        $db=M('videoscore');
        $where=array(
            'uid'=>$ui,
            'tid'=>$pj,
        );
        //"select AVG(CAST(才艺满意度 AS decimal(10, 5))) from 用户_课程评分 where 用户编号=@ui and 课程编号=@pj group by 用户编号,课程编号";//求平均,因同一用户对同一课程可评多次
        $result=$db->where($where)->group('tid','uid')->avg('skill');
        if($k==2){
             $result=$db->where($where)->group('tid','uid')->avg('effects');
        }
        if($k==3){
             $result=$db->where($where)->group('tid','uid')->avg('expression');
        }
        if($result){
            return $result;
        }
       
    }

计算用户相似度 :这里用的是余弦相似度算法计算的. (还可以用 皮尔森相关系数法   公式可以google. 方法和余弦相似度算法类似)

//计算ui,uj两个用户 的相似度,按第k个评分指标计算 
     //余弦相似度公式
     //https://blog.csdn.net/zz_dd_yy/article/details/51926305
  function sim($ui, $uj,$k)
    {
        $samecourse=getPSet($ui,$uj);//找出ui,uj两个用户同时打过分的课程集合
        foreach($samecourse as $key=>$v){//ui,uj用户对每一门课程的第$k个指标
            $r1=getPScore($ui,$v,$k);
            $r2=getPScore($uj,$v,$k);

            $sum0+=$r1*$r2;
            $sum1+=$r1*$r1;
            $sum2+=$r2*$r2;
        } 
        $result=$sum0/(sqrt($sum1)*sqrt($sum2));
        return $result;
        
    }
//取除了ui外的所有用户(评分表中作过评价的用户)
    function getAll_U_ExceptUi($ui)
    {
        $db=M('videoscore');
        $map['uid']=array('NEQ',$ui);
        //"select distinct 用户编号 from 用户_课程评分 where 用户编号<>@ui";
        $result=$db->where($map)->distinct(true)->select();
        
        foreach($result as $key=>$v){
            $result[$key]=intval($v['uid']);//用intval把string转化为int
        };
        $result=array_unique($result);//去掉重复id
        
        foreach($result as $key=>$v){
            $copy[]=$v;
        }
        $result=$copy;
       // echo dump($result); die;
        return $result;
       
    }

 //计算其它用户与用户ui的相似度,按第k个评分指标计算  similar相似度 uid1 用户1 uid2 用户2
   function computeSimToUi($ui,$k)
    {
        $dtU = getAll_U_ExceptUi($ui);//取除了ui外的所有用户
      //  $dtSim = array(array("用户编号1","用户编号2","相似度"));//存放相似度的表          
        for ($i = 0; $i < Count($dtU); $i++) //对每一个用户,$dtU[$i]
        {
         
            $doubleSim=sim($ui, $dtU[$i], $k);
            $dtSim[]=array("uid1"=>$ui,"uid2"=>$dtU[$i],"similar"=>$doubleSim);
        };
        $dtSim=BubbleSort($dtSim,'similar');
        return $dtSim;
      //按相似度similar 倒序
    // return  array_multisort($dtSim['similar'],SORT_NUMERIC,SORT_DESC);
        
    }
 //---------------    以下代码计算ui对pj的预测分  -------------------------------------//
     //计算用户ui的对课程的第k项指标的评价的平均分 计算这个是防止用户习惯性打高分或打低分
    function computeUiAvgForK($ui, $k)
    {
        $db=M('videoscore');
        $where=array(
            'uid'=>$ui
        );
       // "select AVG(CAST(才艺满意度 AS decimal(10, 5))) from 用户_课程评分 where 用户编号=@ui";//求平均,因同一用户的评分
       $result=$db->where($where)->avg('skill');
      
        if ($k == 2)//第2个指标
        {
            //"select AVG(CAST(看满意度 AS decimal(10, 5))) from 用户_课程评分 where 用户编号=@ui";//求平均,
             $result=$db->where($where)->avg('effects');
        }
        if ($k ==3) //第3个指标
        {
            //"select AVG(CAST(信誉度 AS decimal(10, 5))) from 用户_课程评分 where 用户编号=@ui";
        $result=$db->where($where)->avg('expression');
        }
        if($result){
            return $result;
        }
       
    }
 //判断 用户ui有没有给课程pj打过分
    function isExistsUi_Pj_Score($ui, $pj)
    {
        $db=M('videoscore');
        //"select 信誉度 from 用户_课程评分 where 用户编号=@ui and 课程编号=@pj";//是否评过分
        $result=$db->where(array('uid'=>$ui,'tid'=>$pj))->field('expression')->select();
        if(!isset($result))//为空
        {
            return false;
        }
        foreach($result as $key=>$v){
            $result[$key]=intval($v['expression']);
        }
         return $result;
       
    }

 //取给课程pj的第k个指标打过分的,与用户ui最相似的n个用户(用户给课程打分时,所有三个指标都要打分才能提交)
    function getTopN_U_ForPj_To_K($ui,$pj,$k,$n)
    {
      
        $counter = 0;
        $dtNeighbor=computeSimToUi($ui,$k);//得与ui相似的用户与相似度并排序好  输出数组        
      
        for ($i = 0; $i < Count($dtNeighbor); $i++) //对每一个用户,
        {            
           $a=$dtNeighbor[$i]['uid2'];
            if (isExistsUi_Pj_Score($dtNeighbor[$i]['uid2'], $pj))
            {
                $dtResult[]=array('uid1'=>$ui,'uid2'=>$dtNeighbor[$i]['uid2'],'similar'=>$dtNeighbor[$i]['similar']);
                $counter++;
            }
            if ($counter >= $n)
                break;
        }
        return $dtResult;        
    }

//下面的函数要用到公式



 //计算用户ui对课程pj的第k个指标的预测分,使用最相似的n个用户(最多n个) 的相度似 sim(ui,uj) 来计算
    //表结构为:用户编号1,用户编号2,相似度.第k个指标   
     function compute_Score_Ui_Pj_K_N($ui,$pj,$k,$n)
        {
            
        $dt = getTopN_U_ForPj_To_K($ui, $pj, $k, $n);//表结构为:用户编号1,用户编号2,相似度.第k个指标
        foreach($dt as $key=>$v){
            //计算该行对应的用户2,的平均打分,对k指标
                $dUjAvg = computeUiAvgForK($v['uid2'], $k);//Ri平均
                $dUjToPjForK = getPScore($v['uid2'], $pj, $k);//Rij
                $diff = $dUjToPjForK - $dUjAvg;           //(Rij-Ri平均)
                $dSum0+=floatval($v['similar']) * $diff;//计算分子项
                $dSum1 +=floatval($v['similar']);  //计算分母项
        }
        
            $dSum3 = computeUiAvgForK($ui, $k);//Ri平均
            $dResult = $dSum3 + $dSum0 / $dSum1;
            return $dResult;
        }
 //取用户ui没有看评价过的课程集合
    function getAll_New_Pj_For_Ui($ui)
    {
       // "select distinct 课程编号 from 用户_课程评分 where 课程编号 not in (select 课程编号 from 用户_课程评分 where 用户编号=@ui)";
         $db=M('videoscore');
         $result=$db->where(array('uid'=>$ui))->distinct(true)->field('tid')->select();
         foreach($result as $key=>$v){
             $result[$key]=intval($v['tid']);
         }
        $map['tid']=array('not in',$result);
       
        $result=$db->where($map)->distinct(true)->field('tid')->select();
        
        foreach($result as $key=>$v){
            $result[$key]=intval($v['tid']);//用intval把string转化为int
        };
       // echo dump($result); die;
        return $result;
      
    }
     //计算用户ui对没有看过的课程的预测评分(对第k个评价指标的评分),最多使用n个相似的用户数据预测
    function predict_AllPj_Score_ForUi_To_K($ui,$k,$n)
    {
     
        $dtPj = getAll_New_Pj_For_Ui($ui);//得用户ui没有看评价过的课程集合

        for ($i = 0; $i < Count($dtPj); $i++) //对每一个课程,
        {
           // pj = dtPj.Rows[i].ItemArray[0].ToString();//得课程编号
            $dScore = compute_Score_Ui_Pj_K_N($ui, $dtPj[$i], $k, $n);//计算用户ui对课程pj的第k个指标的预测分,使用最相似的n个用户数据(最多n个)
            $dtResult[]=array('uid'=>$ui,'tid'=>$dtPj[$i],'predictscore'=>$dScore );//增加行            
        }
        
         $result=BubbleSort($result,'predictscore');
        return $dtResult;        
    }
     //计算用户ui对没有看过的课程的综合预测评分(3个评价指标的评分的加权平均),最多使用n个相似的用户数据预测,p是权限
    function predict_AllPj_Score_ForUi($ui,$p, $n)
    {
   
        $dtPj = getAll_New_Pj_For_Ui($ui);//得用户ui没有看评价过的课程集合

        for ($i = 0; $i < Count($dtPj); $i++) //对每一个课程,
        {
           // pj = dtPj.Rows[i].ItemArray[0].ToString();//得课程编号
            $dScore1 = compute_Score_Ui_Pj_K_N($ui, $dtPj[$i], 1, $n);//计算用户ui对课程pj的第1个指标的预测分,使用最相似的n个用户数据(最多n个)
            $dScore2 = compute_Score_Ui_Pj_K_N($ui, $dtPj[$i], 2, $n);
            $dScore3 = compute_Score_Ui_Pj_K_N($ui, $dtPj[$i], 3, $n);
            $dScore4 = $p[0] * $dScore1 + $p[1] * $dScore2 + $p[2] * $dScore3;
            $dtResult[]=array('uid'=>$ui,'tid'=>$dtPj[$i],'skill'=>$dScore1,'effects'=>$dScore2,'expression'=>$dScore3,'overall'=>$dScore4);//增加行            
        }
       
        $result=BubbleSort($dtResult,'overall');
        return $result;
    }
    //排序  从高到低
    function BubbleSort($result,$key){
        for($i=0;$i<Count($result)-1;$i++)
        {
            for($j=0;$j<Count($result)-$i-1;$j++){
               
                if($result[$j][$key]<$result[$j+1][$key])
                {
                    $temp=$result[$j];
                    $result[$j]=$result[$j+1];
                    $result[$j+1]=$temp;
                }
            }
        }
        return $result;
    }

以下为测试数据: uid是用户id  tid是课程id 另外三个是评分指标

uid tid skill effects expression
1 1 5 4 4
2 1 3 3 5
3 2 4 5 5
4 3 5 3 4
1 2 4 4 4
4 4 5 4 3
3 3 5 5 4
2 1 4 5 3
1 3 3 4 4
2 2 3 3 3
3 1 4 4 2
4 1 4 4 5
5 1 2 5 4
5 9 5 3 1
5 2 5 5 5
6 1 1 2 3
6 2 3 1 2
6 4 5 4 3
1 1 3 0 2
1 2 3 0 2
1 8 3 3 3
1 3 3 2 3
2 2 2 5 5
2 1 3 3 1
2 10 3 2 2
2 6 5 5 3
3 6 5 4 3
3 2 3 4 3
3 8 4 2 4
3 3 3 3 0
3 2 2 4 3
4 1 3 2 3
4 2 4 2 3
4 3 4 3 2
8 4 4 3 4
5 9 3 3 3
9 2 4 5 4
5 8 3 2 2
5 4 4 3 3
10 5 4 4 4
5 10 3 3 2
5 5 4 4 4
3 6 3 6 4
6 8 4 4 3
7 5 4 3 3
8 4 1 5 5
9 3 2 3 2

10 7 4 2 4

//shell脚本导入数据库

#!/bin/bash
#www.cnblogs.com/iloveyoucc/archive/2012/07/10/2585529.html
#https://www.cnblogs.com/fire909090/p/7202584.html
filename='/home/fitch/Desktop/data.txt'
i=0

#连接数据库
MYSQL="mysql -h localhost -uroot -pfitch --port=3306"


cat $filename | while read uid tid  skill effects expression
do
# echo "$i  i"
  if [ $i -eq 0 ];then
      i=$[$i+1] 
#      echo "o"
  else
#      echo "$line $i"
#	echo $line
	sql="use music; insert into hd_videoscore (uid,tid,skill,effects, expression,content,time) values(${uid},${tid},${skill},${effects},${expression},'aaa',1526630425);"
	$MYSQL -e "$sql"
  fi
done




本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

协同过滤算法代码 的相关文章

  • WordPress 中的 add_action 函数

    嗯 我正在学习创建一个 WordPress 插件 我下载了一个并阅读了代码 然后我看到了这个 我假设 foo 是它将添加操作的标签 但是 array 到底是做什么的呢 add action foo array foo1 foo2 我在看ht
  • 检查php中位字段是否打开的正确方法是什么

    检查位字段是否打开的正确方法是什么 在 php 中 我想检查来自 db mysql 的位字段是否打开 这是正确的方法吗 if bit 1 还有其他方法吗 我看到有人使用代码ord http jameslow com 2008 08 12 m
  • openssl_pkey_get_details($res) 不返回公共指数

    我在用着这个例子 https stackoverflow com a 12575951 2016196使用 php 生成的密钥进行 javascript 加密openssl图书馆 但是 details openssl pkey get de
  • 如何使用 phpunit 运行单个测试方法?

    我正在努力运行一个名为testSaveAndDrop在文件中escalation EscalationGroupTest php with phpunit 我尝试了以下组合 phpunit EscalationGroupTest escal
  • PHP 会话不适用于游戏

    我正在尝试模仿一款名为 SKUNK 用骰子玩 的游戏来完成一项作业 我无法让会话正常工作 这是我第一次使用 PHP 我还被告知无需会议即可完成 这是我的代码
  • Apache 访问 Linux 中的 NTFS 链接文件夹

    在 Debian jessie 中使用 Apache2 PHP 当我想在 Apache 的文档文件夹 var www 中创建一个新的小节时 我只需创建一个指向我的 php 文件所在的外部文件夹的链接 然后只需更改该文件夹的所有者和权限文件夹
  • PHP严格标准:声明应该兼容

    我有以下类层次结构 class O Base class O extends O Base abstract class A Abstract public function save O Base obj class A extends
  • 将“php”作为 shell 脚本执行时的自定义 php.ini 文件

    我在跑php作为 shell 脚本 我不确定 shell脚本 是否正确 该文件以 usr bin php 这很好用 但 MongoDB 类没有正确加载php ini文件 具有extension mongo so 未使用 我该如何使用它tha
  • 从 .phar 存档中提取文件

    对于 Phar 文件 我完全错过了一些东西 我正在安装一个需要 phpunit pdepend 和其他依赖项的项目 我将它们作为 phar 文件获取 但是 我无法使用命令行工具 php 命令 从中提取文件 我用谷歌搜索了这个问题 但没有发现
  • PHP 脚本可以在终端中运行,但不能在浏览器中运行

    我正在尝试执行exec命令 但我遇到了问题 当我运行以下代码时 当我通过浏览器运行它时它不起作用 但如果我把输出 str将其复制并粘贴到终端中 它工作得很好 造成这种情况的原因是什么 我该如何解决 目前我正在运行localhost php
  • 随机组合 MySQL 数据库中的两个单词

    我有一个包含名词和形容词的数据库 例如 id type word 1 noun apple 2 noun ball 3 adj clammy 4 noun keyboard 5 adj bloody ect 我想创建一个查询 它将抓取 10
  • PHP preg_filter 返回意外的长值

    尝试在 Woocommerce 中删除标签并过滤值 但无法以正确的格式获取它 有东西有腥味 我正在使用WC gt cart gt get cart subtotal 来检索该值 在此示例中 我的值是 2 429kr 原始返回值是 span
  • 覆盖控制器 Symfony 3.4/4.0

    我目前正在尝试覆盖 FOSUserBundle 中的控制器 在新的文档中 https symfony com doc 3 4 bundles override html https symfony com doc 3 4 bundles o
  • 在 apache docker 容器中运行虚拟主机

    我在同一个 apache 容器中有两个 php 应用程序 我试图在端口上运行其中一个应用程序 因为它需要通过根域而不是子文件夹进行访问 我想在端口 8060 上运行应用程序 我尝试使用 apache 虚拟主机执行此操作 但它不会加载页面 h
  • Laravel 中只向登录用户显示按钮

    如果我以 John 身份登录 如何才能只显示 John 的红色按钮而不显示 Susan 的红色按钮 测试系统环境 Win10 Laravel5 4 Mysql5 7 19 table class table table responsive
  • 内部 while 循环不工作

    这是我项目网页上的代码片段 这里我想显示用户选择的类别 然后想显示属于该类别的主题 在那里 用户可以拥有多个类别 这没有问题 我可以在第一个 while 循环中打印所有这些类别 问题是当我尝试打印主题时 结果只显示一行 但每个类别中有更多主
  • 使用正则表达式提取两个短语之间的所有单词[重复]

    这个问题在这里已经有答案了 我正在尝试使用以下正则表达式提取两个短语之间的所有单词 b item W w W 0 2 1 one W w W 0 3 business b b item W w W 0 2 3 three W w W 0 3
  • 如何在 Laravel 中使用 PUT http 动词提交表单

    我知道这个问题可能已经提出 但我就是无法让它发挥作用 如果有人可以帮助我 我将非常感激 我安装了 colletive form 但答案也可以是 html 表单标签 现在列出我的表格 我的路线和我的例外情况 Form model array
  • 简单的 PHP 表单:电子邮件附件(代码 Golf)

    想象一下 一个用户想要在其网站上放置一个表单 该表单将允许网站访问者上传一个文件和一条简单的消息 该消息将立即通过电子邮件发送 即 该文件未存储在服务器上 或者如果该文件存储在服务器上 仅暂时 作为文件附件 并在邮件正文中添加注释 查看更多
  • post php mysql 的拆分关键字

    我有一个表存储帖子 ID 它的标签如下 Post id Tags 1 keyword1 keyword2 keyword3 我想循环遍历该表中的每一行并执行以下操作 将关键字1 关键字2 关键字3放入新表中 word id word val

随机推荐

  • minikube start启动集群失败Unable to find image gcr.io/k8s-minikube/kicbase:v0.0.10

    配套视频教程 minikube带你玩转k8s集群 1 minikube启动集群 minikube start vm driver docker image mirror country cn image repository registr
  • Intel CPU5种不同的CPU频率标定方式

    作者 cici xiang 链接 https www zhihu com question 271509706 answer 364246338 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 Intel C
  • G - Ginger的NB数(二分)

    G Ginger的NB数 SDUT OnlineJudge include
  • pyopencv基础操作指南

    个人学习整理 欢迎指正 实验版本 python版本 3 6 13 opencv版本 2 4 9 1 opencv简介 官网 http docs opencv org 3 0 beta doc py tutorials py tutorial
  • python无法导入自定义类

    问题描述是python3环境 在C Python36 Lib site packages mekk xmind目录下有 init py document py id gen py和xmlutil py四个文件 但是在引入mekk xmind
  • Linux 版本的 SQL Server 快速安装

    SQL Server 2017 版本已经支持 Linux 安装了 出来了很长时间 我还没有实现过在 Linux 上面的应用 包括安装和高可用配置 本文就先尝试完成 Linux 版 SQL Server 的安装 经常在 Windows 下安装
  • VLC for unity 插件如何使用

    VLC for unity 插件如何使用 先去下载一个VLC播放器 安装完成后 然后导入插件链接https download csdn net my 这个插件我的另一个上传资源里有 或者到商店去下载 这个插件链接下载完是一个txt文档 里面
  • settings.json是什么?VS Code的“用户”和“工作区”

    setting json settings json是VS Code众多配置文件中的一个 可以对VS Code进行页面风格 代码格式 字体颜色大小等的编辑设置 比如可能编辑器默认的一个tab为4个空格 用户可以在setting json里面
  • C++11-14 第10讲 template template parameter(模板模板参数)

    template
  • QML类型——ListModel

    正文 列表数据Model 可以自定义格式 详细说明 ListModel是定义ListElement的容器 内容可以动态定义 也可以在QML中明确定义 可以通过count属性获得模型中数据的数量 可以使用模型的setProperty 方法来操
  • 【Linux/C++:modebus通信示例】(带初习配置概括)

    以modbus RTU为例 模拟modbus简单通信原理的代码实现 首先需要配置串口 这里使用的为Configure Virtual Serial Port Driver虚拟串口调试工具 创建COM1 COM2虚拟端口 或另创建一对串口互作
  • JAVA自学之路

    JAVA自学之路 一 学会选择 为了就业 不少同学参加各种各样的培训 决心做软件的 大多数人选的是java 或是 net 也有一些选择了手机 嵌入式 游戏 3G 测试等 那么究竟应该选择什么方向呢 我的意见是 不要太过相信各种培训机构或是抢
  • ctfshow web7

    文章目录 题目分析 解题过程 题目分析 打开题目后 有三个文章 随便点一个之后发现网址上有个后缀 id 2 应该是get传参的注入了 在后缀上加 id 1 1 显示全部文章 可能是整形注入 还是盲注 他这个过滤了空格 用 代替 详见web6
  • MySQL 8.0数据库在Win10的位置

    MySQL 8 0的配置文件位置在下面的ini文件中 C ProgramData MySQL MySQL Server 8 0 my ini C ProgramData 一般是隐藏的 修改文件夹选项可见 或者直接输入位置就能打开文件加了 m
  • wifidog浏览器弹窗认证 — 基于OpenWRT路由器

    一 移植 wifidog功能 1 功能介绍 wifidog是一种能够实现让路由器局域网设备 包括wifi连接和网线连接设备 在上网前先进行 portal认证的工具 主要应用于手机端上网认证 手机在连接wifi后会自动打开浏览器并跳转出 lo
  • C++顺序链表

    include
  • Android AutoCompleteTextView实现自动补全

    辛苦堆砌 转载请注明出处 谢谢 最近工作用到了自动补全 这里做一个简单记录 首先上我们的布局
  • 类函数重载

    函数重载必然发生在同一个作用域 重载函数 本事为不同函数 函数名和参数列表决定函数 函数必须发生在同一个作用域中 include
  • IDEA 编写JDBC 第一个示例

    知心惟有雕梁燕 自来相伴 东风不管琵琶怨 落花吹遍 一 新建一个Module 二 在此Module下新建一个包 在包再建一个包 命名为lib 三 导入mysql驱动 四 将mysql驱动添加到项目的库里 五 代码实现 package Con
  • 协同过滤算法代码

    此算法主要用来推荐的 找出ui uj两个用户同时打过分的课程集合 function getPSet uid ujd select 课程编号 from 评分 where 用户编号 ui and 课程编号 in select 课程编号 from