• 找到拥有相同标签的用户对


    一道试题:找到拥有相同标签的用户对

    2012-03-06 21:42 by lvkun, 1083 visits, 收藏编辑

    问题

    给定sina微博的全部用户(1亿以上)和标签(uniq的标签30万左右)的关系, 系统找出共有2个或以上标签的用户对,并给出这些标签是哪些。

    • input:

      userid,taglist 
    • output:

      userid,userid,con-taglist (sizeof(con_taglist)>=2) 

    数据示例

    • 输入

      AA,体育 新闻 清华 百年校庆 BB,娱乐 八卦 清华 新闻 CC,体育 娱乐 新闻 DD,八卦 新闻 娱乐 
    • 输出

      AA,BB 清华 新闻 AA,CC 体育 新闻 BB,CC 娱乐 新闻 BB,DD 娱乐 八卦 新闻 CC,DD 娱乐 新闻 

    生成测试数据

    编写 datagen.py 生成测试数据。

    • 命令行参数

      • --userNumber -u 测试数据中包含的用户数量(默认: 100000000)
      • --tagNumber -t 测试数据中包含的标签数量(默认: 3000000)
      • --maxUserTags -m 每个用户能够拥有的最大标签数量(默认: 10)
      • --outfile -o 输出文件名(默认: data.txt)

    问题分析

    可以将用户对看做为一个矩阵:

     * AA BB CC DD AA 0 清华 新闻 体育 新闻 0 BB 清华 新闻 0 娱乐 新闻 娱乐 八卦 新闻 CC 体育 新闻 娱乐 新闻 0 娱乐 新闻 DD 0 娱乐 八卦 新闻 娱乐 新闻 0 

    该矩阵存在以下特征:

    • 横轴和纵轴都是以用户名作为坐标
    • 对角线上的元素都为空
    • 矩阵元素的值以对角线对称,可以只考虑上半部分。
    • 考虑实际情况,应该会有很多元素为空,即大部分用户不存在相同标签。

    基本解决方法

    • 按行读取输入数据
    • 针对每一行进行如下操作

      • 解析出当前用户名 user_name , tag_text_list
      • 记录行号,作为用户的唯一 id (假定用户名可能重复),将用户名保存在数组 users_name 中, 如:

        users_name[0] = 'AA' users_name[1] = 'BB' ...... 
      • 更新标签字典 tags_id ,为每个新遇到标签分配一个唯一递增的数字 id 。

        tags_id["体育"] = 0 tags_id["新闻"] = 1 tags_id["清华"] = 2 ...... 
      • 更新标签数组文本属性 tags.text

        tags[0].text = "体育" tags[1].text = "新闻" tags[2].text = "清华" .... 
      • 标签用户数组 tags ,该数组保存的是每一个 tag 对应的用户 id 列表。(假设当前读入行 CC )

        tags[0].users = [0] ## 体育    AA tags[1].users = [0, 1] ## 新闻    AA BB tags[2].users = [0, 1] ## 清华    AA BB tags[3].users = [0] ## 百年校庆 AA tags[4].users = [1] ## 娱乐    BB tags[5].users = [1] ## 八卦    BB 
      • 获取当前用户所有对应的标签的用户列表(假设当前读入行 CC )

        user_tag_list = [] for tag_text in current_user.tag_text_list: tag_id = tags_id["tag_text"] user_tag_list.append([(user_id, tag_id) for user_id in tags[tag_id].users]) user_tag_list[0] = [(0, 0)] ## (AA 体育) user_tag_list[1] = [(1, 4)] ## (BB 娱乐) user_tag_list[2] = [(0, 1), (1, 1)] ## (AA 新闻) (BB 新闻) 
      • 将 user_tag_list 按照 user_id 合并排序, 生成新的 user_tag_list

        user_tag_list = [(0, 0), (0, 1), (1, 4), (1, 1)] 
      • 然后遍历该列表, 找到相同 user_id 出现过两次以上, 并输出即可

      • 将当前用户插入标签用户数组 tags_users (假设当前读入行 CC )

        tags[0].users = [0] ## 体育    AA tags[1].users = [0, 1] ## 新闻    AA BB tags[2].users = [0, 1] ## 清华    AA BB tags[3].users = [0] ## 百年校庆 AA tags[4].users = [1] ## 娱乐    BB tags[5].users = [1] ## 八卦    BB 
      • 继续下一循环

    实际应用需解决问题

    • 考虑内存消耗,使用数据库保存

      • 输入文件 > 30G
      • 内存占用 > 50G
    • 将计算过程线程化

      • 暂停
      • 存储当前进度后退出
      • 从上次计算的位置继续进行
    • 用户界面以了解计算进度

    进一步解决方案

    使用MapReduce方案

    本人对算法不算精通,请教大家,上述解决方法中是否存在算法问题,是否有更高效的解决方法?谢谢大家了!

  • 相关阅读:
    ie6 浏览器的bug
    hack (浏览器兼容css hack)
    jquery操作select下拉框的多种方法(选中,取值,赋值等)
    php 环境搭配 脚本模式(1)
    JQuery限制文本框只能输入数字和小数点的方法
    使用jOrgChart插件, 异步加载生成组织架构图
    JavaScript 输出
    Java开发环境的搭建以及使用eclipse从头一步步创建java项目
    git cherry-pick
    <a>标签的href、onclick属性
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2392154.html
Copyright © 2020-2023  润新知