diff --git a/README.md b/README.md index 47e554896abb1ec9c452428bfa8e540902027189..ceb2ccddd12edbbc674e406dc32aacf98f746d92 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,11 @@ # 目录规划 -data 测试用数据集合 -standalone 相关实践的单机实现版本(主要为python实现) -spark 相关实践的spark版本(主要为scala实现) -manual 相关资料集合 +* data 测试用数据集合 +* standalone 相关实践的单机实现版本(主要为python实现) +* spark 相关实践的spark版本(主要为scala实现) + 已经完成特征工程,ItemCF 部分 +* manual 相关资料集合 # 计划项(恩 就是挖坑的意思) ## 推荐算实现 @@ -30,8 +31,6 @@ Markov Chain 社交网络 .... -## paper阅读笔记 - ## 评价系统实现 diff --git a/data/DFPath/._SUCCESS.crc b/data/DFPath/._SUCCESS.crc new file mode 100644 index 0000000000000000000000000000000000000000..3b7b044936a890cd8d651d349a752d819d71d22c Binary files /dev/null and b/data/DFPath/._SUCCESS.crc differ diff --git a/data/DFPath/._common_metadata.crc b/data/DFPath/._common_metadata.crc new file mode 100644 index 0000000000000000000000000000000000000000..753ebae2ba339201807d19be489657a45b91e867 Binary files /dev/null and b/data/DFPath/._common_metadata.crc differ diff --git a/data/DFPath/._metadata.crc b/data/DFPath/._metadata.crc new file mode 100644 index 0000000000000000000000000000000000000000..ff9345ce25ddcf55fe6f1cb36ec3711be1136bb3 Binary files /dev/null and b/data/DFPath/._metadata.crc differ diff --git a/data/DFPath/.part-r-00000-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet.crc b/data/DFPath/.part-r-00000-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet.crc new file mode 100644 index 0000000000000000000000000000000000000000..12bd3088c7b42cbfad866684080c5736fb13151e Binary files /dev/null and b/data/DFPath/.part-r-00000-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet.crc differ diff --git a/data/DFPath/.part-r-00001-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet.crc b/data/DFPath/.part-r-00001-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet.crc new file mode 100644 index 0000000000000000000000000000000000000000..e502f55f2d1ab476023f69ac2940700b4477870e Binary files /dev/null and b/data/DFPath/.part-r-00001-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet.crc differ diff --git a/data/DFPath/_SUCCESS b/data/DFPath/_SUCCESS new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/data/DFPath/_common_metadata b/data/DFPath/_common_metadata new file mode 100644 index 0000000000000000000000000000000000000000..ab00a51bf762d42a32e004ddb9fc2c7fa407f20a Binary files /dev/null and b/data/DFPath/_common_metadata differ diff --git a/data/DFPath/_metadata b/data/DFPath/_metadata new file mode 100644 index 0000000000000000000000000000000000000000..ce41f9bb050d9c7fe15ff5c3a6e30cda256ce3ce Binary files /dev/null and b/data/DFPath/_metadata differ diff --git a/data/DFPath/part-r-00000-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet b/data/DFPath/part-r-00000-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet new file mode 100644 index 0000000000000000000000000000000000000000..4990a4fc540b600780b19538b10359c497d0c58e Binary files /dev/null and b/data/DFPath/part-r-00000-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet differ diff --git a/data/DFPath/part-r-00001-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet b/data/DFPath/part-r-00001-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet new file mode 100644 index 0000000000000000000000000000000000000000..d240e4ae24bc034226b7f3dc6c6163dfeb07dd78 Binary files /dev/null and b/data/DFPath/part-r-00001-3f66a128-164d-4dfe-b291-f716928b12fd.gz.parquet differ diff --git a/data/SimPath/._SUCCESS.crc b/data/SimPath/._SUCCESS.crc new file mode 100644 index 0000000000000000000000000000000000000000..3b7b044936a890cd8d651d349a752d819d71d22c Binary files /dev/null and b/data/SimPath/._SUCCESS.crc differ diff --git a/data/SimPath/.part-00000.crc b/data/SimPath/.part-00000.crc new file mode 100644 index 0000000000000000000000000000000000000000..48510e86bffda1a2481351a1093b6af35d54497d Binary files /dev/null and b/data/SimPath/.part-00000.crc differ diff --git a/data/SimPath/_SUCCESS b/data/SimPath/_SUCCESS new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/data/SimPath/part-00000 b/data/SimPath/part-00000 new file mode 100644 index 0000000000000000000000000000000000000000..71f16d7c170cc3df2fa0a7d5faa16390efb0e832 --- /dev/null +++ b/data/SimPath/part-00000 @@ -0,0 +1,2127 @@ +728|913|1.0 +50|497|1.0 +377|608|0.7071067811865475 +34|562|1.0 +272|357|1.0 +265|562|0.6 +21|589|1.0 +32|800|1.0 +357|919|0.7071067811865475 +52|162|1.0 +288|509|1.0 +229|728|1.0 +321|913|1.0 +515|866|0.6246950475544243 +176|714|1.0 +29|357|1.0 +720|783|1.0 +459|480|0.6622661785325219 +377|551|1.0 +608|783|0.7071067811865475 +348|896|1.0 +41|377|1.0 +162|215|1.0 +1|661|1.0 +292|780|1.0 +551|714|1.0 +194|318|0.5144957554275265 +551|733|0.19611613513818404 +224|733|0.19611613513818404 +515|581|0.6246950475544243 +1|745|1.0 +318|902|0.8574929257125441 +110|349|1.0 +24|39|1.0 +24|224|1.0 +224|913|1.0 +6|194|1.0 +150|608|0.9191450300180579 +321|608|0.7071067811865475 +194|994|1.0 +265|736|0.8 +531|661|1.0 +296|733|0.19611613513818404 +32|321|1.0 +412|728|1.0 +16|728|1.0 +515|800|0.6246950475544243 +202|515|0.6246950475544243 +380|480|0.6622661785325219 +235|442|1.0 +608|860|0.7071067811865475 +348|800|1.0 +509|800|1.0 +47|348|1.0 +32|299|1.0 +110|736|1.0 +265|377|0.6 +32|265|0.6 +356|501|0.19611613513818404 +162|919|0.7071067811865475 +461|581|1.0 +224|299|1.0 +29|356|0.19611613513818404 +165|920|1.0 +16|52|1.0 +321|866|1.0 +590|982|0.7808688094430304 +608|896|0.7071067811865475 +318|497|0.5144957554275265 +194|412|1.0 +52|377|1.0 +215|860|1.0 +24|47|1.0 +800|994|1.0 +914|919|0.7071067811865475 +104|648|0.6 +95|780|1.0 +265|728|0.6 +353|551|1.0 +321|501|1.0 +299|356|0.19611613513818404 +224|608|0.7071067811865475 +24|299|1.0 +1|48|1.0 +299|497|1.0 +48|783|1.0 +728|866|1.0 +29|581|1.0 +163|780|1.0 +34|272|1.0 +215|272|1.0 +356|647|0.9805806756909202 +32|733|0.19611613513818404 +318|736|0.8574929257125441 +50|162|1.0 +348|412|1.0 +104|590|0.6246950475544243 +36|551|1.0 +377|461|1.0 +292|459|1.0 +265|648|0.6400000000000001 +608|745|0.7071067811865475 +29|509|1.0 +162|229|1.0 +163|368|1.0 +50|908|1.0 +349|442|1.0 +50|348|1.0 +162|994|1.0 +589|902|1.0 +480|653|0.5298129428260175 +608|913|0.7071067811865475 +442|736|1.0 +21|498|1.0 +21|457|1.0 +36|608|0.7071067811865475 +39|506|1.0 +29|994|1.0 +47|562|1.0 +1|783|1.0 +349|368|1.0 +21|163|1.0 +235|356|0.9805806756909202 +41|272|1.0 +95|515|0.7808688094430304 +321|581|1.0 +34|348|1.0 +552|648|0.6 +50|357|1.0 +272|994|1.0 +459|589|1.0 +162|202|1.0 +47|272|1.0 +52|714|1.0 +498|920|1.0 +95|648|0.8 +296|321|1.0 +34|919|0.7071067811865475 +39|968|1.0 +714|919|0.7071067811865475 +24|908|1.0 +202|919|0.7071067811865475 +95|498|1.0 +380|434|1.0 +16|377|1.0 +165|589|1.0 +202|733|0.19611613513818404 +265|509|0.6 +165|498|1.0 +32|497|1.0 +590|647|0.7808688094430304 +29|908|1.0 +1|938|1.0 +36|321|1.0 +318|380|0.8574929257125441 +501|896|1.0 +714|908|1.0 +299|321|1.0 +194|224|1.0 +515|860|0.6246950475544243 +39|733|0.19611613513818404 +497|896|1.0 +356|982|0.9805806756909202 +593|982|0.7071067811865475 +21|736|1.0 +29|39|1.0 +589|982|1.0 +176|215|1.0 +299|896|1.0 +29|714|1.0 +163|318|0.8574929257125441 +162|562|1.0 +442|498|1.0 +318|434|0.8574929257125441 +150|594|0.9284766908852594 +29|412|1.0 +265|919|0.42426406871192845 +202|551|1.0 +176|608|0.7071067811865475 +260|531|0.4923659639173309 +29|296|1.0 +229|377|1.0 +265|356|0.9021342216356466 +21|647|1.0 +292|318|0.8574929257125441 +194|509|1.0 +594|720|1.0 +34|497|1.0 +47|50|1.0 +265|348|0.6 +356|562|0.19611613513818404 +265|296|0.6 +714|860|1.0 +215|353|1.0 +321|860|1.0 +348|866|1.0 +318|647|0.8574929257125441 +377|968|1.0 +6|39|1.0 +720|919|0.7071067811865475 +150|783|0.9284766908852594 +501|919|0.7071067811865475 +299|908|1.0 +224|509|1.0 +16|913|1.0 +165|590|0.7808688094430304 +498|982|1.0 +194|296|1.0 +194|357|1.0 +21|434|1.0 +202|994|1.0 +318|461|0.5144957554275265 +224|318|0.5144957554275265 +353|593|0.565685424949238 +461|800|1.0 +498|647|1.0 +215|497|1.0 +24|501|1.0 +296|515|0.6246950475544243 +260|595|0.4923659639173309 +6|412|1.0 +593|919|0.39999999999999997 +531|594|1.0 +265|288|0.6 +39|296|1.0 +501|860|1.0 +50|608|0.7071067811865475 +95|265|0.8 +110|498|1.0 +50|412|1.0 +39|608|0.7071067811865475 +594|783|1.0 +194|353|1.0 +593|896|0.565685424949238 +356|733|0.038461538461538464 +47|501|1.0 +50|515|0.6246950475544243 +272|562|1.0 +480|515|0.5171430023650758 +434|736|1.0 +356|497|0.19611613513818404 +24|461|1.0 +321|733|0.19611613513818404 +229|357|1.0 +356|377|0.19611613513818404 +41|866|1.0 +52|968|1.0 +968|994|1.0 +380|459|1.0 +1|260|0.4923659639173309 +412|860|1.0 +501|728|1.0 +29|41|1.0 +1|588|1.0 +588|745|1.0 +527|783|1.0 +588|608|0.7071067811865475 +6|866|1.0 +50|994|1.0 +52|994|1.0 +265|982|0.8 +16|162|1.0 +104|552|1.0 +288|551|1.0 +235|515|0.7808688094430304 +272|497|1.0 +52|353|1.0 +457|736|1.0 +48|588|1.0 +32|34|1.0 +480|920|0.6622661785325219 +34|593|0.565685424949238 +380|780|1.0 +110|318|0.8574929257125441 +224|968|1.0 +50|299|1.0 +506|581|1.0 +896|994|1.0 +288|515|0.6246950475544243 +593|866|0.565685424949238 +357|968|1.0 +260|653|0.6154574548966636 +6|515|0.6246950475544243 +150|509|0.3713906763541037 +498|648|0.8 +224|919|0.7071067811865475 +50|461|1.0 +265|581|0.6 +480|780|0.6622661785325219 +357|551|1.0 +235|349|1.0 +357|714|1.0 +32|36|1.0 +595|661|1.0 +52|461|1.0 +562|994|1.0 +162|265|0.6 +581|919|0.7071067811865475 +509|913|1.0 +6|501|1.0 +162|860|1.0 +272|509|1.0 +501|733|0.19611613513818404 +588|595|1.0 +377|800|1.0 +531|783|1.0 +461|866|1.0 +593|908|0.565685424949238 +380|498|1.0 +299|800|1.0 +527|595|1.0 +21|442|1.0 +299|608|0.7071067811865475 +39|356|0.19611613513818404 +34|608|0.7071067811865475 +608|866|0.7071067811865475 +150|356|0.07283570407292297 +52|501|1.0 +434|498|1.0 +52|321|1.0 +260|720|0.4923659639173309 +39|581|1.0 +593|647|0.7071067811865475 +150|265|0.22283440581246222 +24|714|1.0 +229|321|1.0 +459|647|1.0 +29|497|1.0 +272|321|1.0 +593|968|0.565685424949238 +41|896|1.0 +215|509|1.0 +919|968|0.7071067811865475 +296|919|0.7071067811865475 +176|968|1.0 +21|318|0.8574929257125441 +41|581|1.0 +215|501|1.0 +176|515|0.6246950475544243 +52|800|1.0 +292|515|0.7808688094430304 +457|480|0.6622661785325219 +296|728|1.0 +16|968|1.0 +288|562|1.0 +412|968|1.0 +318|908|0.5144957554275265 +39|41|1.0 +6|272|1.0 +353|968|1.0 +318|896|0.5144957554275265 +36|860|1.0 +321|377|1.0 +95|593|0.7071067811865475 +32|896|1.0 +202|497|1.0 +593|648|0.8202438661763951 +497|506|1.0 +229|733|0.19611613513818404 +215|593|0.565685424949238 +194|272|1.0 +29|353|1.0 +50|52|1.0 +215|800|1.0 +515|919|0.44172610429938614 +163|480|0.6622661785325219 +47|353|1.0 +34|509|1.0 +380|589|1.0 +348|913|1.0 +52|866|1.0 +515|733|0.12251277836633778 +896|913|1.0 +299|353|1.0 +288|994|1.0 +16|299|1.0 +357|733|0.19611613513818404 +36|800|1.0 +434|593|0.7071067811865475 +150|714|0.3713906763541037 +176|800|1.0 +272|501|1.0 +16|296|1.0 +648|736|0.8 +480|648|0.847700708521628 +150|733|0.07283570407292297 +736|982|1.0 +95|349|1.0 +32|39|1.0 +95|368|1.0 +461|593|0.565685424949238 +176|728|1.0 +41|318|0.5144957554275265 +497|800|1.0 +24|348|1.0 +202|506|1.0 +202|265|0.6 +150|377|0.3713906763541037 +299|866|1.0 +299|728|1.0 +16|29|1.0 +48|919|0.7071067811865475 +356|357|0.19611613513818404 +357|593|0.565685424949238 +527|531|1.0 +235|593|0.7071067811865475 +29|515|0.6246950475544243 +608|968|0.7071067811865475 +272|728|1.0 +24|29|1.0 +32|229|1.0 +39|866|1.0 +581|800|1.0 +36|50|1.0 +162|581|1.0 +29|150|0.3713906763541037 +194|728|1.0 +581|968|1.0 +733|968|0.19611613513818404 +480|736|0.6622661785325219 +6|733|0.19611613513818404 +272|377|1.0 +150|353|0.3713906763541037 +260|733|0.6035056869815845 +150|919|0.9191450300180579 +47|461|1.0 +24|150|0.3713906763541037 +412|733|0.19611613513818404 +29|461|1.0 +41|515|0.6246950475544243 +150|595|0.9284766908852594 +461|860|1.0 +39|593|0.565685424949238 +357|562|1.0 +368|434|1.0 +21|480|0.6622661785325219 +1|720|1.0 +288|497|1.0 +434|648|0.8 +16|265|0.6 +32|866|1.0 +353|913|1.0 +202|860|1.0 +24|321|1.0 +590|733|0.6125638918316889 +783|914|1.0 +265|497|0.6 +176|506|1.0 +800|913|1.0 +202|288|1.0 +593|994|0.565685424949238 +162|296|1.0 +6|162|1.0 +459|498|1.0 +356|919|0.1386750490563073 +318|866|0.5144957554275265 +412|800|1.0 +588|661|1.0 +357|913|1.0 +34|318|0.5144957554275265 +50|581|1.0 +321|968|1.0 +260|588|0.4923659639173309 +36|52|1.0 +497|866|1.0 +29|551|1.0 +110|647|1.0 +235|265|0.8 +36|348|1.0 +39|353|1.0 +608|728|0.7071067811865475 +39|377|1.0 +16|34|1.0 +34|968|1.0 +531|720|1.0 +95|589|1.0 +41|224|1.0 +194|377|1.0 +412|866|1.0 +235|780|1.0 +21|380|1.0 +265|380|0.8 +6|229|1.0 +47|357|1.0 +176|994|1.0 +165|648|0.8 +47|288|1.0 +501|506|1.0 +32|272|1.0 +39|714|1.0 +265|647|0.8 +648|982|0.8 +52|728|1.0 +348|501|1.0 +41|968|1.0 +47|412|1.0 +41|728|1.0 +288|299|1.0 +318|581|0.5144957554275265 +24|919|0.7071067811865475 +36|272|1.0 +608|908|0.7071067811865475 +728|968|1.0 +29|506|1.0 +648|733|0.5883484054145521 +52|515|0.6246950475544243 +377|593|0.565685424949238 +296|994|1.0 +356|860|0.19611613513818404 +104|653|1.0 +594|745|1.0 +593|736|0.7071067811865475 +288|318|0.5144957554275265 +41|501|1.0 +162|356|0.19611613513818404 +531|919|0.7071067811865475 +260|938|0.4923659639173309 +150|501|0.3713906763541037 +368|593|0.7071067811865475 +800|860|1.0 +292|736|1.0 +6|497|1.0 +356|866|0.19611613513818404 +32|357|1.0 +52|562|1.0 +353|501|1.0 +16|32|1.0 +224|288|1.0 +36|733|0.19611613513818404 +288|919|0.7071067811865475 +515|728|0.6246950475544243 +353|377|1.0 +41|913|1.0 +581|896|1.0 +150|348|0.3713906763541037 +194|461|1.0 +349|736|1.0 +272|515|0.6246950475544243 +176|551|1.0 +41|461|1.0 +47|908|1.0 +21|459|1.0 +50|860|1.0 +292|647|1.0 +498|593|0.7071067811865475 +235|982|1.0 +442|982|1.0 +506|968|1.0 +515|590|0.6097560975609757 +356|780|0.9805806756909202 +104|593|0.4242640687119285 +162|272|1.0 +318|920|0.8574929257125441 +110|902|1.0 +29|224|1.0 +34|41|1.0 +36|39|1.0 +34|908|1.0 +299|501|1.0 +202|461|1.0 +29|860|1.0 +24|356|0.19611613513818404 +16|215|1.0 +24|551|1.0 +229|919|0.7071067811865475 +594|595|1.0 +913|994|1.0 +497|608|0.7071067811865475 +41|994|1.0 +150|224|0.3713906763541037 +353|515|0.6246950475544243 +647|920|1.0 +16|896|1.0 +163|515|0.7808688094430304 +6|288|1.0 +194|551|1.0 +176|913|1.0 +356|896|0.19611613513818404 +24|176|1.0 +47|52|1.0 +296|714|1.0 +163|902|1.0 +229|509|1.0 +32|860|1.0 +527|914|1.0 +215|506|1.0 +551|608|0.7071067811865475 +224|593|0.565685424949238 +47|377|1.0 +194|265|0.6 +202|412|1.0 +321|800|1.0 +728|896|1.0 +32|377|1.0 +47|318|0.5144957554275265 +36|968|1.0 +52|412|1.0 +229|412|1.0 +321|506|1.0 +292|589|1.0 +380|515|0.7808688094430304 +265|459|0.8 +288|733|0.19611613513818404 +288|357|1.0 +321|908|1.0 +47|176|1.0 +349|457|1.0 +356|590|0.7657048647896112 +21|590|0.7808688094430304 +860|908|1.0 +265|589|0.8 +229|908|1.0 +163|589|1.0 +47|497|1.0 +16|150|0.3713906763541037 +356|412|0.19611613513818404 +202|913|1.0 +16|47|1.0 +47|202|1.0 +16|593|0.565685424949238 +1|150|0.9284766908852594 +551|800|1.0 +163|265|0.8 +150|461|0.3713906763541037 +6|318|0.5144957554275265 +296|501|1.0 +497|728|1.0 +480|590|0.8481145238787243 +412|515|0.6246950475544243 +6|265|0.6 +377|509|1.0 +6|29|1.0 +594|938|1.0 +318|590|0.6695894800069752 +515|780|0.7808688094430304 +165|780|1.0 +461|608|0.7071067811865475 +288|377|1.0 +353|356|0.19611613513818404 +349|647|1.0 +229|497|1.0 +215|913|1.0 +202|377|1.0 +34|296|1.0 +480|902|0.6622661785325219 +47|356|0.19611613513818404 +299|348|1.0 +501|581|1.0 +588|938|1.0 +215|866|1.0 +920|982|1.0 +39|194|1.0 +296|497|1.0 +24|52|1.0 +6|608|0.7071067811865475 +412|919|0.7071067811865475 +457|590|0.7808688094430304 +52|215|1.0 +265|272|0.6 +506|919|0.7071067811865475 +515|982|0.7808688094430304 +95|902|1.0 +265|318|0.9946917938265512 +288|968|1.0 +265|551|0.6 +318|733|0.10090091909944686 +162|593|0.565685424949238 +442|647|1.0 +50|728|1.0 +593|902|0.7071067811865475 +595|608|0.7071067811865475 +52|551|1.0 +150|506|0.3713906763541037 +24|272|1.0 +594|661|1.0 +348|860|1.0 +104|480|0.5298129428260175 +412|896|1.0 +318|714|0.5144957554275265 +299|515|0.6246950475544243 +6|581|1.0 +292|380|1.0 +296|377|1.0 +265|501|0.6 +41|733|0.19611613513818404 +265|461|0.6 +24|608|0.7071067811865475 +497|581|1.0 +36|224|1.0 +720|914|1.0 +36|288|1.0 +434|780|1.0 +265|866|0.6 +714|733|0.19611613513818404 +265|608|0.42426406871192845 +506|562|1.0 +501|714|1.0 +348|581|1.0 +32|501|1.0 +299|733|0.19611613513818404 +608|800|0.7071067811865475 +224|506|1.0 +47|194|1.0 +50|377|1.0 +229|296|1.0 +581|866|1.0 +202|581|1.0 +357|908|1.0 +461|497|1.0 +163|498|1.0 +501|866|1.0 +163|457|1.0 +551|896|1.0 +265|908|0.6 +349|648|0.8 +292|349|1.0 +194|229|1.0 +457|920|1.0 +202|353|1.0 +48|531|1.0 +648|920|0.8 +34|994|1.0 +39|162|1.0 +321|412|1.0 +162|224|1.0 +50|176|1.0 +353|581|1.0 +515|562|0.6246950475544243 +562|593|0.565685424949238 +34|36|1.0 +162|497|1.0 +714|994|1.0 +202|593|0.565685424949238 +202|714|1.0 +380|648|0.8 +288|593|0.565685424949238 +194|919|0.7071067811865475 +24|515|0.6246950475544243 +647|780|1.0 +728|919|0.7071067811865475 +321|497|1.0 +506|551|1.0 +377|908|1.0 +356|506|0.19611613513818404 +356|736|0.9805806756909202 +595|783|1.0 +368|459|1.0 +176|866|1.0 +377|506|1.0 +357|509|1.0 +260|661|0.4923659639173309 +380|647|1.0 +163|292|1.0 +6|296|1.0 +110|292|1.0 +39|728|1.0 +866|968|1.0 +357|800|1.0 +780|920|1.0 +434|515|0.7808688094430304 +229|896|1.0 +265|498|0.8 +292|368|1.0 +509|908|1.0 +39|800|1.0 +356|459|0.9805806756909202 +745|938|1.0 +32|994|1.0 +562|800|1.0 +272|296|1.0 +162|866|1.0 +552|733|0.9805806756909202 +321|348|1.0 +16|224|1.0 +150|194|0.3713906763541037 +288|896|1.0 +288|501|1.0 +896|968|1.0 +6|47|1.0 +551|968|1.0 +29|919|0.7071067811865475 +16|800|1.0 +272|913|1.0 +377|866|1.0 +194|968|1.0 +32|608|0.7071067811865475 +224|265|0.6 +95|292|1.0 +229|272|1.0 +661|914|1.0 +288|866|1.0 +506|896|1.0 +52|860|1.0 +480|647|0.6622661785325219 +296|412|1.0 +24|497|1.0 +353|412|1.0 +176|202|1.0 +590|780|0.7808688094430304 +41|202|1.0 +36|356|0.19611613513818404 +581|714|1.0 +47|733|0.19611613513818404 +590|648|0.999512076087079 +104|260|0.6154574548966636 +594|919|0.7071067811865475 +24|896|1.0 +288|321|1.0 +506|728|1.0 +165|349|1.0 +590|902|0.7808688094430304 +24|34|1.0 +24|968|1.0 +318|860|0.5144957554275265 +595|745|1.0 +16|288|1.0 +47|215|1.0 +318|968|0.5144957554275265 +461|919|0.7071067811865475 +41|509|1.0 +104|733|0.9805806756909202 +919|994|0.7071067811865475 +661|783|1.0 +457|515|0.7808688094430304 +377|733|0.19611613513818404 +110|459|1.0 +36|357|1.0 +780|982|1.0 +299|551|1.0 +41|356|0.19611613513818404 +163|982|1.0 +224|348|1.0 +272|908|1.0 +34|50|1.0 +661|720|1.0 +162|608|0.7071067811865475 +506|608|0.7071067811865475 +265|994|0.6 +581|733|0.19611613513818404 +509|994|1.0 +896|908|1.0 +32|296|1.0 +349|593|0.7071067811865475 +356|480|0.649405416832664 +162|968|1.0 +41|800|1.0 +36|215|1.0 +50|501|1.0 +265|506|0.6 +434|647|1.0 +318|348|0.5144957554275265 +50|353|1.0 +52|296|1.0 +194|733|0.19611613513818404 +377|994|1.0 +866|908|1.0 +265|968|0.6 +194|356|0.19611613513818404 +16|272|1.0 +647|648|0.8 +39|412|1.0 +551|860|1.0 +224|562|1.0 +163|647|1.0 +21|265|0.8 +41|288|1.0 +412|506|1.0 +6|461|1.0 +224|551|1.0 +288|913|1.0 +34|714|1.0 +36|866|1.0 +162|515|0.6246950475544243 +353|608|0.7071067811865475 +265|299|0.6 +150|531|0.9284766908852594 +50|288|1.0 +299|581|1.0 +356|380|0.9805806756909202 +348|728|1.0 +36|501|1.0 +41|497|1.0 +36|515|0.6246950475544243 +461|968|1.0 +318|728|0.5144957554275265 +202|968|1.0 +299|461|1.0 +501|593|0.565685424949238 +150|745|0.9284766908852594 +661|919|0.7071067811865475 +34|860|1.0 +176|299|1.0 +47|968|1.0 +515|589|0.7808688094430304 +202|357|1.0 +34|501|1.0 +1|595|1.0 +224|860|1.0 +412|593|0.565685424949238 +299|919|0.7071067811865475 +39|348|1.0 +39|265|0.6 +229|461|1.0 +6|509|1.0 +229|353|1.0 +176|860|1.0 +356|509|0.19611613513818404 +661|938|1.0 +150|202|0.3713906763541037 +163|593|0.7071067811865475 +36|908|1.0 +16|581|1.0 +21|235|1.0 +48|720|1.0 +353|506|1.0 +457|982|1.0 +194|581|1.0 +368|442|1.0 +296|800|1.0 +176|229|1.0 +21|515|0.7808688094430304 +531|914|1.0 +32|202|1.0 +288|412|1.0 +442|480|0.6622661785325219 +866|896|1.0 +16|501|1.0 +501|800|1.0 +647|902|1.0 +163|380|1.0 +377|714|1.0 +110|480|0.6622661785325219 +50|356|0.19611613513818404 +215|318|0.5144957554275265 +608|914|0.7071067811865475 +6|551|1.0 +368|590|0.7808688094430304 +24|994|1.0 +296|896|1.0 +202|509|1.0 +260|527|0.4923659639173309 +1|914|1.0 +321|562|1.0 +902|920|1.0 +165|380|1.0 +202|299|1.0 +36|913|1.0 +16|733|0.19611613513818404 +39|229|1.0 +41|150|0.3713906763541037 +527|588|1.0 +531|608|0.7071067811865475 +648|902|0.8 +229|968|1.0 +515|593|0.9055385138137417 +459|780|1.0 +356|920|0.9805806756909202 +29|162|1.0 +150|908|0.3713906763541037 +39|994|1.0 +24|229|1.0 +41|50|1.0 +349|380|1.0 +29|348|1.0 +21|95|1.0 +6|32|1.0 +498|589|1.0 +36|202|1.0 +353|509|1.0 +52|318|0.5144957554275265 +34|215|1.0 +39|551|1.0 +348|515|0.6246950475544243 +95|318|0.8574929257125441 +215|733|0.19611613513818404 +229|593|0.565685424949238 +162|714|1.0 +215|377|1.0 +265|353|0.6 +501|509|1.0 +442|648|0.8 +215|299|1.0 +34|377|1.0 +506|593|0.565685424949238 +24|593|0.565685424949238 +348|356|0.19611613513818404 +6|176|1.0 +590|736|0.7808688094430304 +52|581|1.0 +150|661|0.9284766908852594 +509|608|0.7071067811865475 +52|608|0.7071067811865475 +229|356|0.19611613513818404 +299|377|1.0 +194|908|1.0 +36|497|1.0 +95|457|1.0 +32|506|1.0 +349|515|0.7808688094430304 +47|296|1.0 +356|551|0.19611613513818404 +509|562|1.0 +150|551|0.3713906763541037 +48|260|0.4923659639173309 +356|608|0.1386750490563073 +32|919|0.7071067811865475 +457|902|1.0 +357|896|1.0 +50|229|1.0 +783|919|0.7071067811865475 +50|272|1.0 +1|594|1.0 +661|745|1.0 +296|551|1.0 +36|176|1.0 +229|994|1.0 +50|896|1.0 +506|714|1.0 +47|224|1.0 +41|162|1.0 +202|562|1.0 +50|800|1.0 +457|647|1.0 +292|480|0.6622661785325219 +24|377|1.0 +163|434|1.0 +50|318|0.5144957554275265 +260|914|0.4923659639173309 +235|380|1.0 +272|896|1.0 +480|593|0.6930735005704535 +36|581|1.0 +353|461|1.0 +29|593|0.565685424949238 +497|501|1.0 +292|593|0.7071067811865475 +215|728|1.0 +461|913|1.0 +52|733|0.19611613513818404 +353|866|1.0 +50|919|0.7071067811865475 +321|593|0.565685424949238 +36|461|1.0 +16|41|1.0 +527|938|1.0 +497|908|1.0 +6|860|1.0 +229|714|1.0 +215|356|0.19611613513818404 +860|866|1.0 +349|434|1.0 +377|515|0.6246950475544243 +150|299|0.3713906763541037 +110|590|0.7808688094430304 +265|457|0.8 +321|728|1.0 +162|348|1.0 +509|728|1.0 +16|908|1.0 +515|648|0.6246950475544244 +235|368|1.0 +24|50|1.0 +215|515|0.6246950475544243 +292|920|1.0 +265|442|0.8 +29|377|1.0 +215|608|0.7071067811865475 +48|150|0.9284766908852594 +501|994|1.0 +299|593|0.565685424949238 +16|356|0.19611613513818404 +110|163|1.0 +24|733|0.19611613513818404 +48|594|1.0 +506|860|1.0 +589|648|0.8 +162|509|1.0 +551|913|1.0 +194|501|1.0 +224|497|1.0 +36|377|1.0 +110|920|1.0 +714|896|1.0 +318|501|0.5144957554275265 +498|780|1.0 +412|461|1.0 +176|296|1.0 +357|728|1.0 +194|714|1.0 +235|647|1.0 +457|780|1.0 +348|357|1.0 +288|296|1.0 +150|515|0.23200591622629663 +34|47|1.0 +356|434|0.9805806756909202 +229|866|1.0 +272|800|1.0 +480|982|0.6622661785325219 +34|581|1.0 +95|442|1.0 +296|353|1.0 +47|728|1.0 +224|866|1.0 +176|581|1.0 +16|202|1.0 +21|349|1.0 +356|593|0.8043152845265822 +47|866|1.0 +866|913|1.0 +34|412|1.0 +459|515|0.7808688094430304 +296|593|0.565685424949238 +229|562|1.0 +52|229|1.0 +412|908|1.0 +260|594|0.4923659639173309 +176|908|1.0 +34|551|1.0 +509|968|1.0 +235|480|0.6622661785325219 +480|498|0.6622661785325219 +163|920|1.0 +39|461|1.0 +272|288|1.0 +6|34|1.0 +353|860|1.0 +353|908|1.0 +6|919|0.7071067811865475 +39|919|0.7071067811865475 +39|272|1.0 +292|982|1.0 +783|938|1.0 +551|728|1.0 +288|348|1.0 +368|736|1.0 +176|353|1.0 +6|215|1.0 +224|353|1.0 +21|356|0.9805806756909202 +296|356|0.19611613513818404 +296|860|1.0 +215|265|0.6 +593|608|0.39999999999999997 +36|593|0.565685424949238 +380|736|1.0 +52|150|0.3713906763541037 +318|356|0.9417419115948374 +41|908|1.0 +608|661|0.7071067811865475 +176|356|0.19611613513818404 +457|648|0.8 +380|442|1.0 +914|938|1.0 +47|299|1.0 +21|165|1.0 +349|902|1.0 +224|728|1.0 +95|736|1.0 +16|608|0.7071067811865475 +349|356|0.9805806756909202 +498|515|0.7808688094430304 +41|176|1.0 +29|800|1.0 +176|224|1.0 +47|509|1.0 +357|608|0.7071067811865475 +353|728|1.0 +509|714|1.0 +515|608|0.44172610429938614 +16|562|1.0 +356|442|0.9805806756909202 +150|938|0.9284766908852594 +39|497|1.0 +272|353|1.0 +272|356|0.19611613513818404 +16|994|1.0 +16|176|1.0 +16|318|0.5144957554275265 +47|860|1.0 +202|608|0.7071067811865475 +292|902|1.0 +29|728|1.0 +356|461|0.19611613513818404 +29|318|0.5144957554275265 +356|581|0.19611613513818404 +595|914|1.0 +6|52|1.0 +165|736|1.0 +32|515|0.6246950475544243 +47|896|1.0 +497|714|1.0 +52|176|1.0 +215|321|1.0 +24|32|1.0 +272|919|0.7071067811865475 +357|412|1.0 +288|908|1.0 +588|783|1.0 +434|459|1.0 +34|728|1.0 +501|913|1.0 +52|348|1.0 +272|714|1.0 +292|356|0.9805806756909202 +21|648|0.8 +162|194|1.0 +461|714|1.0 +6|593|0.565685424949238 +194|593|0.565685424949238 +562|581|1.0 +235|590|0.7808688094430304 +588|919|0.7071067811865475 +265|357|0.6 +36|994|1.0 +224|994|1.0 +296|506|1.0 +588|594|1.0 +21|368|1.0 +32|581|1.0 +24|288|1.0 +412|562|1.0 +229|515|0.6246950475544243 +29|733|0.19611613513818404 +377|728|1.0 +296|581|1.0 +34|229|1.0 +150|272|0.3713906763541037 +531|588|1.0 +32|52|1.0 +497|860|1.0 +265|860|0.6 +47|150|0.3713906763541037 +800|866|1.0 +176|733|0.19611613513818404 +348|551|1.0 +16|509|1.0 +356|913|0.19611613513818404 +318|919|0.3638034375544994 +50|968|1.0 +380|982|1.0 +24|357|1.0 +720|745|1.0 +457|593|0.7071067811865475 +531|745|1.0 +552|653|1.0 +265|913|0.6 +589|736|1.0 +531|595|1.0 +162|800|1.0 +202|229|1.0 +745|914|1.0 +357|994|1.0 +162|551|1.0 +50|224|1.0 +163|736|1.0 +224|714|1.0 +162|176|1.0 +162|377|1.0 +39|509|1.0 +733|994|0.19611613513818404 +318|551|0.5144957554275265 +265|733|0.11766968108291043 +348|506|1.0 +459|590|0.7808688094430304 +176|562|1.0 +150|229|0.3713906763541037 +32|593|0.565685424949238 +32|41|1.0 +6|50|1.0 +318|780|0.8574929257125441 +41|47|1.0 +348|733|0.19611613513818404 +6|714|1.0 +288|860|1.0 +47|321|1.0 +6|377|1.0 +497|562|1.0 +24|562|1.0 +235|902|1.0 +224|272|1.0 +318|349|0.8574929257125441 +434|920|1.0 +509|866|1.0 +52|919|0.7071067811865475 +34|506|1.0 +593|800|0.565685424949238 +272|299|1.0 +348|919|0.7071067811865475 +733|800|0.19611613513818404 +6|348|1.0 +292|648|0.8 +590|593|0.8171932929538644 +52|908|1.0 +110|265|0.8 +6|356|0.19611613513818404 +562|860|1.0 +498|902|1.0 +6|353|1.0 +29|299|1.0 +50|265|0.6 +39|224|1.0 +272|733|0.19611613513818404 +552|593|0.4242640687119285 +150|588|0.9284766908852594 +150|497|0.3713906763541037 +47|515|0.6246950475544243 +95|165|1.0 +29|321|1.0 +235|498|1.0 +202|896|1.0 +497|913|1.0 +368|515|0.7808688094430304 +318|982|0.8574929257125441 +47|593|0.565685424949238 +36|353|1.0 +16|506|1.0 +50|509|1.0 +296|913|1.0 +506|994|1.0 +41|353|1.0 +48|595|1.0 +110|442|1.0 +165|515|0.7808688094430304 +733|919|0.1386750490563073 +194|896|1.0 +29|32|1.0 +296|348|1.0 +6|41|1.0 +41|412|1.0 +349|780|1.0 +163|648|0.8 +110|368|1.0 +39|515|0.6246950475544243 +32|461|1.0 +272|608|0.7071067811865475 +194|608|0.7071067811865475 +162|896|1.0 +24|162|1.0 +497|919|0.7071067811865475 +733|896|0.19611613513818404 +353|919|0.7071067811865475 +581|908|1.0 +501|562|1.0 +24|296|1.0 +527|594|1.0 +32|224|1.0 +95|590|0.7808688094430304 +318|913|0.5144957554275265 +29|608|0.7071067811865475 +47|800|1.0 +377|501|1.0 +296|509|1.0 +224|356|0.19611613513818404 +593|733|0.5269651864139677 +714|728|1.0 +229|608|0.7071067811865475 +800|919|0.7071067811865475 +162|353|1.0 +215|288|1.0 +377|412|1.0 +41|229|1.0 +194|860|1.0 +368|902|1.0 +21|110|1.0 +163|356|0.9805806756909202 +194|321|1.0 +531|938|1.0 +36|229|1.0 +176|265|0.6 +21|593|0.7071067811865475 +176|497|1.0 +318|498|0.8574929257125441 +194|202|1.0 +176|377|1.0 +581|860|1.0 +39|150|0.3713906763541037 +110|780|1.0 +150|914|0.9284766908852594 +215|896|1.0 +272|860|1.0 +215|348|1.0 +95|480|0.6622661785325219 +235|292|1.0 +215|229|1.0 +48|527|1.0 +24|36|1.0 +41|551|1.0 +162|733|0.19611613513818404 +589|780|1.0 +39|321|1.0 +194|215|1.0 +110|648|0.8 +461|501|1.0 +608|733|0.1386750490563073 +36|896|1.0 +163|235|1.0 +377|919|0.7071067811865475 +32|562|1.0 +32|908|1.0 +353|714|1.0 +593|780|0.7071067811865475 +36|509|1.0 +34|299|1.0 +265|349|0.8 +357|515|0.6246950475544243 +581|608|0.7071067811865475 +265|896|0.6 +29|501|1.0 +162|913|1.0 +150|215|0.3713906763541037 +229|860|1.0 +356|498|0.9805806756909202 +288|728|1.0 +34|866|1.0 +165|459|1.0 +581|994|1.0 +866|994|1.0 +224|229|1.0 +162|908|1.0 +1|919|0.7071067811865475 +150|288|0.3713906763541037 +296|866|1.0 +165|442|1.0 +860|896|1.0 +29|288|1.0 +224|461|1.0 +224|896|1.0 +497|994|1.0 +272|866|1.0 +215|551|1.0 +165|647|1.0 +377|581|1.0 +296|968|1.0 +47|162|1.0 +32|162|1.0 +299|506|1.0 +16|461|1.0 +348|509|1.0 +150|527|0.9284766908852594 +780|902|1.0 +265|434|0.8 +95|110|1.0 +215|714|1.0 +176|919|0.7071067811865475 +202|348|1.0 +296|461|1.0 +163|590|0.7808688094430304 +34|176|1.0 +589|593|0.7071067811865475 +501|968|1.0 +34|194|1.0 +265|780|0.8 +16|36|1.0 +356|902|0.9805806756909202 +562|608|0.7071067811865475 +272|461|1.0 +16|24|1.0 +348|908|1.0 +357|501|1.0 +50|202|1.0 +380|457|1.0 +562|728|1.0 +194|866|1.0 +16|353|1.0 +50|321|1.0 +165|318|0.8574929257125441 +34|162|1.0 +176|357|1.0 +110|380|1.0 +356|368|0.9805806756909202 +593|913|0.565685424949238 +50|593|0.565685424949238 +588|720|1.0 +272|348|1.0 +29|896|1.0 +36|150|0.3713906763541037 +1|527|1.0 +908|994|1.0 +608|720|0.7071067811865475 +318|648|0.6859943405700353 +202|728|1.0 +202|908|1.0 +459|902|1.0 +647|736|1.0 +714|866|1.0 +202|296|1.0 +41|265|0.6 +593|653|0.4242640687119285 +32|348|1.0 +509|733|0.19611613513818404 +318|412|0.5144957554275265 +176|194|1.0 +552|590|0.6246950475544243 +412|509|1.0 +32|356|0.19611613513818404 +353|994|1.0 +515|994|0.6246950475544243 +590|653|0.6246950475544243 +29|272|1.0 +32|714|1.0 +6|968|1.0 +36|562|1.0 +50|913|1.0 +860|919|0.7071067811865475 +349|498|1.0 +6|321|1.0 +215|908|1.0 +29|913|1.0 +412|497|1.0 +16|321|1.0 +720|938|1.0 +299|994|1.0 +162|412|1.0 +165|265|0.8 +506|908|1.0 +41|348|1.0 +515|968|0.6246950475544243 +299|968|1.0 +6|202|1.0 +48|661|1.0 +165|982|1.0 +16|866|1.0 +215|357|1.0 +34|515|0.6246950475544243 +29|202|1.0 +412|551|1.0 +434|590|0.7808688094430304 +32|215|1.0 +562|896|1.0 +36|47|1.0 +165|902|1.0 +165|434|1.0 +497|515|0.6246950475544243 +318|353|0.5144957554275265 +288|356|0.19611613513818404 +52|202|1.0 +459|593|0.7071067811865475 +272|968|1.0 +461|506|1.0 +150|720|0.9284766908852594 +562|714|1.0 +215|968|1.0 +653|733|0.9805806756909202 +194|913|1.0 +224|800|1.0 +288|714|1.0 +165|368|1.0 +595|919|0.7071067811865475 +229|299|1.0 +318|589|0.8574929257125441 +150|176|0.3713906763541037 +412|501|1.0 +461|551|1.0 +215|224|1.0 +321|356|0.19611613513818404 +29|265|0.6 +562|733|0.19611613513818404 +434|442|1.0 +318|459|0.8574929257125441 +29|562|1.0 +52|506|1.0 +348|377|1.0 +562|866|1.0 +202|272|1.0 +24|318|0.5144957554275265 +21|982|1.0 +515|647|0.7808688094430304 +272|593|0.565685424949238 +194|348|1.0 +150|860|0.3713906763541037 +150|562|0.3713906763541037 +412|714|1.0 +501|515|0.6246950475544243 +497|968|1.0 +318|368|0.8574929257125441 +356|589|0.9805806756909202 +39|52|1.0 +860|913|1.0 +356|800|0.19611613513818404 +34|896|1.0 +442|780|1.0 +380|902|1.0 +150|728|0.3713906763541037 +377|497|1.0 +551|994|1.0 +595|938|1.0 +95|647|1.0 +6|24|1.0 +265|368|0.8 +24|509|1.0 +110|589|1.0 +368|920|1.0 +32|176|1.0 +110|982|1.0 +461|908|1.0 +150|913|0.3713906763541037 +595|720|1.0 +21|920|1.0 +356|457|0.9805806756909202 +498|736|1.0 +110|165|1.0 +110|457|1.0 +733|860|0.19611613513818404 +318|800|0.5144957554275265 +590|920|0.7808688094430304 +593|714|0.565685424949238 +36|728|1.0 +41|357|1.0 +353|896|1.0 +299|913|1.0 +714|800|1.0 +32|47|1.0 +728|860|1.0 +47|581|1.0 +50|506|1.0 +150|800|0.3713906763541037 +41|714|1.0 +32|968|1.0 +202|321|1.0 +215|461|1.0 +260|480|0.6521546507260246 +318|994|0.5144957554275265 +24|194|1.0 +349|459|1.0 +229|506|1.0 +6|562|1.0 +36|265|0.6 +176|288|1.0 +292|434|1.0 +16|229|1.0 +32|194|1.0 +348|608|0.7071067811865475 +202|800|1.0 +34|224|1.0 +229|318|0.5144957554275265 +461|515|0.6246950475544243 +459|982|1.0 +356|728|0.19611613513818404 +509|896|1.0 +39|299|1.0 +860|968|1.0 +34|150|0.3713906763541037 +224|412|1.0 +50|194|1.0 +202|866|1.0 +260|648|0.36927447293799814 +24|202|1.0 +29|215|1.0 +24|41|1.0 +176|501|1.0 +902|982|1.0 +29|194|1.0 +6|728|1.0 +41|562|1.0 +47|229|1.0 +6|800|1.0 +461|509|1.0 +215|562|1.0 +24|265|0.6 +588|914|1.0 +229|288|1.0 +265|321|0.6 +321|994|1.0 +21|780|1.0 +318|357|0.5144957554275265 +50|150|0.3713906763541037 +506|800|1.0 +480|589|0.6622661785325219 +442|457|1.0 +265|800|0.6 +6|357|1.0 +356|908|0.19611613513818404 +919|938|0.7071067811865475 +52|224|1.0 +162|357|1.0 +356|968|0.19611613513818404 +515|896|0.6246950475544243 +150|593|0.2100902925755561 +47|551|1.0 +39|357|1.0 +6|913|1.0 +21|292|1.0 +162|728|1.0 +348|461|1.0 +229|800|1.0 +608|919|0.9999999999999998 +908|919|0.7071067811865475 +412|913|1.0 +498|590|0.7808688094430304 +509|593|0.565685424949238 +235|318|0.8574929257125441 +353|497|1.0 +1|608|0.7071067811865475 +348|968|1.0 +162|321|1.0 +50|733|0.19611613513818404 +368|982|1.0 +265|515|0.999512076087079 +36|506|1.0 +581|728|1.0 +265|920|0.8 +434|480|0.6622661785325219 +589|920|1.0 +321|919|0.7071067811865475 +461|994|1.0 +501|908|1.0 +321|461|1.0 +348|562|1.0 +50|215|1.0 +860|994|1.0 +728|800|1.0 +34|461|1.0 +501|551|1.0 +296|562|1.0 +745|783|1.0 +459|920|1.0 +41|506|1.0 +272|318|0.5144957554275265 +292|457|1.0 +95|235|1.0 +461|733|0.19611613513818404 +380|593|0.7071067811865475 +32|913|1.0 +908|968|1.0 +165|356|0.9805806756909202 +265|480|0.5298129428260175 +52|288|1.0 +318|608|0.3638034375544994 +165|292|1.0 +736|920|1.0 +150|357|0.3713906763541037 +202|356|0.19611613513818404 +52|593|0.565685424949238 +235|736|1.0 +32|551|1.0 +24|800|1.0 +356|648|0.7844645405527362 +36|714|1.0 +562|913|1.0 +47|994|1.0 +229|348|1.0 +509|919|0.7071067811865475 +52|896|1.0 +176|509|1.0 +150|296|0.3713906763541037 +321|357|1.0 +380|590|0.7808688094430304 +194|299|1.0 +150|866|0.3713906763541037 +377|562|1.0 +150|412|0.3713906763541037 +163|459|1.0 +235|589|1.0 +434|902|1.0 +224|321|1.0 +52|265|0.6 +357|377|1.0 +349|590|0.7808688094430304 +459|648|0.8 +24|506|1.0 +36|296|1.0 +34|39|1.0 +299|412|1.0 +16|497|1.0 +349|982|1.0 +593|920|0.7071067811865475 +527|720|1.0 +515|908|0.6246950475544243 +24|860|1.0 +47|913|1.0 +39|501|1.0 +380|920|1.0 +348|714|1.0 +32|150|0.3713906763541037 +39|896|1.0 +296|318|0.5144957554275265 +29|47|1.0 +110|593|0.7071067811865475 +95|163|1.0 +562|919|0.7071067811865475 +733|908|0.19611613513818404 +150|994|0.3713906763541037 +41|215|1.0 +515|714|0.6246950475544243 +459|736|1.0 +110|515|0.7808688094430304 +551|866|1.0 +318|457|0.8574929257125441 +457|498|1.0 +551|919|0.7071067811865475 +368|457|1.0 +29|229|1.0 +368|648|0.8 +24|581|1.0 +52|497|1.0 +150|581|0.3713906763541037 +353|800|1.0 +150|260|0.4571503208824944 +36|194|1.0 +260|783|0.4923659639173309 +36|318|0.5144957554275265 +202|501|1.0 +29|34|1.0 +589|590|0.7808688094430304 +24|866|1.0 +357|581|1.0 +272|412|1.0 +349|480|0.6622661785325219 +461|728|1.0 +39|50|1.0 +16|714|1.0 +908|913|1.0 +515|902|0.7808688094430304 +202|215|1.0 +442|515|0.7808688094430304 +318|509|0.5144957554275265 +733|866|0.19611613513818404 +50|551|1.0 +6|908|1.0 +506|866|1.0 +150|318|0.1910789265895446 +41|919|0.7071067811865475 +224|296|1.0 +32|318|0.5144957554275265 +551|581|1.0 +357|866|1.0 +48|745|1.0 +714|968|1.0 +215|296|1.0 +165|593|0.7071067811865475 +34|356|0.19611613513818404 +235|648|0.8 +6|150|0.3713906763541037 +229|551|1.0 +348|353|1.0 +29|176|1.0 +296|908|1.0 +39|860|1.0 +377|913|1.0 +39|318|0.5144957554275265 +800|908|1.0 +265|412|0.6 +296|299|1.0 +52|913|1.0 +48|608|0.7071067811865475 +349|589|1.0 +288|800|1.0 +647|982|1.0 +728|908|1.0 +34|353|1.0 +52|299|1.0 +412|608|0.7071067811865475 +733|913|0.19611613513818404 +41|52|1.0 +299|714|1.0 +527|608|0.7071067811865475 +163|349|1.0 +296|357|1.0 +509|515|0.6246950475544243 +581|593|0.565685424949238 +509|581|1.0 +1|531|1.0 +176|318|0.5144957554275265 +589|647|1.0 +377|896|1.0 +163|165|1.0 +165|457|1.0 +41|608|0.7071067811865475 +608|714|0.7071067811865475 +866|919|0.7071067811865475 +150|968|0.3713906763541037 +6|299|1.0 +41|321|1.0 +6|896|1.0 +527|919|0.7071067811865475 +41|860|1.0 +457|589|1.0 +36|41|1.0 +215|412|1.0 +497|509|1.0 +368|380|1.0 +165|480|0.6622661785325219 +434|982|1.0 +318|506|0.5144957554275265 +21|902|1.0 +162|288|1.0 +34|321|1.0 +202|224|1.0 +356|994|0.19611613513818404 +377|860|1.0 +299|357|1.0 +434|589|1.0 +52|357|1.0 +515|913|0.6246950475544243 +16|551|1.0 +506|515|0.6246950475544243 +357|506|1.0 +412|994|1.0 +913|919|0.7071067811865475 +501|608|0.7071067811865475 +29|52|1.0 +736|902|1.0 +593|860|0.565685424949238 +368|589|1.0 +52|509|1.0 +551|593|0.565685424949238 +47|506|1.0 +288|353|1.0 +581|913|1.0 +497|733|0.19611613513818404 +110|235|1.0 +357|860|1.0 +194|800|1.0 +110|356|0.9805806756909202 +608|938|0.7071067811865475 +896|919|0.7071067811865475 +296|608|0.7071067811865475 +292|442|1.0 +272|551|1.0 +150|162|0.3713906763541037 +515|920|0.7808688094430304 +16|348|1.0 +39|202|1.0 +39|47|1.0 +368|480|0.6622661785325219 +461|562|1.0 +299|860|1.0 +728|733|0.19611613513818404 +32|288|1.0 +162|461|1.0 +16|919|0.7071067811865475 +648|653|0.6 +299|562|1.0 +52|272|1.0 +442|902|1.0 +509|860|1.0 +224|357|1.0 +24|215|1.0 +50|562|1.0 +16|39|1.0 +176|321|1.0 +318|480|0.5678885630303183 +39|176|1.0 +515|736|0.7808688094430304 +349|920|1.0 +506|509|1.0 +215|919|0.7071067811865475 +318|442|0.8574929257125441 +162|318|0.5144957554275265 +41|194|1.0 +913|968|1.0 +353|733|0.19611613513818404 +176|896|1.0 +318|593|0.897381812634432 +41|299|1.0 +265|714|0.6 +356|714|0.19611613513818404 +224|581|1.0 +461|896|1.0 +357|461|1.0 +32|353|1.0 +52|356|0.19611613513818404 +442|920|1.0 +551|562|1.0 +29|968|1.0 +265|593|0.9050966799187807 +34|202|1.0 +229|265|0.6 +95|380|1.0 +50|714|1.0 +176|412|1.0 +39|215|1.0 +800|896|1.0 +24|353|1.0 +260|552|0.6154574548966636 +497|593|0.565685424949238 +39|562|1.0 +29|50|1.0 +34|52|1.0 +442|593|0.7071067811865475 +16|194|1.0 +515|551|0.6246950475544243 +95|920|1.0 +594|608|0.7071067811865475 +34|288|1.0 +260|608|0.3481553119113956 +32|50|1.0 +16|50|1.0 +260|590|0.3844732240543962 +745|919|0.7071067811865475 +527|661|1.0 +235|920|1.0 +36|919|0.7071067811865475 +176|272|1.0 +321|896|1.0 +442|590|0.7808688094430304 +32|728|1.0 +506|913|1.0 +272|506|1.0 +6|506|1.0 +24|728|1.0 +442|589|1.0 +265|590|0.6246950475544244 +47|608|0.7071067811865475 +6|36|1.0 +16|412|1.0 +95|434|1.0 +527|745|1.0 +265|902|0.8 +353|357|1.0 +321|353|1.0 +509|551|1.0 +318|562|0.5144957554275265 +442|459|1.0 +348|593|0.565685424949238 +215|581|1.0 +32|509|1.0 +6|994|1.0 +194|506|1.0 +480|733|0.5195243334661311 +176|461|1.0 +150|896|0.3713906763541037 +194|288|1.0 +321|515|0.6246950475544243 +29|866|1.0 +176|348|1.0 +551|908|1.0 +194|515|0.6246950475544243 +34|800|1.0 +52|194|1.0 +292|590|0.7808688094430304 +24|412|1.0 +368|780|1.0 +318|321|0.5144957554275265 +41|593|0.565685424949238 +194|497|1.0 +162|299|1.0 +34|913|1.0 +357|497|1.0 +194|562|1.0 +714|913|1.0 +224|515|0.6246950475544243 +95|356|0.9805806756909202 +95|459|1.0 +434|457|1.0 +36|299|1.0 +47|714|1.0 +41|296|1.0 +497|551|1.0 +506|733|0.19611613513818404 +39|913|1.0 +235|459|1.0 +162|506|1.0 +16|357|1.0 +6|16|1.0 +229|581|1.0 +229|501|1.0 +594|914|1.0 +29|36|1.0 +39|908|1.0 +299|318|0.5144957554275265 +321|714|1.0 +348|497|1.0 +165|235|1.0 +50|866|1.0 +348|994|1.0 +162|501|1.0 +480|552|0.5298129428260175 +95|982|1.0 +34|357|1.0 +48|914|1.0 +728|994|1.0 +608|994|0.7071067811865475 +47|265|0.6 +32|412|1.0 +36|162|1.0 +368|647|1.0 +356|515|0.888217643155949 +50|296|1.0 +6|224|1.0 +412|581|1.0 +260|593|0.26111648393354675 +224|377|1.0 +368|498|1.0 +215|994|1.0 +16|515|0.6246950475544243 +288|461|1.0 +292|498|1.0 +648|780|0.8 +24|913|1.0 +562|968|1.0 +48|938|1.0 +110|434|1.0 +288|608|0.7071067811865475 +36|412|1.0 +34|265|0.6 +457|459|1.0 +163|442|1.0 +288|581|1.0 +318|377|0.5144957554275265 +39|288|1.0 +229|913|1.0 +16|860|1.0 +224|908|1.0 +299|509|1.0 +235|457|1.0 +800|968|1.0 +34|733|0.19611613513818404 +562|908|1.0 +321|509|1.0 +321|551|1.0 +176|593|0.565685424949238 +260|919|0.3481553119113956 +150|321|0.3713906763541037 +353|562|1.0 +260|745|0.4923659639173309 +318|515|0.9909924304103233 +272|581|1.0 +47|919|0.7071067811865475 +288|506|1.0 +265|292|0.8 +235|434|1.0 +202|318|0.5144957554275265 +224|501|1.0 +736|780|1.0 +593|728|0.565685424949238 diff --git a/data/libSVMPath/._SUCCESS.crc b/data/libSVMPath/._SUCCESS.crc new file mode 100644 index 0000000000000000000000000000000000000000..3b7b044936a890cd8d651d349a752d819d71d22c Binary files /dev/null and b/data/libSVMPath/._SUCCESS.crc differ diff --git a/data/libSVMPath/.part-00000.crc b/data/libSVMPath/.part-00000.crc new file mode 100644 index 0000000000000000000000000000000000000000..afe0e5d96dc1489ab13ffc2afdb9db51478e3807 Binary files /dev/null and b/data/libSVMPath/.part-00000.crc differ diff --git a/data/libSVMPath/.part-00001.crc b/data/libSVMPath/.part-00001.crc new file mode 100644 index 0000000000000000000000000000000000000000..60e233025d1e5fa8bb4c8f9d5ad896a19f0978bb Binary files /dev/null and b/data/libSVMPath/.part-00001.crc differ diff --git a/data/libSVMPath/_SUCCESS b/data/libSVMPath/_SUCCESS new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/data/libSVMPath/part-00000 b/data/libSVMPath/part-00000 new file mode 100644 index 0000000000000000000000000000000000000000..5489e316ed669bff5deb47ef09a4b94b5e4c93cf --- /dev/null +++ b/data/libSVMPath/part-00000 @@ -0,0 +1,2 @@ +4 260:5 480:4 +2 21:1 95:2 110:5 163:4 165:3 235:3 265:4 292:3 318:5 349:4 356:5 368:4 380:5 434:2 442:3 457:4 459:3 480:5 498:3 515:5 589:4 590:5 593:5 647:3 648:4 736:4 780:3 902:2 920:5 982:4 diff --git a/data/ratingslibsvm b/data/libSVMPath/part-00001 similarity index 71% rename from data/ratingslibsvm rename to data/libSVMPath/part-00001 index 6add3fbb1ec2e37c29716ef96e1e54122b7686d1..8f4a49dd4c4782eb3286dfedf9810787d4967979 100644 --- a/data/ratingslibsvm +++ b/data/libSVMPath/part-00001 @@ -1,5 +1,3 @@ -4 260:5 480:4 -2 21:1 95:2 110:5 163:4 165:3 235:3 265:4 292:3 318:5 349:4 356:5 368:4 380:5 434:2 442:3 457:4 459:3 480:5 498:3 515:5 589:4 590:5 593:5 647:3 648:4 736:4 780:3 902:2 920:5 982:4 5 6:2 16:3 24:1 29:5 32:4 34:4 36:3 39:3 41:4 47:3 50:5 52:2 150:2 162:4 176:4 194:3 202:2 215:3 224:3 229:3 265:3 272:3 288:2 296:4 299:3 318:3 321:3 348:4 353:2 356:1 357:2 377:4 412:2 461:3 497:3 501:1 506:4 509:4 515:4 551:4 562:4 581:3 593:4 608:4 714:4 728:4 733:1 800:2 860:2 866:4 896:4 908:4 913:5 919:4 968:3 994:5 3 104:4 260:5 480:4 552:4 590:4 593:3 648:3 653:4 733:5 1 1:5 48:5 150:5 260:4 527:5 531:4 588:4 594:4 595:5 608:4 661:3 720:3 745:3 783:4 914:3 919:4 938:4 diff --git a/data/hot_movies.csv b/data/ml-1m/hot_movies.csv similarity index 100% rename from data/hot_movies.csv rename to data/ml-1m/hot_movies.csv diff --git a/data/ratings b/data/ml-1m/ratings similarity index 100% rename from data/ratings rename to data/ml-1m/ratings diff --git a/data/user_movies.csv b/data/ml-1m/user_movies.csv similarity index 100% rename from data/user_movies.csv rename to data/ml-1m/user_movies.csv diff --git a/spark/README.md b/spark/README.md new file mode 100644 index 0000000000000000000000000000000000000000..cf348c580ba7ec43d6d7c5e3ca3a23235d6e6c81 --- /dev/null +++ b/spark/README.md @@ -0,0 +1,41 @@ +# 特征工程部分 +代码位于Features 类 +因为现实系统的rating 值,非常稀疏,为了节省存储空间和提升效率,在特征存储结构上,需要进行一些改动。主要思路如下: + +## 将rating 转为libsvm的方式存储 +用户对物品打分的数据,针对单个用户而言,对不同的物品的打分是很稀疏的。可以用libsvm格式来进行存储。 +``` +例如: 输入为 +1::661::3::978302109 +1::914::3::978301968 +转化之后结果为 +1 661:3 914:3 +``` + +## 将rating 转为 格式的DataFrame +id 为String +features 为 SparseVector + +# ItemCF +代码位于ItemCF 类 +## 相似度计算 +实现了两种方式,Jaccard 相似度 和 余弦相似度 + +## Jaccard +使用BitSet 存储每个用户的对该Item 是否有Ratting 的情况。 + +## 余弦相似度 +使用自带API实现 + + +## 基于Item 相似度 推荐单个物品 +选取该物品和其他物品的相似度向量。使用特征向量和相似度向量点乘即可。 + + +## 基于Item 相似度 推荐topK 的物品 +挖坑 + +# UserCF +挖坑 +## 根据topN的相似用户推荐 + \ No newline at end of file diff --git a/spark/src/main/scala/com/apachecn/recommand/colfliter/Features.scala b/spark/src/main/scala/com/apachecn/recommand/colfliter/Features.scala index 2f6374855f8add33ffe20b42f3ff6a86991b5b6c..141af349c74aee8082c4bab111efa45619b5db77 100644 --- a/spark/src/main/scala/com/apachecn/recommand/colfliter/Features.scala +++ b/spark/src/main/scala/com/apachecn/recommand/colfliter/Features.scala @@ -53,14 +53,15 @@ object Features{ def main(args: Array[String]): Unit = { /** + * 如需使用集群模式,修改入参,使用如下命令提交即可 * 提交命令 spark-submit --master yarn-cluster */ - val conf = new SparkConf().setAppName("Features Prepare") + val conf = new SparkConf().setAppName("Features Prepare").setMaster("local[*]") val sc = new SparkContext(conf) - val ratingsPath = args(0) - val libSVMOutPath = args(1) - val dfOutPath = args(2) - val featureSize = args(3).toInt + val ratingsPath = "..//data//ml-1m//ratings" + val libSVMOutPath = "..//data//libSVMPath" + val dfOutPath = "..//data//DFPath" + val featureSize = 3953 val testF = new Features @@ -69,3 +70,4 @@ object Features{ } } + diff --git a/spark/src/main/scala/com/apachecn/recommand/colfliter/ItemCF.scala b/spark/src/main/scala/com/apachecn/recommand/colfliter/ItemCF.scala index 852b19b7154be3f901a94061b7cdcf20ccb0a541..41e69da1c4749a7a6d2be844b8c00d7e87833eee 100644 --- a/spark/src/main/scala/com/apachecn/recommand/colfliter/ItemCF.scala +++ b/spark/src/main/scala/com/apachecn/recommand/colfliter/ItemCF.scala @@ -21,7 +21,7 @@ class ItemCF { val sqlContext = new SQLContext(sc) val rdd = sqlContext.read.parquet(featurePath).select("features") .rdd.map(x=>x(0).asInstanceOf[org.apache.spark.mllib.linalg.SparseVector]) - .map(x=>(x.indices)) + .map(x=>x.indices) .zipWithIndex() .map(x=>{ for (i <- x._1) yield { @@ -104,6 +104,13 @@ class ItemCF { } + /** + * 载入相似度矩阵 + * @param sc + * @param simPath + * @param featruesSize + * @return + */ def loadSimMatrix(sc: SparkContext, simPath: String, featruesSize: Int @@ -130,59 +137,144 @@ class ItemCF { } - def predictByMatrix(sc: SparkContext, - simMatrix: breeze.linalg.Matrix[Double], - featuresSize: Int, - featurePath: String, - resultPath: String - ): Unit ={ - val rdd = sc.textFile(featurePath) - .map(_.split(" ")) - .map(x=>(x.filter(g=>g.contains(":")))) - .map(x=>(x.map(_.split(":")).map(ar => (ar(0).toInt,ar(1).toDouble)))) - .map(x=>{ - val idx = x.map(_._1) - val v = x.map(_._2) - val vec: SparseVector[Double] = new SparseVector(idx, v, featuresSize) - vec + /** + * 根据Item 编号,从相似矩阵中获取该Item 的相似向量 + * @param simMatrix + * @param itemNum + * @return + */ + def getSimVecFromMatrix(simMatrix: SparseMatrix, itemNum: Int):Array[Double] ={ + val arr1 = for (i <- 0 until itemNum) yield { + simMatrix(i, itemNum) + } + val arr2 = for (i <- itemNum until simMatrix.numRows) yield { + simMatrix(itemNum, i) + } + (arr1 ++ arr2).toArray + } + + /** + * 基于Item 相似度向量 计算推荐单个物品时的得分,输出结果按得分降序排序 + * @param sc + * @param sim + * @param featurePath + * @return + */ + def predictBySimVecWithLibSVM(sc: SparkContext, + sim: Array[Double], + featurePath: String): RDD[(String, Double)] ={ + sc.textFile(featurePath).map(_.split(" ")).map(x=>{ + val id = x(0) + var score = 0.0 + for (i <- 1 until x.length){ + val idx = x(i).split(":")(0) + val value = x(i).split(":")(1) + score += value.toDouble * sim(idx.toInt) + } + (id,score) + }).sortBy(_._2,false) + } + + + /** + * 基于Item 相似度向量 计算推荐单个物品时的得分,输出结果按得分降序排序 + * @param sc + * @param sim + * @param featurePath + * @return + */ + def predictBySimVecWithDF(sc: SparkContext, + sim: Array[Double], + featurePath: String): RDD[(String, Double)] ={ + + val sqlContext = new SQLContext(sc) + sqlContext.read.parquet(featurePath).select("id","features") + .rdd.map(x=>{ + val p = x(0).toString + val v = x(1).asInstanceOf[org.apache.spark.mllib.linalg.SparseVector] + + val idxs = v.toSparse.indices + val values = v.toSparse.values + var score = 0.0 + for (i <- 0 until idxs.length){ + score += values(i) * sim(idxs(i)) + } + (p,score) }) -// .map(x=>(x.toDenseVector.toDenseMatrix.dot(simMatrix))) + .sortBy(_._2,false) } + } object ItemCF extends ItemCF{ + + + def main(args: Array[String]): Unit = { val conf = new SparkConf().setAppName("utils").setMaster("local[8]") val sc = new SparkContext(conf) val sqlContext = new SQLContext(sc) - val libsvmFeaturePath = "C:\\workspace\\data\\apacheCN\\libsvmOut" - val dfFeaturePath = "C:\\workspace\\data\\apacheCN\\dfOut" - val simPath = "C:\\workspace\\data\\apacheCN\\simPath" + val libsvmFeaturePath = "..//data//libSVMPath" + val dfFeaturePath = "..//data//DFPath" + val simPath = "..//data//SimPath" -// val JaccardSimPath = "..//data//jaccardSim" - val CosSimPath = "..//data//cosSim" val featureSize = 3953 -// -// val sim1 = computeJaccardSimWithLibSVM(sc,libsvmFeaturePath) -// sim1.entries.take(10) + testComputeSim() + testSaveAndLoadSimMatrix() + + + def testComputeSim(): Unit ={ + println("Test Compute Jaccard Sim With LibSVM ") + val sim1 = computeJaccardSimWithLibSVM(sc,libsvmFeaturePath) + sim1.entries.take(3).foreach(println) - val sim2 = computeCosSimWithLibSVM(sc,featureSize,libsvmFeaturePath) -// sim2.entries.take(10).foreach(println) -// saveSimMatrix(sc,simPath,sim2) + println("Test Compute Cossin Sim With LibSVM ") + val sim2 = computeCosSimWithLibSVM(sc,featureSize,libsvmFeaturePath) + sim2.entries.take(3).foreach(println) + + println("Test Compute Jaccard Sim With DataFrame ") val sim3 = computeJaccardSimWithDF(sc,dfFeaturePath) - sim3.entries.take(10) + sim3.entries.take(3).foreach(println) + + println("Test Compute Cossin Sim With DataFrame ") + val sim4 = computeCosSimWithDF(sc,dfFeaturePath) + sim4.entries.take(3).foreach(println) + } - val sim4 = computeCosSimWithDF(sc,dfFeaturePath) - sim4.entries.take(10) -// computeItemJaccardSim(sc,featurePath, JaccardSimPath) -// computeItemCosSim(sc,100,featurePath, CosSimPath) - val simMatrix = loadSimMatrix(sc, simPath, featureSize) -// val score = predict() + def testSaveAndLoadSimMatrix(): Unit ={ + val sim = computeCosSimWithLibSVM(sc,featureSize,libsvmFeaturePath) + saveSimMatrix(sc,simPath,sim) + + println("Save The SimMatrix") + + val simLoad = loadSimMatrix(sc, simPath, featureSize) + println(s"Load The SimMatrix. The Row Num Is ${simLoad.numRows} The Col Num Is ${simLoad.numCols}") + } + + def testPredict(): Unit ={ + val simMatrix = loadSimMatrix(sc, simPath, featureSize) + println(s"Load The SimMatrix. The Row Num Is ${simMatrix.numRows} The Col Num Is ${simMatrix.numCols}") + + val itemNum = 800 + val simVec = getSimVecFromMatrix(simMatrix,itemNum) + + println("Test Predict By SimVec With LibSVM ") + val score1 = predictBySimVecWithLibSVM(sc, simVec, libsvmFeaturePath) + score1.take(3).foreach(println) + + println("Test Predict By SimVec With DataFrame ") + val score2 = predictBySimVecWithDF(sc, simVec, dfFeaturePath) + score2.take(3).foreach(println) + + + + } + } }