Hadoop好友推荐系统-寻找最佳DC

项目总目录:基于Hadoop的好友推荐系统项目综述

一、寻找最佳DC

1、前端展示

  • jsp页面
<div style="padding-left: 30px;font-size: 20px;padding-top:10px;">
        <table>
            <tr>
                <td><label for="name">输入路径:</label>
                </td>
                <td><input class="easyui-validatebox" type="text"
                    id="findbestdc_input_id" data-options="required:true" style="width:300px"
                    value="/user/root/_filter/caldistance" /></td>

            </tr>

            <tr>
                <td><label for="name">输入记录数:</label>
                </td>
                <td><input class="easyui-validatebox" type="text"
                    id="findbestdc_record_id" data-options="required:true" style="width:300px"
                    value="0" /></td>
                <td><label for="name">如果已经运行了距离计算MR,可以不用设置此值</label></td>

            </tr>

            <tr>
                <td><label for="name">阈值百分比:</label>
                </td>
                <td><input class="easyui-validatebox" type="text"
                    id="findbestdc_delta_id" data-options="required:true" style="width:300px"
                    value="2%" /></td>

            </tr>
            <tr>
                <td></td>
                <td><a id="findbestdc_submit_id" href="" class="easyui-linkbutton"
                    data-options="iconCls:'icon-door_in'">定位最佳DC</a></td>
            </tr>

        </table>
    </div>

    <div id="dc_return_id" style="padding-left: 30px;font-size: 20px;padding-top:10px;"></div>

jsp页面需要设置文件输入路径(默认就是距离计算任务的输出路径)、输入记录数(可以手工设置,如果运行过距离计算任务,则该值以保存在后台中,不需要手动设置)、阈值百分比(默认2%)。

  • js逻辑
//findbestdc_submit_id 找到最佳阈值
    $('#findbestdc_submit_id').bind('click', function(){
        var input_=$('#findbestdc_input_id').val();
        var delta_=$('#findbestdc_delta_id').val();
        var record_=$('#findbestdc_record_id').val();
        // 弹出进度框
        popupProgressbar('请等待','寻找最佳阈值DC中...',1000);
        // ajax 异步提交任务
        callByAJaxLocal_findbestdc('cloud/cloud_findbestdc.action',{input:input_,delta:delta_,record:record_});
    });

这里使用callByAJaxLocal_findbestdc方法实现任务提交,其定义如下:如果任务执行成功,它将后台返回数据中的dc写入到前端的相应位置。

function callByAJaxLocal_findbestdc(url,data_){
    $.ajax({
        url : url,
        data: data_,
        async:true,
        dataType:"json",
        context : document.body,
        success : function(data) {
//          $.messager.progress('close');
            closeProgressbar();
            console.info("data.flag:"+data.flag);
            var retMsg;
            if("true"==data.flag){
                retMsg='操作成功!DC阈值为:'+data.dc;
                $('#dc_return_id').html("推荐DC阈值为:"+data.dc);//将结果写入前端页面
            }else{
                retMsg='操作失败!失败原因:'+data.msg;
            }
            $.messager.show({
                title : '提示',
                msg : retMsg
            });

        }
    });
}

后台逻辑

  • action层

对应的action从这里获取:callByAJaxLocal_findbestdc(‘cloud/cloud_findbestdc.action’,)

/**
     * 遍历向量距离文件,寻找最佳阈值
     */
    public void findbestdc(){
        double dc=0.0;
        Map<String,Object> map = new HashMap<String,Object>();
        int recordInt = Integer.parseInt(record);
        if(HUtils.INPUT_RECORDS==0&&recordInt!=0){
            HUtils.INPUT_RECORDS=recordInt;
        }
        try{
            if(HUtils.INPUT_RECORDS==0){
                map.put("flag", "false");
                map.put("msg", "请先运行计算距离MR任务,或者设置任务运行后的记录数!");
                Utils.write2PrintWriter(JSON.toJSONString(map));
                return ;
            }
            dc=HUtils.findInitDC(Double.parseDouble(delta.substring(0, delta.length()-1))/100, input, 
                    HUtils.INPUT_RECORDS);
            //前端传过来的delta是字符串"2%",substring(0, delta.length()-1))截取的就是"2",然后转为double除以100即可。
            //public String substring(int beginIndex, int endIndex)返回一个新字符串,
            //它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 处开始,直到索引 endIndex - 1 处的字符。因此,该子字符串的长度为 endIndex-beginIndex。 
        }catch(Exception e){
            e.printStackTrace();
            map.put("flag", "false");
            map.put("msg", e.getMessage());
            Utils.write2PrintWriter(JSON.toJSONString(map));
            return ;
        }
        map.put("flag", "true");
        map.put("dc", dc);
        Utils.simpleLog(JSON.toJSONString(map));
        Utils.write2PrintWriter(JSON.toJSONString(map));
        return;
    }

其中的关键语句是

dc=HUtils.findInitDC(Double.parseDouble(delta.substring(0, delta.length()-1))/100, input, 
                    HUtils.INPUT_RECORDS);
  • 寻找最佳DC

HUtils.findInitDC的定义如下:

/**
     * 根据给定的阈值百分比返回阈值,输入参数为阀值百分比、输入路径和总记录数
     * 因为距离计算的MapReduce任务输出文件自动按照用户间的距离从小到大排序,所以计算阀值只需截取操作即可。
     * @param percent
     *            一般为1~2%
     * @return
     */
    public static double findInitDC(double percent, String path,long iNPUT_RECORDS2) {
        Path input = null;
        if (path == null) {
            input = new Path(HUtils.getHDFSPath(HUtils.FILTER_CALDISTANCE
                    + "/part-r-00000"));
        } else {
            input = new Path(HUtils.getHDFSPath(path + "/part-r-00000"));//初始化输入路径
        }
        Configuration conf = HUtils.getConf();
        SequenceFile.Reader reader = null;
        long counter = 0;
        long percent_ = (long) (percent * iNPUT_RECORDS2);//计算截取的下标值(按前2%计算)
        try {
            reader = new SequenceFile.Reader(conf, Reader.file(input),
                    Reader.bufferSize(4096), Reader.start(0));
            DoubleWritable dkey = (DoubleWritable) ReflectionUtils.newInstance(
                    reader.getKeyClass(), conf);
            Writable dvalue = (Writable) ReflectionUtils.newInstance(
                    reader.getValueClass(), conf);
            while (reader.next(dkey, dvalue)) {// 从小到大依次遍历距离结果文件
                counter++;
                if(counter%1000==0){//每1000个数据输出一个log
                    Utils.simpleLog("读取了"+counter+"条记录。。。");
                }
                if (counter >= percent_) {//遍历到了阀值下标处
                    HUtils.DELTA_DC = dkey.get();// 赋予最佳DC阈值
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeStream(reader);
        }
        return HUtils.DELTA_DC;//返回最佳DC的值
    }

二、程序运行截图

这里写图片描述
这里的阀值百分比需要人为设置,这个值将影响DC值得选取,从而影响整个分类算法的准确性,需要经过多次尝试才能得出最佳的阀值百分比。关于该值的如何选取尚未有相关研究,在新型算法的论文中也提到这个值是个经验选取值,推荐在1%-2%,但是有时候得到的分类情况并不理想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值