Sesenta y cinco, caso Spark-Comprehensive (análisis de registro de búsqueda de Sogou)

Sogou Lab: la base de datos de registro de consultas del motor de búsqueda está diseñada para incluir la recopilación de datos de registro de consultas web de algunos requisitos de consulta de páginas web y clics de usuarios del motor de búsqueda Sogou durante aproximadamente un mes (junio de 2008). Proporcionar un corpus de investigación de referencia para los investigadores que realizan análisis de comportamiento de usuarios de motores de búsqueda chinos.

contenido

Visualización de datos originales

Necesidades del negocio

Lógica de negocios

herramienta de segmentación de palabras

Dependencias expertas

Código

Visualización de efectos


Sitio web oficial del registro de búsqueda de Sogou: http://www.sogou.com/labs/resource/q.php

Enlace de descarga del mini registro: http://download.labs.sogou.com/dl/sogoulabdown/SogouQ/SogouQ.mini.zip

         Nota: debido al uso de prueba, la versión mini de los datos puede satisfacer las necesidades

Visualización de datos originales

        Nota: Hay 10000 piezas de datos originales, y los campos son: tiempo de acceso\t ID de usuario\t [palabra de consulta]\t la clasificación de la URL en los resultados devueltos\t el número de secuencia del clic del usuario\t el URL en la que el usuario hizo clic

Necesidades del negocio

Descripción del requisito:  Segmente SougouSearchLog y cuente los siguientes indicadores:

  1. términos de búsqueda populares
  2. Términos de búsqueda populares del usuario (con ID de usuario)
  3. Buscar popularidad en varios períodos de tiempo

 

Lógica de negocios

Lógica comercial: para que los usuarios de SougoQ consulten diferentes campos en los datos de registro, use SparkContext para leer los datos de registro, encapsúlelos en conjuntos de datos RDD y llame a las funciones de Transformación y Acción para procesar el análisis estadístico de diferentes negocios.

herramienta de segmentación de palabras

Sitio web oficial de HanLP: http://www.sogou.com/labs/resource/q.php

 

         Funciones principales de HanLP: Basado en la última tecnología de HanLP, utilizando entrenamiento de corpus general de mil millones de niveles, llamada API directa, ¡simple y eficiente!

Dependencias expertas

<dependency>
<groupId>com.hankcs</groupId>
<artifactId>hanlp</artifactId>
<version>portable-1.7.7</version>
</dependency>

Caja de inicio 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, 安全卫士)
  }
}

efecto de impresión de consola

 

Código

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
                        )
}

Visualización de efectos

         Nota: El SougouSearchLog está segmentado y se cuentan los siguientes indicadores, términos de búsqueda populares, términos de búsqueda populares del usuario (con ID de usuario) y popularidad de búsqueda en cada período de tiempo. Este efecto es básicamente el mismo que la idea esperada.

Supongo que te gusta

Origin blog.csdn.net/m0_54925305/article/details/122712863
Recomendado
Clasificación