├── .gitignore ├── .idea └── .name ├── README.md ├── data ├── discoveryWord │ └── dis-word-part-00023-opt └── recommend │ └── ml-1m │ ├── README │ ├── movies.dat │ ├── personalRatings.txt │ ├── ratings.dat │ └── users.dat ├── out └── artifacts │ └── spark_example_jar │ └── spark-example.jar ├── pom.xml ├── spark-example.iml └── src └── main └── java ├── META-INF └── MANIFEST.MF └── com └── blogchong ├── spark └── mllib │ ├── advance │ ├── ALSRecommendMovie │ │ └── AlsArithmeticPractice.scala │ ├── DiscoveryNewWord │ │ ├── AnsjDisWords.scala │ │ └── NGramSpark.scala │ └── LdaExtractTopics │ │ ├── Check │ │ ├── PredictsDocTopics.scala │ │ └── PredictsDocTopicsArgsParser.scala │ │ ├── Refer │ │ ├── LDAModelBuild.scala │ │ └── LDAModelBuildArgsParser.scala │ │ └── Train │ │ ├── LDAModelBuild.scala │ │ └── LDAModelBuildArgsParser.scala │ └── base │ ├── AlsArithmetic.scala │ ├── Kmeans.scala │ ├── KmeansArithmetic.scala │ ├── LdaArithmetic.scala │ └── Word2Vec.scala └── util ├── CharUtil.java └── NewTime.java /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /.classpath 3 | /.project 4 | /.cache 5 | /.settings 6 | /logs 7 | /.idea 8 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | spark-example -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #这是一个Spark MLlib实例 2 | ##1 K-meams基础实例 3 | ###1.1 数据准备 4 | **准备好如下数据:**
5 | >0.0 0.0 0.0
6 | 0.1 0.1 0.1
7 | 0.2 0.2 0.2
8 | 9.0 9.0 9.0
9 | 9.1 9.1 9.1
10 | 9.2 9.2 9.2
11 | 0.3 0.2 0.2
12 | 9.1 9.5 9.1
13 | 0.2 0.2 0.2
14 | 0.1 0.2 0.2
15 | 8.9 9.5 9.1
16 | 17 | 命名为kmeans_data.txt,且上传到hdfs的/spark/mllib/data/路径中。
18 | 19 | ###1.2 代码打包 20 | * 在Intellij中,点击file->选择project structure->选择Artifact->添加jar->把乱七八糟的依赖移除->勾选Build on make。
21 | * 点击Build->选择Build Artifact->选择ReBuild,然后在之前填写的路径下找到jar。
22 | * 上传到spark中。
23 | 24 | ###1.3 执行代码 25 | * 执行命令`./spark-submit --class com.blogchong.spark.mllib.base.Kmeans --master spark://192.168.5.200:7077 --num-executors 2 --driver-memory 124m --executor-memory 124m --total-executor-cores 2 /root/spark/hcy/spark-example.jar`
26 | //需要注意的是,在设置core数以及内存时,最好先参考一下spark-master-id:8080页面中的worker参数,别超过了就行。
27 | * 跑完了,直接到输出文件夹下,找到代码的输出结果即可。
28 | 29 | ##2 协同推荐ALS算法基础实例 30 | ###2.1 数据准备 31 | **用户评分数据,格式: 用户ID,电影ID,评分**
32 | >1,1,5.0
33 | 1,2,1.0
34 | 1,3,5.0
35 | 1,4,1.0
36 | 2,1,5.0
37 | 2,2,1.0
38 | 2,3,5.0
39 | 2,4,1.0
40 | 3,1,1.0
41 | 3,2,5.0
42 | 3,3,1.0
43 | 3,4,5.0
44 | 4,1,1.0
45 | 4,2,5.0
46 | 4,3,1.0
47 | 4,4,5.0
48 | 49 | 上传到hdfs的/spark/mllib/data/als路径中。
50 | 51 | ###2.2 代码打包 52 | * 在Intellij中,点击file->选择project structure->选择Artifact->添加jar->把乱七八糟的依赖移除->勾选Build on make。
53 | * 点击Build->选择Build Artifact->选择ReBuild,然后在之前填写的路径下找到jar。
54 | * 上传到spark中。
55 | 56 | ###2.3 执行代码 57 | * 执行命令`./spark-submit --class com.blogchong.spark.mllib.base.AlsArithmetic --master spark://192.168.5.200:7077 --num-executors 2 --driver-memory 124m --executor-memory 124m --total-executor-cores 2 /root/spark/hcy/spark-example.jar`
58 | //需要注意的是,在设置core数以及内存时,最好先参考一下spark-master-id:8080页面中的worker参数,别超过了就行。
59 | * 跑完了,直接到输出文件夹下,找到代码的输出结果即可。
60 | 61 | ###2.4 附加说明 62 | >在实际的调试过程中,我们会把ALS的几个重要参数,比如迭代次数,比如lambda值等,设置成一个范围,然后进行逐步调优,当MSE值,也就是均根方差值最小时,这个模型即我们需要的训练模型。
63 | 64 | ##3 协同推荐ALS算法进阶--电影推荐实例 65 | ###3.1 数据准备 66 | **当前用户(需要给这货做推荐)评分数据(11条)personalRatings.txt
67 | >格式 用户ID::电影ID::评分::时间戳**
68 | >0::1::5::1409495135
69 | 0::780::4::1409495135
70 | 0::590::3::1409495135
71 | 0::1216::4::1409495135
72 | 0::648::5::1409495135
73 | 0::344::3::1409495135
74 | 0::165::4::1409495135
75 | 0::153::5::1409495135
76 | 0::597::4::1409495135
77 | 0::1586::5::1409495135
78 | 0::231::5::1409495135
79 | 80 | **电影信息数据(3706条)movies.dat
81 | >格式: 电影ID::电影名称::类型**
82 | >1::Toy Story (1995)::Animation|Children's|Comedy
83 | 2::Jumanji (1995)::Adventure|Children's|Fantasy
84 | 3::Grumpier Old Men (1995)::Comedy|Romance
85 | 4::Waiting to Exhale (1995)::Comedy|Drama
86 | 5::Father of the Bride Part II (1995)::Comedy
87 | 6::Heat (1995)::Action|Crime|Thriller
88 | 7::Sabrina (1995)::Comedy|Romance
89 | 8::Tom and Huck (1995)::Adventure|Children's
90 | 9::Sudden Death (1995)::Action
91 | 92 | **用户电影评分信息数据(1000209条)ratings.dat
93 | >格式: 用户ID::电影名称::评分::时间戳**
94 | >3::260::5::978297512
95 | 3::2858::4::978297039
96 | 3::3114::3::978298103
97 | 3::1049::4::978297805
98 | 3::1261::1::978297663
99 | 3::552::4::978297837
100 | 3::480::4::978297690
101 | 4::1265::2::978298316
102 | 4::1266::5::978297396
103 | 4::733::5::978297757
104 | 105 | 上传到hdfs的/spark/mllib/data/als2路径中。
106 | 107 | ###3.2 代码打包 108 | * 在Intellij中,点击file->选择project structure->选择Artifact->添加jar->把乱七八糟的依赖移除->勾选Build on make。
109 | * 点击Build->选择Build Artifact->选择ReBuild,然后在之前填写的路径下找到jar。
110 | * 上传到spark中。
111 | 112 | ###3.3 执行代码 113 | * 执行命令`./spark-submit --class com.blogchong.spark.mllib.advance.ALSRecommendMovie.AlsArithmeticPractice --master spark://192.168.5.200:7077 --num-executors 2 --driver-memory 400m --executor-memory 400m --total-executor-cores 2 /root/spark/hcy/spark-example.jar`
114 | //需要注意的是,在设置core数以及内存时,最好先参考一下spark-master-id:8080页面中的worker参数,别超过了就行。
115 | * 跑完了,直接到输出文件夹下,找到代码的输出结果即可。
116 | 117 | ###3.4 附加说明 118 | >在调试过程中,把ALS的几个重要参数,比如迭代次数,比如lambda值等,设置成一个范围,然后进行逐步调优,当MSE值,也就是均根方差值最小时,这个模型即我们需要的训练模型。
119 | 120 | ###3.5 输出结果 121 | >对于每次尝试的结果直接打印,最终给用户0推荐的结果按降序保存在/spark/mllib/result/als2/data/recommendations,模型文件保存在/spark/mllib/result/als2/model。 122 | 123 | 124 | ##4 LDA主题特征抽取实例 125 | 126 | ###执行命令 127 | 128 | > 批量文档训练:获取训练文档的Docs-Topics概率矩阵,以及Words-Topics概率矩阵,当然,还有Model文件,这是后期预测新文档的基础. 129 | 130 | * 训练执行命令`./spark-submit --class com.blogchong.spark.mllib.advance.LdaExtractTopics.Train.LDAModelBuild --master spark://192.168.25.10:7077 --conf "spark.driver.extraJavaOptions=-XX:MaxPermSize=512m" --conf "spark.executor.extraJavaOptions=-XX:MaxPermSize=512m" --executor-memory 6G --driver-memory 6G --num-executors 4 --executor-cores 4 --jars /root/hcyLda/spark-example-1.0-SNAPSHOT.jar XX PdataPath /hcy/lda/train/part-r-00000-write PmodelPath /hcy/lda/model PtopicSize 100 PmaxIterations 100 PwordsPath /hcy/lda/train/extract_index.dic PsaveVector true > ~/hcyLda/20151219.log 2>&1` 131 | 132 | > 新文档主题预测:利用上面训练得到的LocalLDAMoldel,进行新文档的主题预测,求docs-topics矩阵,然后结合Model中已有的Topics-words矩阵,求docs-words矩阵 133 | 134 | * 测试执行命令`./spark-submit --class com.blogchong.spark.mllib.advance.LdaExtractTopics.Check.PredictsDocTopics --master spark://192.168.25.10:7077 --conf "spark.driver.extraJavaOptions=-XX:MaxPermSize=512m" --conf "spark.executor.extraJavaOptions=-XX:MaxPermSize=512m" --executor-memory 6G --driver-memory 6G --num-executors 1 --executor-cores 1 --jars /root/hcyLda/spark-example-1.0-SNAPSHOT.jar XX PdataPath /hcy/lda/data/test.data PmodelPath /hcy/lda/model/2015-12-23-23-32-00/localLdaModel PtopicsPath /hcy/lda/data PtopicSize 200 PwordsPath /hcy/lda/train/extract_index.dic > ~/hcyLda/201512231544.log 2>&1` 135 | 136 | ##5 新词发现(基于Ansj工具) 137 | 138 | ###执行命令 139 | 140 | * 训练执行命令`./spark-submit --class com.blogchong.spark.mllib.advance.DiscoveryNewWord.AnsjDisWords --master spark://192.168.25.10:7077 --conf "spark.driver.extraJavaOptions=-XX:MaxPermSize=512m" --conf "spark.executor.extraJavaOptions=-XX:MaxPermSize=512m" --executor-memory 3G --driver-memory 3G --num-executors 1 --executor-cores 1 --jars /root/hcyLda/newWord/spark-example-1.0-SNAPSHOT.jar,/root/hcyLda/newWord/ansj_seg-0.9.jar,/root/hcyLda/newWord/tree_split-1.0.1.jar --driver-library-path /root/hcyLda/newWord/ansj_seg-0.9.jar /root/hcyLda/newWord/tree_split-1.0.1.jar /hcy/newWord/data/11 /hcy/newWord/result` 141 | 142 | ##6 新词发现(基于NGram算法的Spark实现) 143 | 144 | ###执行命令 145 | 146 | * 执行命令`./spark-submit --class com.blogchong.spark.mllib.advance.DiscoveryNewWord.NGramSpark --master spark://192.168.25.10:7077 --conf "spark.driver.extraJavaOptions=-XX:MaxPermSize=512m" --conf "spark.executor.extraJavaOptions=-XX:MaxPermSize=512m" --executor-memory 6G --driver-memory 18G --num-executors 3 --executor-cores 3 --jars /root/hcyLda/newWord/spark-example-1.0-SNAPSHOT.jar,/root/hcyLda/newWord/ansj_seg-0.9.jar,/root/hcyLda/newWord/tree_split-1.0.1.jar,/root/hcyLda/newWord/json-lib-2.4-jdk13.jar,/root/hcyLda/newWord/ezmorph-1.0.6.jar /root/hcyLda/newWord/spark-example-1.0-SNAPSHOT.jar /hcy/newWord/data/userLibrary.dic /hcy/newWord/data/11 /hcy/newWord/result > ~/hcyLda/newWord/20160118.log` 147 | -------------------------------------------------------------------------------- /data/discoveryWord/dis-word-part-00023-opt: -------------------------------------------------------------------------------- 1 | font-family 2 | vertical-align 3 | 售票窗口 4 | 安全组 5 | 图形缓冲区 6 | 去雾 7 | 抗变 8 | 要素类 9 | gdt表 10 | 写者 11 | rtp数据 12 | 提取器 13 | user_agent 14 | nat转换 15 | 虚拟运行 16 | read_lock 17 | 流程浅析 18 | surfaceflinger服务 19 | 任务栈 20 | 意图对象 21 | 注释类型 22 | phone状态 23 | 传输地址 24 | render进程 25 | 界面外观 26 | build_system 27 | 错误响应 28 | power_supply 29 | 单面板 30 | 局部变量数组 31 | sql节点 32 | 全文目录 33 | 顺序锁 34 | gpu进程 35 | 分配粒度 36 | ffmpeg源代码 37 | 暗通道 38 | session数据 39 | wms服务 40 | 兼容级别 41 | store节点 42 | 霍夫变换 43 | start_code 44 | 线程pool 45 | 滤波法 46 | 重写规则 47 | schedule_timeout 48 | 输入子系统 49 | fd_set 50 | 纤程 51 | socket描述 52 | body对象 53 | 辅助索引 54 | xp_cmdshell 55 | 工作项 56 | signal_pending 57 | 资料表 58 | 数据捕获 59 | 管理节点 60 | 性能视图 61 | using指示 62 | 败者树 63 | project元素 64 | 同步框架 65 | 会话bean 66 | current_session 67 | 段界限 68 | 年轻代 69 | 弱符号 70 | session文件 71 | 类厂 72 | 核心动画 73 | gatt服务 74 | settings跳转 75 | 父rdd 76 | zi类 77 | 过滤规则 78 | 划分数 79 | mysql_fetch_array 80 | 降序数组 81 | 立即数 82 | 界面线程 83 | 国际化消息 84 | arp请求 85 | 本尊 86 | 检索策略 87 | 脏页面 88 | riff文件 89 | compatible属性 90 | buf_type 91 | session隔离 92 | rtpsession类 93 | 操作视窗 94 | 贝叶斯算法 95 | open列表 96 | id_file 97 | 事件过滤器 98 | dll_thread_attach 99 | irq_desc 100 | 旋锁 101 | 远程对象 102 | 延迟检索 103 | crontab文件 104 | 提权 105 | set_fd 106 | thread-count 107 | dllmain函数 108 | 目标场景 109 | tcp段 110 | scn号 111 | withevent方法 112 | nat穿透 113 | pthread_rwlock_init 114 | hp-socket 115 | session初始化 116 | 标签处理器 117 | 强符号 118 | 事务id 119 | 活动对象 120 | 共享函数 121 | activity组件 122 | rtp包 123 | bitset对象 124 | 产品族 125 | 缓存项 126 | ngx_http 127 | aopproxy代理 128 | 推荐列表 129 | 互斥对象 130 | 子块 131 | lob类型 132 | 共享函数库 133 | activitymanagerservice服务 134 | 添加商品 135 | product_out 136 | system_window 137 | json_object 138 | record结构 139 | 导向图 140 | javaweb工程 141 | kitkatphone工作 142 | 副本集 143 | 层次聚类 144 | 返回页 145 | corp节点 146 | 帧缓存 147 | 位域 148 | overflow按钮 149 | 传输控制块 150 | 处理例程 151 | hash_map 152 | 丑数 153 | 深度测试 154 | browser进程 155 | 数据标签 156 | 快速窗口 157 | soap消息 158 | 数据节点 159 | 语法解析器 160 | 马氏距离 161 | 面板布局 162 | 消息块 163 | 屏蔽信号 164 | 数据库集成 165 | 拖尾 166 | criteria查询 167 | uitableviewcell对象 168 | 右值 169 | 游戏模式 170 | 旋转算法 171 | 平均滤波 172 | 商品列表 173 | 动态函数库 174 | 设计问题 175 | closed列表 176 | 输入分片 177 | 闭包表达式 178 | idle进程 179 | 页面空间 180 | 宽依赖 181 | 引用逸出 182 | 类型擦除 183 | socket描述字 184 | 游戏邦 185 | toast通知 186 | 实际用户 187 | 规则文件 188 | 窗口修饰 189 | 终结节点 190 | 应用空间 191 | 宿主语言 192 | cdata段 193 | 加密体制 194 | 视图名称 195 | 实时流 196 | 孤儿进程 197 | java栈 198 | dll_process_attach 199 | auto_ptr 200 | 短链 201 | 存储属性 202 | 中断处理 203 | alpha混合 204 | 描述字 205 | 地址结构 206 | deb-src 207 | 人脸图像 208 | pthread_detach 209 | 特殊权限 210 | 实时传输 211 | nfc标签 212 | 病毒编号 213 | 组合索引 214 | machine-name 215 | proto文件 216 | 记录锁 217 | 缓存行 218 | 页框 219 | 模式串 220 | 纹素 221 | shelldll_defview 222 | 桥方法 223 | 外部存储介质 224 | 表变量 225 | 动态性能视图 226 | 栋栋 227 | 堆内存heap 228 | 导向滤波 229 | lock函数 230 | 脉冲干扰 231 | 捕获机制 232 | 奇圈 233 | 私有地址 234 | 取票 235 | hashentry数组 236 | 顶点函数 237 | job参数 238 | storm集群 239 | ntp时间 240 | slave进程 241 | 依赖范围 242 | 安装副本 243 | id_edit_copy 244 | 物理menu 245 | 序列化形式 246 | 汇编地址 247 | dll_process_attach 248 | 调用bean 249 | 路径表 250 | 日志清理 251 | stream_type 252 | 主站点 253 | 坐标轴范围 254 | 标记文本 255 | 帧缓冲 256 | 范围扫描 257 | 拖拽事件 258 | 校验器 259 | 自定义功能 260 | state模式 261 | file_operations 262 | 命令执行器 263 | region_id 264 | 中断处理 265 | 平衡因子 266 | 原根 267 | 残量 268 | hprof文件 269 | dbf文件 270 | ble设备 271 | pthread_cond_wait 272 | 钩子方法 273 | jni编程 274 | rtp会话 275 | 伪元素 276 | 睡眠模式 277 | 半连接 278 | 共用体 279 | 黑球 280 | poi检索 281 | 局部引用 282 | 硬链接 283 | 结构元素 284 | 框架层 285 | 后端服务器 286 | 内存池 287 | 特权级 288 | request函数 289 | 类地址 290 | 控制块 291 | 注册中心 292 | 特征点 293 | 职责链 294 | 周期数 295 | zygote进程 296 | 胜者树 297 | 双向队列 298 | instead_of触发器 299 | 桶排序 300 | before触发器 301 | spi设备 302 | 代码运行图 303 | 求解树 304 | 白球 305 | 公共长度 306 | 嵌套表 307 | 远端仓库 308 | video_capture 309 | survivor区域 310 | 行光标 311 | js数组 312 | 点云 313 | 按键音 314 | sensoreventlistener接口 315 | 情感倾向 316 | 更新脚本 317 | smali文件 318 | 物理仿真 319 | 参考帧 320 | 浸入式 321 | 奇异态 322 | 硬解码 323 | 转移次数 324 | 目的寄存器 325 | 帧间预测 326 | return-einval 327 | loop对象 328 | 加壳 329 | 列族 330 | binder驱动程序 331 | 位带操作 332 | wm_drawitem 333 | entry链 334 | connectionstrings配置 335 | 动态函数 336 | non-fast-forward 337 | 媒体流 338 | iic总线 339 | play应用 340 | tiddata块 341 | might_sleep 342 | 灰度变换 343 | next_date 344 | 隐函数 345 | 喷水装置 346 | 立即检索 347 | 伪目标 348 | 切比雪夫距离 349 | 并行化 350 | size-cells 351 | do_select 352 | autowired注释 353 | nagios监测 354 | dll_process_detach 355 | 子分区 356 | 优惠劵 357 | component类 358 | interface方式 359 | gui组件 360 | word_count 361 | resultsethandler实现 362 | gen_server 363 | cfs调度 364 | 面版 365 | slot函数 366 | 滑动块 367 | 阶码 368 | network-manager 369 | erlang节点 370 | scoped_ptr 371 | commit历史 372 | cmyk模式 373 | 缓冲设备 374 | crash日志 375 | 设置gpio 376 | cast转换 377 | longjmp函数 378 | 内存示意图 379 | pthread_key 380 | ssl协议 381 | writablecomparable接口 382 | avio_open 383 | 自动回复 384 | 函数节流 385 | 写锁 386 | 委托类 387 | 就绪队列 388 | 工作内存 389 | 服务时间 390 | 条件变量 391 | socket通道 392 | 可变集合 393 | 颜色表 394 | wait_event 395 | 内核抢占 396 | 等价类 397 | url标签 398 | 抽象路径名 399 | 互斥量 400 | timestamp列 401 | 动态性能 402 | 逻辑块号 403 | 物理块号 404 | 数据报文 405 | 鸽巢 406 | 鸽巢原理 407 | survivor区 408 | 资源计数 409 | sheet页 410 | innodb表 411 | hello-hello 412 | out事件 413 | 负载类型 414 | 前台服务 415 | cms收集器 416 | jit编译器 417 | 逸出 418 | 控制终端 419 | 虚基类 420 | 状态模式 421 | core文件 422 | 画刷 423 | binder驱动 424 | 主串 425 | pthread_once 426 | 父坐标 427 | nulls说明 428 | session生命周期 429 | open_cache 430 | oaf框架 431 | 麦可网 432 | rmi调用 433 | 长度类型 434 | simplest_ffmpeg_remuxer 435 | 滑动动画 436 | http_core 437 | 灰度模式 438 | 偏移坐标 439 | dc算法 440 | 匈牙利树蜂 441 | 顺序文件 442 | android镜像 443 | list块 444 | 脚本编程 445 | 工厂等级 446 | 再哈希 447 | 频繁项 448 | 文章分页 449 | mysql_connect 450 | rtp时间戳 451 | 号码本 452 | 搜索区域 453 | 源代码程序 454 | drawitem消息 455 | component注释 456 | reqsk_queue 457 | 频率域 458 | 切词 459 | initrd文件 460 | 停止等待协议 461 | 增量索引 462 | 后缀操作符 463 | 输出属性 464 | 托管资源 465 | 非托管资源 466 | 并行收集 467 | 正样本 468 | surface对象 469 | ftp客户端 470 | swift教程 471 | speak方法 472 | 模式对话框 473 | data-widget-config 474 | block块 475 | 正交矩阵 476 | 直交矩阵 477 | heap视图 478 | 计算引擎 479 | 重力传感器 480 | 活动记录 481 | 实例表 482 | gap优化 483 | property_read 484 | public_key 485 | dir结构 486 | 空间容量 487 | 块划分 488 | fb设备 489 | 异步编程 490 | flash演示 491 | 描述符索引 492 | 内置锁 493 | rtp数据包 494 | 短信验证 495 | 死亡骑士 496 | 字节区 497 | 长腿 498 | rigidbody组件 499 | 虚拟运行时间 500 | 等待队列机制 501 | spi控制器 502 | 指针悬挂 503 | 特性分支 504 | rpm-gpg 505 | 平台游戏开发 506 | right-angled 507 | 魔术字 508 | 帧内预测 509 | loadview方法 510 | 地址offset 511 | 导航面板 512 | for死循环 513 | 隶属度 514 | 抢占式调度 515 | beanutils包 516 | 解答树 517 | 参数集 518 | 空闲节点 519 | 失性存储器 520 | 聚合器 521 | 非静态属性 522 | 需求说明书 523 | 计算上限 524 | 动态语句 525 | 反射型 526 | 超步 527 | 终止方法 528 | messagedigest对象 529 | 迷途指针 530 | rpc函数 531 | 空闲堆 532 | 进程组 533 | 低通滤波 534 | 卷组 535 | time_wait 536 | 项集 537 | 内存索引 538 | piggy-bank 539 | platform_device 540 | 语法解析 541 | 用户账户 542 | 外部类 543 | 懒加载 544 | 非正式协议 545 | 程序进程 546 | 办理业务 547 | socket服务 548 | 类加载器 549 | storyboard文件 550 | 函数原形 551 | mediaplayer对象 552 | can总线 553 | repeater控件 554 | 匿名类型 555 | 静态嵌套 556 | 对齐模数 557 | root结点 558 | world对象 559 | 内存heap 560 | random对象 561 | key_value 562 | 分类标签 563 | 线性地址 564 | one标签 565 | 位图排序 566 | 货币系统 567 | 网站编号 568 | 跨立 569 | nginx负载 570 | 广播接收器 571 | 建造者 572 | 像素密度 573 | 映射区 574 | 根堆 575 | 慢查询 576 | lamp对象 577 | 二进制日志 578 | threadlocal实例 579 | 左偏树 580 | 右偏树 581 | 杀敌数 582 | 关联规则 583 | 加速度传感器 584 | property元素 585 | handle_irq 586 | 覆盖集 587 | 常量池 588 | 地址表 589 | dts文件 590 | 虚拟系统 591 | 优先数 592 | 优先数系 593 | 大顶堆 594 | 小顶堆 595 | 僵尸对象 596 | 操作集 597 | board_init_f 598 | com库 599 | xss攻击 600 | a星算法 601 | 日志组 602 | 序数组 603 | 页目录 604 | pthread_mutex_t 605 | 伸展树 606 | 内核对象 607 | 商品id 608 | character_set_server 609 | 隐式对象 610 | lambda表达式 611 | view对象 612 | 引用计数器 613 | 局部类 614 | 责任链模式 615 | 重定位 616 | dispatchtouchevent方法 617 | 异步通知 618 | 程序分析 619 | 虚继承 620 | 对端IP 621 | 工兵营地 622 | 布局管理 623 | 阻塞模式 624 | 块元素 625 | shared_ptr 626 | 程序集 627 | 弱引用 628 | 初始化块 629 | 虚基类 630 | 外键 631 | prototype模式 632 | description方法 633 | derived对象 634 | 强分类器 635 | merge操作 636 | 学生学籍 637 | binder_thread 638 | 分组密码 639 | 客户浏览器 640 | 光照模式 641 | 光栅化 642 | 全局引用 643 | crontab命令 644 | backtrace_symbols 645 | httpd服务 646 | webbrowser组件 647 | 脉宽 648 | 着色程序 649 | extern类型 650 | js嵌入 651 | 点轴 652 | javaclass文件 653 | 卷管理 654 | 内核锁 655 | 内核页 656 | vao对象 657 | 目标资源 658 | 注释标记 659 | 普通参数 660 | 营业情况 661 | pendingintent对象 662 | 节点target参数 663 | 槽位 664 | 导航窗 665 | 网络事件 666 | 全匹配 667 | sequence序列 668 | worker节点 669 | 标准关联 670 | 水王 671 | 静态构造 672 | 解码decode 673 | 预补偿 674 | 强顺序 675 | 模板测试 676 | 睡眠唤醒 677 | vip客户 678 | 优化函数 679 | 秩优化 680 | 查询串 681 | tabcontrol控件 682 | aoe网 683 | set_terminate 684 | 最大承载 685 | 裁减区域 686 | flood攻击 687 | where筛选 688 | 引导扇区 689 | mysql_field_name 690 | car类 691 | 音频资源 692 | 状态节点 693 | opengl命令 694 | 编码代码 695 | 费纳波契序列 696 | 裴波那契序列 697 | 内容页 698 | 弱分类 699 | 程序协议 700 | 执行模式 701 | 引用队列 702 | interruptible状态 703 | devices视图 704 | sub-string 705 | android内容提供器 706 | 逆向队列 707 | 弱分类器 708 | 验证框架 709 | user模型 710 | ddos攻击 711 | 交叉业务 712 | 弦图 713 | 双面板宽 714 | 托管堆 715 | 运输层 716 | dma控制器 717 | 特殊日期 718 | socket输出流 719 | token令牌 720 | 估价函数 721 | log系统 722 | osal_wmem_alloc 723 | 表状态 724 | gets命令 725 | 过滤机制 726 | 集合容器类 727 | getopt函数 728 | dense_rank 729 | 程序集清单 730 | write_lock 731 | item项 732 | 进程数目 733 | 高层组件 734 | 动态图层 735 | material主题 736 | 图像去雾算法 737 | 片段着色器 738 | 公共域 739 | the-sequence 740 | 底层文件 741 | 好莱坞原则 742 | sobel算子 743 | 指示点 744 | 转换文件 745 | phonewindow类 746 | 离线下载 747 | disconnect函数 748 | 动态列表 749 | 唤醒状态 750 | 弱学习算法 751 | 交集部分 752 | 存储段描述符 753 | beautifulsoup对象 754 | to_days 755 | 等级结构 756 | path对象 757 | 文件modulea 758 | 窄依赖 759 | 免费电话 760 | proc_dir_entry 761 | 左扩展 762 | 新建进程 763 | access_token 764 | 模型函数 765 | address-cells 766 | 扩展段 767 | 适配者模式 768 | 通道号 769 | df标志 770 | spin_unlock宏 771 | 接口隔离原则 772 | 观察序列 773 | 笨小熊 774 | 外部工具 775 | 动态联结 776 | atexit函数 777 | 表错误 778 | hello_world 779 | 消息长度 780 | 距离标号 781 | 水位标记 782 | dom对象 783 | rst包 784 | 目标元素 785 | hiddenfield控件 786 | 策略路由 787 | 导航控制器 788 | 标签技术 789 | node_identifier 790 | 局部环境 791 | 标签应用 792 | 附加属性 793 | 功能寄存器 794 | 编辑方式 795 | uevent_ops 796 | 信号屏蔽 797 | 剪枝算法 798 | 已用空间 799 | 通信组件 800 | dispatch_group 801 | mime-type 802 | mat文件 803 | device_package_overlays 804 | product_package_overlays 805 | dup函数 806 | 图层类 807 | singleinstance模式 808 | 局部类型 809 | 加权轮转调度算法 810 | 后置通知 811 | syn包 812 | 异常捕获机制 813 | 上下文定义 814 | apt工具 815 | 集合视图 816 | 失败指针 817 | http框架 818 | 内建命令 819 | 美观程度 820 | 云硬盘 821 | babab模式 822 | daemon线程 823 | usb总线 824 | usermanager接口 825 | cs设计 826 | 转换运算符 827 | 调整算法 828 | 自然对齐 829 | 混合模型 830 | 应用模式 831 | double-kwic-index 832 | 源矩形 833 | thread_info 834 | onhandleintent方法 835 | mcontentparent对象 836 | 字符编码方式 837 | dp设置 838 | 驾车路线 839 | 外部联接 840 | 重建索引 841 | spark_worker_menory 842 | spark_worker_core 843 | 滚动块 844 | 输入源 845 | hittestwithevent方法 846 | 滚动框 847 | 驻留池 848 | high-low 849 | sst文件 850 | 物理卷 851 | 同步关系 852 | 客户接口 853 | 静态构造函数 854 | winmain函数 855 | 硬中断 856 | derived类 857 | 作业类 858 | drop事件 859 | 新闻阅读器 860 | 识别符 861 | 组合算法 862 | 属性页 863 | start-point 864 | 梯度上升算法 865 | 作用对象 866 | put_user 867 | 预载 868 | click事件函数 869 | hdf文件 870 | 衍合 871 | 设备描述符 872 | remote接口 873 | head对象 874 | 内核目录 875 | 幸运数 876 | usb设备 877 | 启动事务 878 | img镜像 879 | 窗口实例 880 | 聚簇索引 881 | param标签 882 | prehandle方法 883 | 适配器驱动 884 | 新朋友 885 | sharedpreferences数据 886 | rank函数 887 | 对象模板 888 | list_entry 889 | 事务信息 890 | 匿名内存 891 | 跳跃表 892 | ebx寄存器 893 | 链接标签 894 | 双括号 895 | 方法表 896 | 上层逻辑 897 | nat操作 898 | 增广路 899 | 僵尸进程 900 | 连接队列 901 | clone方法 902 | 对称加密 903 | 重复提交 904 | wait_queue 905 | const修饰 906 | 双连通分量 907 | logistic回归 908 | copy_from_user 909 | socket描述符 910 | 原型模式 911 | 外围类 912 | classloader类 913 | 虚拟网络 914 | local_module_class 915 | 逆序对 916 | objc_msgsend 917 | sql语法 918 | worker进程 919 | init进程 920 | 分析函数 921 | map集合 922 | 意图过滤器 923 | 倍增算法 924 | 字符串池 925 | null字符 926 | 根对象 927 | 地精商人 928 | 正式协议 929 | 中断处理程序 930 | 关联对象 931 | 字节代码 932 | finalize方法 933 | hive数据 934 | 公平调度 935 | 二次排序 936 | 号码管理 937 | 密钥库 938 | demo工程 939 | struct_board_info 940 | 运行地址 941 | 定位信息 942 | arp包 943 | 双缓冲 944 | udp数据报 945 | 共享中断 946 | 前置声明 947 | 主题角色 948 | 后缀表达式 949 | to_date 950 | 引用计数 951 | wifi状态 952 | 目的主机 953 | cookie对象 954 | 目录项 955 | 上下文容器 956 | 写缓存 957 | entry对象 958 | 目标窗口 959 | 视图函数 960 | 投票结果 961 | 软中断 962 | 分组函数 963 | 开关操作 964 | export_symbol 965 | 读锁 966 | 消息映射 967 | 自动变量 968 | keep-alive 969 | eax寄存器 970 | wait状态 971 | binder对象 972 | 装饰类 973 | 父类 974 | 属性表 975 | ioc容器 976 | usb驱动 977 | decimal类型 978 | static数据成员 979 | 注解处理器 980 | systemserver进程 981 | intent对象 982 | 线性加速度 983 | 推荐方案 984 | declare-styleable 985 | ip_hash 986 | 启动模式 987 | source类 988 | 容器集合 989 | object文件 990 | net服务器 991 | global对象 992 | api库 993 | pair对象 994 | 单调栈 995 | platform设备 996 | 反素数 997 | 处理层 998 | 威威 999 | 第三方应用程序 1000 | socket结构 1001 | 参数签名 1002 | 服务器证书 1003 | 设备模型 1004 | 数据权限 1005 | 过滤操作 1006 | initrc文件 1007 | epoll事件 1008 | 单类 1009 | 响应文件 1010 | 启动请求 1011 | am文件 1012 | 核心态 1013 | 普通表 1014 | 设备结点 1015 | case常量 1016 | curl_easy_perform 1017 | linux命令行 1018 | 候选对象 1019 | 非聚集索引 1020 | lu系统 1021 | 偏函数 1022 | 滤波方法 1023 | 功能快捷键 1024 | 相机应用 1025 | mother类 1026 | 最小点权覆盖 1027 | fun方法 1028 | 幂等性 1029 | 验证器 1030 | 积分图像 1031 | 类型转换器 1032 | 聊天消息 1033 | unsafe_unretained 1034 | 应用程序域 1035 | ubuntu镜像 1036 | 位图排序 1037 | 临时节点 1038 | jquery类 1039 | sighup信号 1040 | raii对象 1041 | roi区域 1042 | 动态sql 1043 | invalidate流程 1044 | 成功响应 1045 | 外连接 1046 | 实体bean 1047 | 工厂方法 1048 | 操作栏 1049 | lamp类 1050 | 大根堆 1051 | obj对象 1052 | 单向关联 1053 | 中文分词 1054 | 互斥锁 1055 | 梯度下降 1056 | dispatch_queue 1057 | 特征码 1058 | 目标组件 1059 | 嵌套类 1060 | aidl文件 1061 | 回文子串 1062 | 模板方法模式 1063 | 工厂方法模式 1064 | haar特征 1065 | ack包 1066 | 随机数种子 1067 | 连接串 1068 | 基础表 1069 | text-decoration 1070 | private_data 1071 | scanf函数 1072 | session变量 1073 | 共享锁 1074 | 账户信息 1075 | 组件对象模型 1076 | avi文件 1077 | int-identity 1078 | va_start 1079 | 拷贝构造函数 1080 | http模块 1081 | pthread_cleanup_push 1082 | pthread_cleanup_pop 1083 | 深度克隆 1084 | jstl标签 1085 | customer_id 1086 | 硬件地址 1087 | 整数函数 1088 | cgi程序 1089 | 子空间 1090 | rtp协议 1091 | pattern对象 1092 | 窗口布局 1093 | 导出函数 1094 | 调用约定 1095 | context-param 1096 | 时钟周期 1097 | 同步函数 1098 | 代理对象 1099 | 相度 1100 | 负载因子 1101 | const_iterator 1102 | bindservice方法 1103 | 式套 1104 | 控制文件 1105 | vip窗口 1106 | 懒汉模式 1107 | 提交状态 1108 | 虚拟继承 1109 | 外部状态 1110 | 删除器 1111 | 右孩子 1112 | 方法摘要 1113 | 执行耗时 1114 | 本地仓库 1115 | 关联映射 1116 | 深拷贝 1117 | 形图 1118 | 页首 1119 | run方法 1120 | apk包 1121 | sim卡 1122 | 强引用 1123 | 传输控制 1124 | looper对象 1125 | 智能指针 1126 | 临界区 1127 | 简单工厂模式 1128 | 类加载 1129 | 运行时区 1130 | 离屏渲染 1131 | 验证规则 1132 | from属性 1133 | socket实战 1134 | 喜爱程度 1135 | 密集型任务 1136 | singletop模式 1137 | repo仓库 1138 | 钥匙串 1139 | 出栈算法 1140 | 入栈算法 1141 | 空间使用率 1142 | xml编辑器 1143 | list_for_each 1144 | 带权路径 1145 | 父母节点 1146 | bab模式 1147 | 父加载器 1148 | 二级索引 1149 | 覆盖模型 1150 | 输出电压 1151 | 模式规则 1152 | io复用 1153 | 父函数 1154 | uitouch对象 1155 | matlab仿真 1156 | scrollby方法 1157 | ocx控件 1158 | remoting-config.xml 1159 | 基准时间 1160 | 包装集 1161 | 父窗 1162 | page_size 1163 | http_conf 1164 | 堆管理器 1165 | 环回 1166 | movie对象 1167 | 代理程序 1168 | cache-control 1169 | 卷积层 1170 | 协议处理器 1171 | 短信信息 1172 | 唯一索引 1173 | 命令列表 1174 | 相遇点 1175 | responsetext属性 1176 | 代理ip 1177 | 捕获组 1178 | 非捕获组 1179 | 手写栈 1180 | 计时器对象 1181 | invited_nodes 1182 | sed编辑器 1183 | 魔术方法 1184 | jsp-file 1185 | array_buffer 1186 | 左子节点 1187 | 二维rmq 1188 | gralloc模块 1189 | 组合函数 1190 | 指标计算 1191 | html元件 1192 | 核心协议 1193 | rpc消息 1194 | 抽屉原理 1195 | 数据库链接 1196 | 写句柄 1197 | bootstrap-datetimepicker 1198 | unix_timestamp 1199 | 深度解剖 1200 | queue消息队列 1201 | curl_global_init 1202 | 故事板 1203 | 解码流程 1204 | 聚类中心 1205 | 异常模式 1206 | 移动存储 1207 | day_of_week 1208 | doc类 1209 | 后验概率 1210 | 主键id 1211 | 异常模型 1212 | syslog函数 1213 | windows类 1214 | cast表达式 1215 | 控制元素 1216 | tcp_keepalive 1217 | 原生字符串 1218 | is_ref_gc 1219 | 区间外 1220 | 按秩合并 1221 | app包 1222 | 悍马 1223 | 慕课 1224 | qq互联 1225 | arm开发板 1226 | opengl库 1227 | 扩展分区 1228 | 实验效果 1229 | progress_display 1230 | 增益率 1231 | imwrite函数 1232 | 数据表结构 1233 | cursor_variable 1234 | wake_lock 1235 | target元素 1236 | 碎片率 1237 | 响应消息头 1238 | sock_init 1239 | 双端链表 1240 | 二级指针 1241 | 随机字符串 1242 | father类 1243 | 调度类 1244 | net-snmp 1245 | color函数 1246 | 向量类 1247 | 名称声明 1248 | tga文件 1249 | tftp-server 1250 | logistic函数 1251 | 过滤表达式 1252 | 控制项 1253 | inplace_merge 1254 | gatt服务器 1255 | udp数据包 1256 | 确认报文 1257 | 汇编函数 1258 | 奇数阶 1259 | redirect_uri 1260 | pthread_rwlockattr_init 1261 | lazy初始化 1262 | 待删 1263 | shell扩展 1264 | 保留表 1265 | 离散点 1266 | crond服务 1267 | 差异报告 1268 | 基因序列 1269 | 磁盘块 1270 | 连接描述符 1271 | findfirst函数 1272 | request_threaded_irq 1273 | cas命令 1274 | 嵌套属性 1275 | resultsethandler实现类 1276 | 右健 1277 | 世界矩阵 1278 | systemserver类 1279 | shell提示 1280 | android属性 1281 | 隔离原则 1282 | 深度拷贝 1283 | 移动窗 1284 | compile-time 1285 | events域 1286 | 虚拟机进程 1287 | 变换方法 1288 | curl_easy_setopt 1289 | 内存片段 1290 | 帧指针 1291 | 衰减因子 1292 | 操作区域 1293 | transaction命令 1294 | 兰州烧饼 1295 | 缩放系数 1296 | jni对象 1297 | 数据手册 1298 | 字符串表达式 1299 | 等式约束 1300 | 颜色模式 1301 | 构建规则 1302 | 响应报头 1303 | 描述词组 1304 | abstractclass方式 1305 | select方法 1306 | 填充方式 1307 | 回归问题 1308 | heap内存 1309 | 地址字节 1310 | 跨平台游戏 1311 | 代理函数 1312 | xml声明 1313 | 点球大战 1314 | cx_oracle 1315 | os-ii 1316 | msg函数 1317 | 程序题 1318 | commandargument属性 1319 | must-revalidate 1320 | android签名 1321 | 注释驱动 1322 | 存储类别 1323 | alloc_netdev 1324 | account_type 1325 | 内容分发 1326 | overlapped结构 1327 | cume_dist 1328 | 消息中心 1329 | session数组 1330 | swap分区 1331 | 安装函数 1332 | 工作分配 1333 | 处理器缓存 1334 | org语句 1335 | 序转换到 1336 | ajax验证 1337 | block类 1338 | poll_wait 1339 | 登录窗 1340 | 双亲表示法 1341 | 队列机制 1342 | css_set 1343 | updated_at 1344 | 网站地图 1345 | 主机字节序 1346 | find操作 1347 | control文件 1348 | 哈密顿回路 1349 | tif文件 1350 | enable函数 1351 | 出栈序列 1352 | 符号链 1353 | wait_event_interruptible 1354 | unsafe类 1355 | 启发式函数 1356 | 快速失败 1357 | canny边缘检测 1358 | 依赖事务 1359 | 三角数 1360 | com_test 1361 | 信号捕捉 1362 | 采样模式 1363 | 产品等级 1364 | 环形链 1365 | 信息域 1366 | 数字下标 1367 | cycle函数 1368 | rtp库 1369 | 接收模式 1370 | 类厂对象 1371 | ontransact方法 1372 | 状态会话 1373 | 属性缓存 1374 | 填充算法 1375 | m_mmap_threshold 1376 | 当前会话 1377 | 上升算法 1378 | jdbc规范 1379 | query组件 1380 | 洗牌问题 1381 | register_encdec 1382 | cv_fourcc 1383 | usb主机 1384 | iterable对象 1385 | no_data_found 1386 | 执行入口 1387 | sobel导数 1388 | 标识对象 1389 | static_library 1390 | source命令 1391 | 服务消费者 1392 | dojo类 1393 | 触发操作 1394 | udp客户端 1395 | neon优化 1396 | scsi硬盘 1397 | 介绍页面 1398 | getopts命令 1399 | 地址库 1400 | ngx_event_s 1401 | flex项目 1402 | 产生序列 1403 | android.mk 1404 | 登录地址 1405 | 属性检查器 1406 | driver结构 1407 | 音频处理 1408 | preempt_count 1409 | ftl标签 1410 | sex男 1411 | one-two 1412 | pull方式 1413 | pyc文件 1414 | 脚本函数 1415 | 持久化对象 1416 | describe命令 1417 | boolean定义 1418 | 依赖属性 1419 | 排序准则 1420 | arg变量 1421 | http块 1422 | 引导页面 1423 | 微信易 1424 | dispatch_get_main_queue 1425 | const_ty 1426 | flag_include_stopped_packages 1427 | servlet源 1428 | 弹性域 1429 | setsortcomparatorclass设置 1430 | 源码声明 1431 | 应用模块 1432 | cpu控制 1433 | 病毒特征 1434 | com_joomsport 1435 | date命令 1436 | mmap系统调用 1437 | 共享模块 1438 | 排序命令 1439 | node应用 1440 | 父线程 1441 | 幽灵引用 1442 | final标记 1443 | 触发模式 1444 | 实时索引 1445 | 实体管理 1446 | 主索引 1447 | isvalid属性 1448 | 临时页 1449 | 接口电路 1450 | 弱引用对象 1451 | sta模式 1452 | 媒体特性 1453 | 异常向量表 1454 | 权限标志 1455 | 栈限制 1456 | graphicspath类 1457 | html安全 1458 | 日历应用 1459 | 架构视图 1460 | 授权登陆 1461 | 缓冲区分配 1462 | 事件传播 1463 | 中断号 1464 | 中断控制器 1465 | 终结符表达式 1466 | 描述表 1467 | 压缩传输 1468 | sql模板 1469 | 初级篇 1470 | 顶点着色器 1471 | logo_linux 1472 | memcached服务器 1473 | variables变量 1474 | 槽函数 1475 | 轴偏移 1476 | 域属性 1477 | touch对象 1478 | hash值 1479 | 条件运算结果 1480 | 媒体数据 1481 | 事务操作 1482 | session连接 1483 | 访问控制符 1484 | mqtt协议 1485 | first_drv 1486 | 时间比例 1487 | 操作函数原形 1488 | 线程局部存储 1489 | iphone应用程序 1490 | 模板图像 1491 | 二路归并 1492 | query_time 1493 | head引用 1494 | typeid操作符 1495 | nat模块 1496 | jni库 1497 | 自动关联 1498 | aware接口 1499 | 硬件服务 1500 | 不可靠信号 1501 | 溢出结果 1502 | 函数重构 1503 | cookie登录 1504 | dlopen函数 1505 | 业务组件 1506 | 硬件抽象层 1507 | worker对象 1508 | getdefaultsensor方法 1509 | 吞吐率 1510 | 虚指针 1511 | process_request 1512 | slave端 1513 | 事务传播 1514 | 向量加法 1515 | 购买流程 1516 | 原料厂 1517 | length字段 1518 | soapobject对象 1519 | 闵可夫斯基距离 1520 | 重心公式 1521 | pop序列 1522 | key主键 1523 | pci设备 1524 | binder实体 1525 | 配置解析 1526 | row_count 1527 | config.mk -------------------------------------------------------------------------------- /data/recommend/ml-1m/README: -------------------------------------------------------------------------------- 1 | SUMMARY 2 | ================================================================================ 3 | 4 | These files contain 1,000,209 anonymous ratings of approximately 3,900 movies 5 | made by 6,040 MovieLens users who joined MovieLens in 2000. 6 | 7 | USAGE LICENSE 8 | ================================================================================ 9 | 10 | Neither the University of Minnesota nor any of the researchers 11 | involved can guarantee the correctness of the data, its suitability 12 | for any particular purpose, or the validity of results based on the 13 | use of the data set. The data set may be used for any research 14 | purposes under the following conditions: 15 | 16 | * The user may not state or imply any endorsement from the 17 | University of Minnesota or the GroupLens Research Group. 18 | 19 | * The user must acknowledge the use of the data set in 20 | publications resulting from the use of the data set, and must 21 | send us an electronic or paper copy of those publications. 22 | 23 | * The user may not redistribute the data without separate 24 | permission. 25 | 26 | * The user may not use this information for any commercial or 27 | revenue-bearing purposes without first obtaining permission 28 | from a faculty member of the GroupLens Research Project at the 29 | University of Minnesota. 30 | 31 | If you have any further questions or comments, please contact GroupLens 32 | . 33 | 34 | ACKNOWLEDGEMENTS 35 | ================================================================================ 36 | 37 | Thanks to Shyong Lam and Jon Herlocker for cleaning up and generating the data 38 | set. 39 | 40 | FURTHER INFORMATION ABOUT THE GROUPLENS RESEARCH PROJECT 41 | ================================================================================ 42 | 43 | The GroupLens Research Project is a research group in the Department of 44 | Computer Science and Engineering at the University of Minnesota. Members of 45 | the GroupLens Research Project are involved in many research projects related 46 | to the fields of information filtering, collaborative filtering, and 47 | recommender systems. The project is lead by professors John Riedl and Joseph 48 | Konstan. The project began to explore automated collaborative filtering in 49 | 1992, but is most well known for its world wide trial of an automated 50 | collaborative filtering system for Usenet news in 1996. Since then the project 51 | has expanded its scope to research overall information filtering solutions, 52 | integrating in content-based methods as well as improving current collaborative 53 | filtering technology. 54 | 55 | Further information on the GroupLens Research project, including research 56 | publications, can be found at the following web site: 57 | 58 | http://www.grouplens.org/ 59 | 60 | GroupLens Research currently operates a movie recommender based on 61 | collaborative filtering: 62 | 63 | http://www.movielens.org/ 64 | 65 | RATINGS FILE DESCRIPTION 66 | ================================================================================ 67 | 68 | All ratings are contained in the file "ratings.dat" and are in the 69 | following format: 70 | 71 | UserID::MovieID::Rating::Timestamp 72 | 73 | - UserIDs range between 1 and 6040 74 | - MovieIDs range between 1 and 3952 75 | - Ratings are made on a 5-star scale (whole-star ratings only) 76 | - Timestamp is represented in seconds since the epoch as returned by time(2) 77 | - Each user has at least 20 ratings 78 | 79 | USERS FILE DESCRIPTION 80 | ================================================================================ 81 | 82 | User information is in the file "users.dat" and is in the following 83 | format: 84 | 85 | UserID::Gender::Age::Occupation::Zip-code 86 | 87 | All demographic information is provided voluntarily by the users and is 88 | not checked for accuracy. Only users who have provided some demographic 89 | information are included in this data set. 90 | 91 | - Gender is denoted by a "M" for male and "F" for female 92 | - Age is chosen from the following ranges: 93 | 94 | * 1: "Under 18" 95 | * 18: "18-24" 96 | * 25: "25-34" 97 | * 35: "35-44" 98 | * 45: "45-49" 99 | * 50: "50-55" 100 | * 56: "56+" 101 | 102 | - Occupation is chosen from the following choices: 103 | 104 | * 0: "other" or not specified 105 | * 1: "academic/educator" 106 | * 2: "artist" 107 | * 3: "clerical/admin" 108 | * 4: "college/grad student" 109 | * 5: "customer service" 110 | * 6: "doctor/health care" 111 | * 7: "executive/managerial" 112 | * 8: "farmer" 113 | * 9: "homemaker" 114 | * 10: "K-12 student" 115 | * 11: "lawyer" 116 | * 12: "programmer" 117 | * 13: "retired" 118 | * 14: "sales/marketing" 119 | * 15: "scientist" 120 | * 16: "self-employed" 121 | * 17: "technician/engineer" 122 | * 18: "tradesman/craftsman" 123 | * 19: "unemployed" 124 | * 20: "writer" 125 | 126 | MOVIES FILE DESCRIPTION 127 | ================================================================================ 128 | 129 | Movie information is in the file "movies.dat" and is in the following 130 | format: 131 | 132 | MovieID::Title::Genres 133 | 134 | - Titles are identical to titles provided by the IMDB (including 135 | year of release) 136 | - Genres are pipe-separated and are selected from the following genres: 137 | 138 | * Action 139 | * Adventure 140 | * Animation 141 | * Children's 142 | * Comedy 143 | * Crime 144 | * Documentary 145 | * Drama 146 | * Fantasy 147 | * Film-Noir 148 | * Horror 149 | * Musical 150 | * Mystery 151 | * Romance 152 | * Sci-Fi 153 | * Thriller 154 | * War 155 | * Western 156 | 157 | - Some MovieIDs do not correspond to a movie due to accidental duplicate 158 | entries and/or test entries 159 | - Movies are mostly entered by hand, so errors and inconsistencies may exist 160 | -------------------------------------------------------------------------------- /data/recommend/ml-1m/movies.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blogchong/spark-example/6333b20128368dce31cb22fd2dc1184001075e1b/data/recommend/ml-1m/movies.dat -------------------------------------------------------------------------------- /data/recommend/ml-1m/personalRatings.txt: -------------------------------------------------------------------------------- 1 | 0::1::5::1409495135 2 | 0::780::4::1409495135 3 | 0::590::3::1409495135 4 | 0::1216::4::1409495135 5 | 0::648::5::1409495135 6 | 0::344::3::1409495135 7 | 0::165::4::1409495135 8 | 0::153::5::1409495135 9 | 0::597::4::1409495135 10 | 0::1586::5::1409495135 11 | 0::231::5::1409495135 12 | -------------------------------------------------------------------------------- /out/artifacts/spark_example_jar/spark-example.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blogchong/spark-example/6333b20128368dce31cb22fd2dc1184001075e1b/out/artifacts/spark_example_jar/spark-example.jar -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.blogchong 8 | spark-example 9 | 1.0-SNAPSHOT 10 | 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | net.sf.json-lib 31 | json-lib 32 | 2.4 33 | jdk15 34 | 35 | 36 | 37 | org.ansj 38 | ansj_seg 39 | 0.9 40 | 41 | 42 | org.ansj 43 | tree_split 44 | 1.0.1 45 | 46 | 47 | 48 | org.scala-lang 49 | scala-library 50 | 2.10.3 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | org.apache.spark 64 | spark-core_2.10 65 | 1.5.0 66 | 67 | 68 | org.apache.spark 69 | spark-mllib_2.10 70 | 1.5.1 71 | 72 | 73 | 74 | 75 | 76 | 77 | org.apache.maven.plugins 78 | maven-surefire-plugin 79 | 2.8.1 80 | 81 | 82 | **/*.java 83 | **/*.scala 84 | 85 | 86 | 87 | 88 | org.apache.maven.plugins 89 | maven-compiler-plugin 90 | 2.3.2 91 | 92 | -g 93 | true 94 | 95 | 96 | 97 | 98 | org.scala-tools 99 | maven-scala-plugin 100 | 2.15.2 101 | 102 | 103 | 104 | -g:vars 105 | 106 | 107 | true 108 | 109 | 110 | 111 | scala-compile-first 112 | process-resources 113 | 114 | compile 115 | 116 | 117 | 118 | scala-test-compile 119 | process-test-resources 120 | 121 | testCompile 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /spark-example.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: com.blogchong.spark.mllib.Kmeans 3 | 4 | -------------------------------------------------------------------------------- /src/main/java/com/blogchong/spark/mllib/advance/ALSRecommendMovie/AlsArithmeticPractice.scala: -------------------------------------------------------------------------------- 1 | package com.blogchong.spark.mllib.advance.ALSRecommendMovie 2 | 3 | import org.apache.log4j.{Level, Logger} 4 | import org.apache.spark.{SparkConf, SparkContext} 5 | import org.apache.spark.mllib.recommendation.{ALS, MatrixFactorizationModel, Rating} 6 | import org.apache.spark.rdd._ 7 | import scala.io.Source 8 | 9 | /** 10 | * Author: blogchong 11 | * Blog: www.blogchong.com 12 | * Mailbox: blogchong@163.com 13 | * Data: 2015/10/30 14 | * Describe:协同过滤中,基于模型的协同,最小二乘法ALS算法,贴合实践的实例 15 | */ 16 | object AlsArithmeticPractice { 17 | def main(args: Array[String]) { 18 | 19 | // 屏蔽不必要的日志显示在终端上 20 | Logger.getLogger("org.apache.spark").setLevel(Level.WARN) 21 | Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF) 22 | 23 | // 设置运行环境 24 | val conf = new SparkConf().setAppName("ALSPractice") 25 | val sc = new SparkContext(conf) 26 | 27 | val personalRatingsPath = "/root/spark/spark-1.4.0-bin-hadoop2.6/data/mllib/als2/personalRatings.txt" 28 | val moviesPath = "hdfs://192.168.5.200:9000/spark/mllib/data/als2/movies.dat" 29 | val ratingsPath = "hdfs://192.168.5.200:9000/spark/mllib/data/als2/ratings.dat" 30 | val userPath = "hdfs://192.168.5.200:9000/spark/mllib/data/als2/users.dat" 31 | val modelPath = "hdfs://192.168.5.200:9000/spark/mllib/result/als2/model" 32 | val outPath = "hdfs://192.168.5.200:9000/spark/mllib/result/als2/data/recommendations" 33 | 34 | // 装载用户评分数据,该评分由评分器生成,即文件personalRatings.txt 35 | val myRatings = loadRatings(personalRatingsPath) 36 | val personalRatingsData = sc.parallelize(myRatings, 1) 37 | 38 | //装载样本评分数据,最后一列Timestamp去除10余数作为key,Rating为值,即(Int, Ratings) 39 | //输出的结果是一个key-value集合,其中key为时间取余,value是Rating对象 40 | val ratings = sc.textFile(ratingsPath).map{ 41 | line => 42 | val fields = line.split("::") 43 | (fields(3).toLong %10, Rating(fields(0).toInt, fields(1).toInt, fields(2).toDouble)) 44 | } 45 | 46 | //装载电影电影目录对照表(电影ID->电影标题),即输出是一个数组集合 47 | val movies = sc.textFile(moviesPath).map { 48 | line => 49 | val fields = line.split("::") 50 | (fields(0).toInt, fields(1)) 51 | } 52 | 53 | //统计有用户数量和电影数量以及用户对电影的评分数目 54 | val numRatings = ratings.count() 55 | val numUsers = ratings.map(_._2.user).distinct().count() 56 | val numMovies = ratings.map(_._2.product).distinct().count() 57 | 58 | println("==================样本数量===================") 59 | println("NumRatings: [" + numRatings + "]") 60 | println("NumUsers: [" + numUsers + "]") 61 | println("NumMovies: [" + numMovies + "]") 62 | 63 | //将样本评分表以Key值切分成3个部分,并且数据在计算的过程中会多次用到,所以存入cache 64 | //-训练(60%,并加入用户评分) 65 | //-校验(20%) 66 | //-测试(20%) 67 | val numPartions = 4 68 | //通过key(10的余数,均衡分布,所以x._1 < 6基本能够切分出大约60%的数据量) 69 | val training = ratings.filter(x => x._1 < 6).values 70 | .union(personalRatingsData).repartition(numPartions).persist() 71 | val validation = ratings.filter(x => x._1 >=6 && x._1 < 8).values 72 | .repartition(numPartions).persist() 73 | val test = ratings.filter(x => x._1 > 8).values.persist() 74 | 75 | //统计各部分的量 76 | val numTraining = training.count() 77 | val numValidation = validation.count() 78 | val numTest = test.count() 79 | //打印统计信息 80 | println("==================样本划分===================") 81 | println("NumTraining: [" + numTraining + "]") 82 | println("NumValidation: [" + numValidation + "]") 83 | println("NumTest: [" + numTest + "]") 84 | 85 | //训练不同参数下的模型,并在校验集中验证,获取最佳参数下的模型 86 | val ranks = List(5, 8, 12, 15) 87 | val lambdas = List(0.1, 0.5, 5) 88 | val numIters = List(8, 10, 20) 89 | //最佳模型变量 90 | var bestModel: Option[MatrixFactorizationModel] = None 91 | //最佳校验均根方差 92 | var bestValidationRmse = Double.MaxValue 93 | var bestRank = 0 94 | var bestLambda = -1.0 95 | var bestNumIter = -1 96 | 97 | var count = 0 98 | //进行三层循环遍历,找最佳的Rmse值,对应的model 99 | for (rank <- ranks; lambda <- lambdas; numIter <- numIters) { 100 | val model = ALS.train(training, rank, numIter, lambda) 101 | //计算均根方差值,传入的是model以及校验数据 102 | val validationRmse = computeRmse(model, validation, numValidation) 103 | count += 1 104 | println("==============参数尝试次数:[" + count + "]=======================") 105 | println("RMSE(validation): [" + validationRmse + "]") 106 | println("rank: [" + rank + "]") 107 | println("lambda: [" + lambda + "]") 108 | println("numIter: [" + numIter + "]") 109 | 110 | //选取最佳值,均方根误差越小越OK 111 | if (validationRmse < bestValidationRmse) { 112 | bestModel = Some(model) 113 | bestValidationRmse = validationRmse 114 | bestLambda = lambda 115 | bestRank = rank 116 | bestNumIter = numIter 117 | } 118 | } 119 | 120 | //至此,已经选择出均方根误差最小的模型,即最佳模型 121 | //用最佳模型进行测试集评分预测,并计算和实际评分之间的RMSE值 122 | val testRmse = computeRmse(bestModel.get, test, numTest) 123 | println("==============测试集预测==========================") 124 | println("rank: [" + bestRank + "]") 125 | println("lambda: [" + bestLambda + "]") 126 | println("numIter: [" + bestNumIter + "]") 127 | println("Rmse: [" + testRmse + "]") 128 | 129 | //创建一个基准衡量标准,并且用最好的模型进行比较 130 | //获取训练样本+预测样本的rating平均分 131 | val meanRating = training.union(validation).map(_.rating).mean() 132 | //计算标准差 133 | val baseLineRmse = math.sqrt(test.map(x => (meanRating - x.rating) * (meanRating - x.rating)).reduce(_+_)/numTest) 134 | //改进系数 135 | val improvement = (baseLineRmse - testRmse) / baseLineRmse * 100 136 | println("=============模型预测改进系数========================================================") 137 | println("The best model improves the baseline by " + "%1.2f".format(improvement) + "%.") 138 | 139 | //推荐前十部最感兴趣的电影,注意需要剔除该用户已经评分的电影,即去重 140 | val myRatedMovieIds = myRatings.map(_.product).toSet 141 | 142 | val candidates = movies.keys.filter(!myRatedMovieIds.contains(_)) 143 | 144 | //为用户0推荐十部movies 145 | val candRDD: RDD[(Int, Int)] = candidates.map((0, _)) 146 | val recommendations:RDD[Rating] = bestModel.get.predict(candRDD) //.collect.sortBy(_.rating).take(10) 147 | val recommendations_ = recommendations.collect().sortBy(-_.rating).take(10) 148 | var i = 1 149 | 150 | println("Movies recommended for you:") 151 | recommendations_.foreach { 152 | r => 153 | println("%2d".format(i) + ": [" + r.product + "]") 154 | i += 1 155 | } 156 | 157 | //保存结果 158 | recommendations.sortBy(-_.rating).saveAsTextFile(outPath) 159 | //保存模型文件 160 | bestModel.get.save(sc, modelPath) 161 | //再次使用模型文件 162 | //val sameModel = MatrixFactorizationModel.load(sc, modelPath) 163 | 164 | sc.stop() 165 | } 166 | 167 | /** 装载用户评分文件 personalRatings.txt **/ 168 | def loadRatings(path:String):Seq[Rating] = { 169 | val lines = Source.fromFile(path).getLines() 170 | val ratings = lines.map{ 171 | line => 172 | val fields = line.split("::") 173 | Rating(fields(0).toInt,fields(1).toInt,fields(2).toDouble) 174 | }.filter(_.rating > 0.0) 175 | if(ratings.isEmpty){ 176 | sys.error("No ratings provided.") 177 | ratings.toSeq 178 | }else{ 179 | ratings.toSeq 180 | } 181 | } 182 | 183 | //校验集预测数据和实际数据之间的均方根误差 184 | def computeRmse(model:MatrixFactorizationModel,data:RDD[Rating],n:Long):Double = { 185 | 186 | //调用model的predict预测方法,把预测数据初始化model中,并且生成预测rating 187 | val predictions:RDD[Rating] = model.predict((data.map(x => (x.user, x.product)))) 188 | 189 | //通过join操作,把相同user-product的value合并成一个(double,double)元组,前者为预测值,后者为实际值 190 | val predictionsAndRatings = predictions.map{ 191 | x => ((x.user, x.product), x.rating) 192 | }.join(data.map(x => ((x.user, x.product), x.rating))).values 193 | 194 | //均方根误差能够很好的反应出测量的精密度,对于偏离过大或者过小的测量值较为敏感 195 | //计算过程为观测值与真实值偏差的平方,除于观测次数n,然后再取平方根 196 | //reduce方法,执行的是值累加操作 197 | math.sqrt(predictionsAndRatings.map(x => (x._1 - x._2) * (x._1 - x._2)).reduce( _ + _ )/n) 198 | 199 | } 200 | 201 | } 202 | -------------------------------------------------------------------------------- /src/main/java/com/blogchong/spark/mllib/advance/DiscoveryNewWord/AnsjDisWords.scala: -------------------------------------------------------------------------------- 1 | package com.blogchong.spark.mllib.advance.DiscoveryNewWord 2 | 3 | import org.apache.spark.{SparkContext, SparkConf} 4 | import scala.util.parsing.json.JSONObject 5 | import scala.collection.JavaConversions._ 6 | import org.ansj.app.newWord.LearnTool 7 | import org.ansj.domain.TermNatures 8 | import org.ansj.splitWord.analysis.NlpAnalysis 9 | 10 | /** 11 | * Author: blogchong 12 | * Blog: www.blogchong.com 13 | * Mailbox: blogchong@163.com 14 | * Data: 2016/1/10 15 | * Describe: ansj工具新词发现实验 16 | */ 17 | object AnsjDisWords { 18 | def main(args: Array[String]) { 19 | // 设置运行环境 20 | val conf = new SparkConf().setAppName("新词发现") 21 | val sc = new SparkContext(conf) 22 | 23 | val inputPath = args(0) 24 | val outputPath = args(1) 25 | 26 | println("InputPath:" + inputPath) 27 | println("OutputPath:" + outputPath) 28 | 29 | val list: List[Int] = List(1) 30 | 31 | list.map { 32 | k => 33 | //获取初始数据 34 | val input = sc.textFile(inputPath) 35 | 36 | println("InputSize:" + input.count()) 37 | 38 | if (LTSerializa2.getTool == null) { 39 | println("learnTool is NULL!") 40 | } else { 41 | println("learnTool is not NULL!") 42 | } 43 | 44 | input.map { 45 | f => 46 | val notes = f.split("\t") 47 | val noteObj = notes(1).asInstanceOf[JSONObject] 48 | NlpAnalysis.parse(noteObj.obj.get("title").toString, LTSerializa2.getTool) 49 | NlpAnalysis.parse(noteObj.obj.get("body").toString, LTSerializa2.getTool) 50 | } 51 | 52 | val newWords = LTSerializa2.getTool.getTopTree(100, TermNatures.NW) 53 | 54 | if (newWords == null) { 55 | println("NewWords is NULL!") 56 | } else { 57 | println("NewWordsSize:" + newWords.size()) 58 | sc.parallelize(newWords.map(f => f.getKey).toSeq).saveAsTextFile(outputPath) 59 | } 60 | } 61 | sc.stop() 62 | } 63 | 64 | object LTSerializa2 { 65 | val learnTool2 = new LearnTool 66 | def getTool = { 67 | learnTool2 68 | } 69 | } 70 | 71 | class LTSerializa extends java.io.Serializable { 72 | val learnTool = new LearnTool 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/blogchong/spark/mllib/advance/DiscoveryNewWord/NGramSpark.scala: -------------------------------------------------------------------------------- 1 | package com.blogchong.spark.mllib.advance.DiscoveryNewWord 2 | 3 | import org.apache.spark.{SparkContext, SparkConf} 4 | import org.ansj.splitWord.analysis.{ToAnalysis} 5 | import scala.collection.JavaConversions._ 6 | import java.util.Date 7 | import com.blogchong.util.{CharUtil, NewTime} 8 | import java.util.regex.Pattern 9 | import java.util 10 | import org.apache.log4j.Logger 11 | 12 | /** 13 | * Author: blogchong 14 | * Blog: www.blogchong.com 15 | * Mailbox: blogchong@163.com 16 | * Data: 2016/1/12 17 | * Describe: NGram算法 - 新词发现实验 18 | */ 19 | object NGramSpark { 20 | 21 | val logger = Logger.getLogger(NGramSpark.getClass) 22 | 23 | def main(args: Array[String]) { 24 | 25 | // 设置运行环境 26 | val conf = new SparkConf().setAppName("ansj分词,新词发现") 27 | val sc = new SparkContext(conf) 28 | 29 | val userDicPath = args(0) 30 | val inputPath = args(1) 31 | val outputPath = args(2) 32 | 33 | println("=============>UserDicPath:" + userDicPath) 34 | println("=============>InputPath:" + inputPath) 35 | println("=============>OutputPath:" + outputPath) 36 | 37 | //输入 38 | val input = sc.textFile(inputPath).collect() 39 | println("=============>InputSize:" + input.size) 40 | 41 | //初始化用户字典 42 | val userDic = sc.textFile(userDicPath).map { 43 | f => 44 | val notes = f.split("\t") 45 | if (notes.size == 3) { 46 | notes(0) 47 | } 48 | }.collect.toSet 49 | 50 | //设置TF/D阈值 51 | val tdfThreshold = 2.5 52 | 53 | println("=============>UserDicSize:" + userDic.size) 54 | 55 | val mergeWordTFDMap = new util.HashMap[String, Double]() 56 | 57 | //进行词合并 58 | val mergeWordTFMap = new util.HashMap[String, Int]() 59 | val mergeWordTF2WordsMap = new util.HashMap[String, String]() 60 | val mergeWordDMap = new util.HashMap[String, Int]() 61 | val wordMap = new util.HashMap[String, Int]() 62 | 63 | val que_2: util.Queue[String] = new util.LinkedList[String] 64 | val que_3: util.Queue[String] = new util.LinkedList[String] 65 | 66 | var count = 0 67 | //统计总词数 68 | var wordCount = 0 69 | val output = input.map { 70 | f => 71 | val newWordSet = new util.HashSet[String]() 72 | val notes = f.split("\t") 73 | val id = notes(0) 74 | val noteObj = net.sf.json.JSONObject.fromObject(notes(1)) 75 | 76 | val title = noteObj.get("title").toString 77 | val body = noteObj.get("body").toString 78 | 79 | val titleParse = ToAnalysis.parse(title) 80 | val bodyParse = ToAnalysis.parse(body) 81 | 82 | val titleWords = titleParse.map { 83 | f => 84 | replaceStr(f.getName.toLowerCase.trim) 85 | }.filter(f => f.length > 0) 86 | 87 | val bodyWords = bodyParse.map { 88 | f => 89 | replaceStr(f.getName.toLowerCase.trim).trim 90 | }.filter(f => f.length > 0).union(titleWords) 91 | 92 | //进行单个字词统计 93 | bodyWords.foreach { 94 | f => 95 | wordCount = wordCount + 1 96 | if (wordMap.containsKey(f)) { 97 | wordMap.put(f, wordMap.get(f) + 1) 98 | } else { 99 | wordMap.put(f, 1) 100 | } 101 | } 102 | 103 | //做两词合并 104 | bodyWords.foreach { 105 | j => 106 | que_2.offer(j) 107 | //先做2词合并实验,并记录词频,目前只考虑词频 文档频以及 平均文档频 108 | if (que_2.size() == 2) { 109 | val newWord2Words = joinWord(que_2, 2) 110 | val newWord = newWord2Words._1 111 | //判断是否在基本字典中 112 | if (!userDic.contains(newWord) && newWord.trim.size != 0) { 113 | //存储组合词和字词关系 114 | mergeWordTF2WordsMap.put(newWord2Words._1, newWord2Words._2) 115 | //存储词个数 116 | if (mergeWordTFMap.containsKey(newWord)) { 117 | mergeWordTFMap.put(newWord, mergeWordTFMap.get(newWord) + 1) 118 | } else { 119 | mergeWordTFMap.put(newWord, 1) 120 | } 121 | //加入单篇文档新词set 122 | newWordSet.add(newWord) 123 | wordCount = wordCount + 1 124 | } 125 | } else if (que_2.size() > 2) { 126 | //先移除之前的 127 | que_2.poll() 128 | val newWord2Words = joinWord(que_2, 2) 129 | val newWord = newWord2Words._1 130 | //判断是否在基本字典中 131 | if (!userDic.contains(newWord) && newWord.trim.size != 0) { 132 | //存储组合词和字词关系 133 | mergeWordTF2WordsMap.put(newWord2Words._1, newWord2Words._2) 134 | //存储词个数 135 | if (mergeWordTFMap.containsKey(newWord)) { 136 | mergeWordTFMap.put(newWord, mergeWordTFMap.get(newWord) + 1) 137 | } else { 138 | mergeWordTFMap.put(newWord, 1) 139 | } 140 | //加入单篇文档新词set 141 | newWordSet.add(newWord) 142 | wordCount = wordCount + 1 143 | } 144 | } 145 | } 146 | 147 | //做三词合并 148 | bodyWords.foreach { 149 | j => 150 | que_3.offer(j) 151 | //先做2词合并实验,并记录词频,目前只考虑词频 文档频以及 平均文档频 152 | if (que_3.size() == 3) { 153 | val newWord2Words = joinWord(que_3, 3) 154 | val newWord = newWord2Words._1 155 | //判断是否在基本字典中 156 | if (!userDic.contains(newWord) && newWord.trim.size != 0) { 157 | // //存储组合词和字词关系 158 | mergeWordTF2WordsMap.put(newWord2Words._1, newWord2Words._2) 159 | //存储词个数 160 | if (mergeWordTFMap.containsKey(newWord)) { 161 | mergeWordTFMap.put(newWord, mergeWordTFMap.get(newWord) + 1) 162 | } else { 163 | mergeWordTFMap.put(newWord, 1) 164 | } 165 | //加入单篇文档新词set 166 | newWordSet.add(newWord) 167 | wordCount = wordCount + 1 168 | } 169 | } else if (que_3.size() > 3) { 170 | //先移除之前的 171 | que_3.poll() 172 | val newWord2Words = joinWord(que_3, 3) 173 | val newWord = newWord2Words._1 174 | //判断是否在基本字典中 175 | if (!userDic.contains(newWord) && newWord.trim.size != 0) { 176 | if (mergeWordTFMap.containsKey(newWord)) { 177 | mergeWordTFMap.put(newWord, mergeWordTFMap.get(newWord) + 1) 178 | } else { 179 | mergeWordTFMap.put(newWord, 1) 180 | } 181 | //加入单篇文档新词set 182 | newWordSet.add(newWord) 183 | wordCount = wordCount + 1 184 | } 185 | } 186 | } 187 | 188 | //计算文档频 189 | newWordSet.foreach { 190 | f => 191 | if (mergeWordDMap.containsKey(f)) { 192 | mergeWordDMap.put(f, mergeWordDMap.get(f) + 1) 193 | } else { 194 | mergeWordDMap.put(f, 1) 195 | } 196 | } 197 | 198 | if (count % 5000 == 0) { 199 | println("Begin--------------------------------------------------------") 200 | println("=============>count:" + count) 201 | println("=============>mergeWordTFMapSize:" + mergeWordTFMap.size()) 202 | println("=============>mergeWordDMapSize:" + mergeWordDMap.size()) 203 | println("End--------------------------------------------------------") 204 | } 205 | 206 | count = count + 1 207 | s"${id}\t${bodyWords.mkString(",")}" 208 | } 209 | 210 | println("=============>OutputSize:" + output.size) 211 | 212 | val dateDate = new Date 213 | val saveTime = NewTime.dateToString(dateDate, NewTime.`type`) 214 | 215 | //存储基础分词之后的结果 216 | // sc.parallelize(output.toSeq).saveAsTextFile(outputPath + "/" + saveTime + "/splitwords") 217 | 218 | //进行TF词频,文档排序输出 219 | val scTFMap = mergeWordTFMap.toSeq.sortBy { 220 | case (word, freq) => freq 221 | }.filter(_._2 > 1) 222 | println("=============>新词词频MergeWordTFMapSize:" + scTFMap.size()) 223 | // sc.parallelize(scTFMap).saveAsTextFile(outputPath + "/" + saveTime + "/tfNewWord") 224 | 225 | //进行文档频存储 226 | val scDMap = mergeWordDMap.toSeq.sortBy { 227 | case (word, freq) => freq 228 | }.filter(_._2 > 1) 229 | println("=============>新词文档频MergeWordDMapSize:" + scDMap.size()) 230 | // sc.parallelize(scDMap).saveAsTextFile(outputPath + "/" + saveTime + "/dNewWord") 231 | 232 | //进行平均词频计算 233 | scDMap.foreach { 234 | f => 235 | if (mergeWordTFMap.containsKey(f._1) && f._2 != 0) { 236 | mergeWordTFDMap.put(f._1, mergeWordTFMap.get(f._1).toDouble / f._2.toDouble) 237 | } 238 | } 239 | 240 | //进行平均文档频计算存储 241 | val scTFDMap = mergeWordTFDMap.toSeq.sortBy { 242 | case (word, freq) => freq 243 | }.filter(_._1.split("\\s").size == 1).filter(_._2 >= tdfThreshold) 244 | println("=============>新词平均词频(过阈值过纯英文\\s组合之后)MergeWordTFDMapSize:" + scTFDMap.size()) 245 | sc.parallelize(scTFDMap).saveAsTextFile(outputPath + "/" + saveTime + "/tfdNewWord") 246 | 247 | //////////////////////////////////计算凝固度//////////////////////////////////////////////////////////// 248 | sc.parallelize(wordMap.toSeq).saveAsTextFile(outputPath + "/" + saveTime + "/wordMap") 249 | 250 | println("=============>词总量wordCount:" + wordCount) 251 | 252 | //计算单个字词的概率 253 | val wordRateMap = new util.HashMap[String, Double]() 254 | wordMap.foreach { 255 | f => 256 | wordRateMap.put(f._1, f._2.toDouble / wordCount.toDouble) 257 | } 258 | println("=============>全量子词概率WordRateMapSize:" + wordRateMap.size()) 259 | sc.parallelize(wordRateMap.toSeq.sortBy{ 260 | case (word, freq) => freq 261 | }).saveAsTextFile(outputPath + "/" + saveTime + "/wordRateMap") 262 | 263 | //计算组合词概率,只计算过了TFD阈值的词 264 | val wordTfdRateMap = new util.HashMap[String, Double]() 265 | scTFDMap.foreach { 266 | f => 267 | wordTfdRateMap.put(f._1, f._2.toDouble / wordCount.toDouble) 268 | } 269 | println("=============>新词组合概率(过了TFD阈值)WordTfdRateMapSize:" + wordTfdRateMap.size()) 270 | sc.parallelize(wordTfdRateMap.toSeq.sortBy{ 271 | case (word, freq) => freq 272 | }).saveAsTextFile(outputPath + "/" + saveTime + "/wordTfdRateMap") 273 | 274 | //计算组合词概率和 字词乘积和 275 | sc.parallelize(mergeWordTF2WordsMap.toSeq).saveAsTextFile(outputPath + "/" + saveTime + "/mergeWordTF2WordsMap") 276 | val proRate = new util.HashMap[String, Double]() 277 | wordTfdRateMap.foreach{ 278 | f=> 279 | var rate : Double = 1.0 280 | mergeWordTF2WordsMap.get(f._1).split("\t").foreach{ 281 | g => 282 | rate = rate * wordRateMap.get(g) 283 | } 284 | 285 | proRate.put(f._1, wordTfdRateMap.get(f._1) / rate) 286 | } 287 | println("=============>计算组合词概率和子词乘积比值ProRateSize:" + proRate.size()) 288 | 289 | //保存概率比 290 | sc.parallelize(proRate.toSeq.sortBy{ 291 | case(word, freq) => freq 292 | }).saveAsTextFile(outputPath + "/" + saveTime + "/proRate") 293 | 294 | sc.stop() 295 | } 296 | 297 | //合并新词 298 | def joinWord(que: util.Queue[String], num: Int): (String, String) = { 299 | val que_ret: util.Queue[String] = que 300 | if (num == 2) { 301 | val word1 = que_ret.poll() 302 | val word2 = que_ret.poll() 303 | if ((CharUtil.isNumeric(word1) || CharUtil.isNumeric(word2)) 304 | || (word1.equals("的") || word2.equals("的"))) { 305 | ("", word1 + "\t" + word2) 306 | } else if ((word1.equals("-") || (word2.equals("-"))) || (word1.equals("_") || word2.equals("_"))) { 307 | ("", word1 + "\t" + word2) 308 | } else { 309 | if (!CharUtil.isChinese(word1) && !CharUtil.isChinese(word2)) { 310 | (word1 + " " + word2, word1 + "\t" + word2) 311 | } else { 312 | (word1 + word2, word1 + "\t" + word2) 313 | } 314 | } 315 | } else if (num == 3) { 316 | val word1 = que_ret.poll() 317 | val word2 = que_ret.poll() 318 | val word3 = que_ret.poll() 319 | if ((CharUtil.isNumeric(word1) || CharUtil.isNumeric(word2) || CharUtil.isNumeric(word3)) 320 | || (word1.equals("的") || word2.equals("的") || word3.equals("的"))) { 321 | ("", word1 + "\t" + word2 + "\t" + word3) 322 | } else if (word1.equals("-") || word1.equals("_") || word3.equals("-") || word3.equals("_")) { 323 | ("", word1 + "\t" + word2 + "\t" + word3) 324 | } else if (!CharUtil.isChinese(word1) && !CharUtil.isChinese(word2) && !CharUtil.isChinese(word3) 325 | && (word2.equals("-") || word2.equals("_"))) { 326 | (word1 + word2 + word3, word1 + "\t" + word2 + "\t" + word3) 327 | } else if (!CharUtil.isChinese(word1) && !CharUtil.isChinese(word2) && !CharUtil.isChinese(word3) 328 | && (!word2.equals("-") && !word2.equals("_"))) { 329 | (word1 + " " + word2 + " " + word3, word1 + "\t" + word2 + "\t" + word3) 330 | } else { 331 | (word1 + word2 + word3, word1 + "\t" + word2 + "\t" + word3) 332 | } 333 | } else { 334 | (que_ret.mkString(""), que.mkString("\t")) 335 | } 336 | 337 | } 338 | 339 | //特殊字符去除 340 | def replaceStr(str: String) = { 341 | if (!CharUtil.isChinese(str) && !str.equals("-") && !str.equals("_") && str.size <= 1) { 342 | "" 343 | } else { 344 | val regEx = "[`~!@#$%^&*()+=|{}':→;ˇ'\\\\,\\[\\].<>/?~!≤@#¥%《》ø━……&*()——+|{}【】‘;:”“’。,、?]" 345 | val pattern = Pattern.compile(regEx) 346 | val matcher = pattern.matcher(str) 347 | matcher.replaceAll("").trim 348 | } 349 | } 350 | 351 | } 352 | -------------------------------------------------------------------------------- /src/main/java/com/blogchong/spark/mllib/advance/LdaExtractTopics/Check/PredictsDocTopics.scala: -------------------------------------------------------------------------------- 1 | package com.blogchong.spark.mllib.advance.LdaExtractTopics.Check 2 | 3 | import org.apache.spark.mllib.clustering.{LocalLDAModel} 4 | import org.apache.spark.mllib.linalg.Vectors 5 | import org.apache.spark.{SparkConf, SparkContext} 6 | import scala.collection.JavaConversions._ 7 | import java.util.Date 8 | import com.blogchong.util.NewTime 9 | import java.util 10 | 11 | /** 12 | * Author: blogchong 13 | * Blog: www.blogchong.com 14 | * Mailbox: blogchong@163.com 15 | * Data: 2015/10/23 16 | * Describe: LDA主题词 新文档主题推测,然后进行校验 17 | */ 18 | 19 | object PredictsDocTopics { 20 | def main(args: Array[String]) = { 21 | 22 | args.map(f => println(f)) 23 | 24 | val argsParser = new PredictsDocTopicsArgsParser 25 | 26 | require(args.length >= 3, argsParser.getUsageMessage(null)) 27 | 28 | argsParser.parseArgs(args.toList) 29 | 30 | val dataPath = argsParser.dataPath 31 | val modelPath = argsParser.modelPath 32 | val wordsPath = argsParser.wordsPath 33 | val maxWordsTopic = argsParser.topicSize 34 | val topicsPath = argsParser.topicsPath 35 | 36 | val conf = new SparkConf().setAppName("PredictsDocTopics") 37 | val sc = new SparkContext(conf) 38 | 39 | //生成对应关系。要求为字典