搜狗實驗室:搜索引擎查詢日志庫設計為包括約1個月(2008年6月)Sogou搜索引擎部分網頁查詢需求及用戶點擊情況的網頁查詢日志資料集合,為進行中文搜索引擎用戶行為分析的研究者提供基準研究語料
目錄
原資料展示
業務需求
業務邏輯
分詞工具
Maven依賴
代碼實作
效果展現
搜狗搜索日志官網:http://www.sogou.com/labs/resource/q.php
?
迷你版日志下載鏈接:http://download.labs.sogou.com/dl/sogoulabdown/SogouQ/SogouQ.mini.zip
?
注:由于進行測驗使用,迷你版資料就可以滿足需求
原資料展示
?
注:原資料存在10000條 ,欄位分別為:訪問時間 \t 用戶ID \t [查詢詞] \t 該URL在回傳結果中的排名 \t 用戶點擊的順序號 \t 用戶點擊的URL
業務需求
需求說明: 對SougouSearchLog進行分詞并統計如下指標:
- 熱門搜索詞
- 用戶熱門搜索詞(帶上用戶id)
- 各個時間段搜索熱度
?
業務邏輯
業務邏輯:針對SougoQ用戶查詢日志資料中不同欄位,使用SparkContext讀取日志資料,封裝到RDD資料集中,呼叫Transformation函式和Action函式進行處理不同業務統計分析
分詞工具
HanLP官網:http://www.sogou.com/labs/resource/q.php
?
?
HanLP主要功能:基于HanLP最新技術,使用億級通用語料庫訓練,直接API呼叫,簡單高效!
Maven依賴
<dependency>
<groupId>com.hankcs</groupId>
<artifactId>hanlp</artifactId>
<version>portable-1.7.7</version>
</dependency>
HanLP入門案例
package org.example.spark import java.util import com.hankcs.hanlp.HanLP import com.hankcs.hanlp.seg.common.Term /** * Author tuomasi * Desc HanLP入門案例 */ object HanLPTest { def main(args: Array[String]): Unit = { val words = "[HanLP入門案例]" val terms: util.List[Term] = HanLP.segment(words) //分段 println(terms) //直接列印java的list:[[/w, HanLP/nx, 入門/vn, 案例/n, ]/w] import scala.collection.JavaConverters._ println(terms.asScala.map(_.word)) //轉為scala的list:ArrayBuffer([, HanLP, 入門, 案例, ]) val cleanWords1: String = words.replaceAll("\\[|\\]", "") //將"["或"]"替換為空"" //"HanLP入門案例" println(cleanWords1) //HanLP入門案例 println(HanLP.segment(cleanWords1).asScala.map(_.word)) //ArrayBuffer(HanLP, 入門, 案例) val log = """00:00:00 2982199073774412 [360安全衛士] 8 3 download.it.com.cn/softweb/software/firewall/antivirus/20067/17938.html""" val cleanWords2 = log.split("\\s+")(2) //[360安全衛士] .replaceAll("\\[|\\]", "") //360安全衛士 println(HanLP.segment(cleanWords2).asScala.map(_.word)) //ArrayBuffer(360, 安全衛士) } }控制臺列印效果
?
代碼實作
package org.example.spark
import com.hankcs.hanlp.HanLP
import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
import shapeless.record
import spire.std.tuples
import scala.collection.immutable.StringOps
import scala.collection.mutable
/**
* Author tuomasi
* Desc 需求:對SougouSearchLog進行分詞并統計如下指標:
* 1.熱門搜索詞
* 2.用戶熱門搜索詞(帶上用戶id)
* 3.各個時間段搜索熱度
*/
object SougouSearchLogAnalysis {
def main(args: Array[String]): Unit = {
//TODO 0.準備環境
val conf: SparkConf = new SparkConf().setAppName("spark").setMaster("local[*]")
val sc: SparkContext = new SparkContext(conf)
sc.setLogLevel("WARN")
//TODO 1.加載資料
val lines: RDD[String] = sc.textFile("data/input/SogouQ.sample")
//TODO 2.處理資料
//封裝資料
val SogouRecordRDD: RDD[SogouRecord] = lines.map(line => { //map是一個進去一個出去
val arr: Array[String] = line.split("\\s+")
SogouRecord(
arr(0),
arr(1),
arr(2),
arr(3).toInt,
arr(4).toInt,
arr(5)
)
})
//切割資料
/* val wordsRDD0: RDD[mutable.Buffer[String]] = SogouRecordRDD.map(record => {
val wordsStr: String = record.queryWords.replaceAll("\\[|\\]", "") //360安全衛士
import scala.collection.JavaConverters._ //將Java集合轉為scala集合
HanLP.segment(wordsStr).asScala.map(_.word) //ArrayBuffer(360, 安全衛士)
})*/
val wordsRDD: RDD[String] = SogouRecordRDD.flatMap(record => { //flatMap是一個進去,多個出去(出去之后會被壓扁) //360安全衛士==>[360, 安全衛士]
val wordsStr: String = record.queryWords.replaceAll("\\[|\\]", "") //360安全衛士
import scala.collection.JavaConverters._ //將Java集合轉為scala集合
HanLP.segment(wordsStr).asScala.map(_.word) //ArrayBuffer(360, 安全衛士)
})
//TODO 3.統計指標
//--1.熱門搜索詞
val result1: Array[(String, Int)] = wordsRDD
.filter(word => !word.equals(".") && !word.equals("+"))
.map((_, 1))
.reduceByKey(_ + _)
.sortBy(_._2, false)
.take(10)
//--2.用戶熱門搜索詞(帶上用戶id)
val userIdAndWordRDD: RDD[(String, String)] = SogouRecordRDD.flatMap(record => { //flatMap是一個進去,多個出去(出去之后會被壓扁) //360安全衛士==>[360, 安全衛士]
val wordsStr: String = record.queryWords.replaceAll("\\[|\\]", "") //360安全衛士
import scala.collection.JavaConverters._ //將Java集合轉為scala集合
val words: mutable.Buffer[String] = HanLP.segment(wordsStr).asScala.map(_.word) //ArrayBuffer(360, 安全衛士)
val userId: String = record.userId
words.map(word => (userId, word))
})
val result2: Array[((String, String), Int)] = userIdAndWordRDD
.filter(t => !t._2.equals(".") && !t._2.equals("+"))
.map((_, 1))
.reduceByKey(_ + _)
.sortBy(_._2, false)
.take(10)
//--3.各個時間段搜索熱度
val result3: Array[(String, Int)] = SogouRecordRDD.map(record => {
val timeStr: String = record.queryTime
val hourAndMitunesStr: String = timeStr.substring(0, 5)
(hourAndMitunesStr, 1)
}).reduceByKey(_ + _)
.sortBy(_._2, false)
.take(10)
//TODO 4.輸出結果
result1.foreach(println)
result2.foreach(println)
result3.foreach(println)
//TODO 5.釋放資源
sc.stop()
}
//準備一個樣例類用來封裝資料
/**
* 用戶搜索點擊網頁記錄Record
*
* @param queryTime 訪問時間,格式為:HH:mm:ss
* @param userId 用戶ID
* @param queryWords 查詢詞
* @param resultRank 該URL在回傳結果中的排名
* @param clickRank 用戶點擊的順序號
* @param clickUrl 用戶點擊的URL
*/
case class SogouRecord(
queryTime: String,
userId: String,
queryWords: String,
resultRank: Int,
clickRank: Int,
clickUrl: String
)
}
效果展現
?
注:對SougouSearchLog進行分詞并統計出了如下指標,熱門搜索詞,用戶熱門搜索詞(帶上用戶id),各個時間段搜索熱度,此效果與預期想法基本一致
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/421875.html
標籤:其他








