精华内容
下载资源
问答
  • 电信用户行为分析
    千次阅读
    2022-06-27 09:29:37

    基于Spark的电商用户行为分析系统的设计与实现

    项目架构

    Flume–>Kafka–>Spark Streaming–>Mysql–>FineReport 10

    数据可视化使用第三方软件FineReport支持

    1. 数据采集:利用Java线程模拟行为数据写入被监控的文件

    模拟电商网站用户行为数据(也可与阿里云天池开源数据集:真实的淘宝或天猫用户行为数据)

    user_id	用户ID,整数类型,序列化后的用户ID
    item_id 商品ID,整数类型,序列化后的商品ID
    category_id 商品类目ID,整数类型,序列化后的商品所属类目ID
    behavior_type 行为类型,字符串,枚举类型,包括('pv','buy', 'cart','fav')
    ddate 行为发生的时间
    
    • flume实时监控数据文件,并将新增的用户行为数据采集传输给Kafka

    启动flume:

    flume-ng agent -c ./softwares/flume/conf/ -f ./flume2kafka.conf -n a1
    

    flume2kafka.conf

    a1.sources = r1
    a1.sinks = k1
    a1.channels = c1
    
    # Describe/configure the source
    # 这里其实是监控Linux命令的source,该命令是监控文件并将实时变化的内容输出
    a1.sources.r1.type = exec
    a1.sources.r1.command = tail -F /home/admin/bigdata.log
    
    # 设置kafka接收器 
    a1.sinks.k1.type = org.apache.flume.sink.kafka.KafkaSink
    # 设置kafka的broker地址和端口号
    a1.sinks.k1.brokerList=172.17.33.37:9092
    # 设置Kafka的topic
    a1.sinks.k1.topic=henry
    # 设置序列化的方式
    a1.sinks.k1.serializer.class=kafka.serializer.StringEncoder
    
    # use a channel which buffers events in memory
    a1.channels.c1.type=memory
    a1.channels.c1.capacity = 100000
    a1.channels.c1.transactionCapacity = 1000
    
    # Bind the source and sink to the channel
    a1.sources.r1.channels=c1
    a1.sinks.k1.channel=c1
    
    • Kafka接收数据:将flume传输过来的数据放入消息队列,等待spark streaming 消费
      启动zookeeper
    zkServer.sh start
    

    启动Kafka(-deamon后台启动)

    kafka-server-start.sh -daemon ./softwares/kafka/config/server.properties
    

    创建topic(3个分区,1个副本,topic名为henry)

    kafka-topics.sh --create --zookeeper 172.17.33.37:2181 --replication-factor 1 --partitions 3 --topic henry
    
    #查看所有topic
    kafka-topics.sh --list --zookeeper 172.17.33.37:2181 
    
    #定义一个Kafka生产者端口
    kafka-console-producer.sh --broker-list 172.17.33.37:9092 --topic henry
    
    #定义一个Kafka消费者端口
    kafka-console-consumer.sh --bootstrap-server 172.17.33.37:9092 --topic henry
    

    数据采集部分已准备完成,这里没有进行数据清洗而是将全量的上游数据传输至数据处理模块,统一处理

    2. 数据处理

    • spark streaming 程序为 实时等待流,从Kafka指定的topic中消费数据

    UserBehavior.scala

    /**
      * spark streaming实时处理kafka端的数据并持久化到MySQL
      *
      * @author huangxuan
      * @date 2021.03.19
      */
    object UserBehavior {
      def main(args: Array[String]): Unit = {
        Logger.getLogger("org.apache.spark").setLevel(Level.WARN)
        System.setProperty("spark.serializer","org.apache.spark.serializer.KryoSerializer")
        //sc
        val sc = new SparkConf().setAppName("To MySql").setMaster("local[5]")
        //ssc  每5秒一个批次
        val ssc = new StreamingContext(sc,Seconds(5))
    
        //从Kafka中读取数据
        val topics = "henry"  //topic name
        val numThreads = 3 //每个topic的分区数
        val topicMap = topics.split(" ").map((_,numThreads.toInt)).toMap
        val kafkaStream = KafkaUtils.createStream(
          ssc, // spark streaming 上下文对象
          "172.17.33.37:2181", //zookeeper 集群
          "test1",   //topic 所在组
          topicMap
        )
    
        //获取一个连接对象
        val conn = ConnectionPool.getConnection
        val stmt = conn.createStatement
    
        //spark streaming 消费数据
        val lines = kafkaStream.map(_._2).flatMap(_.split("\n"))
        lines.foreachRDD(line=>{
          //将kafka的数据以行为单位转换成字符串集合
          // (1,1,pv),(1,2,pv)
          val datas:Array[String] = line.collect()
          datas.foreach(x=>{
            val parms = x.split(",")
            val sql = "insert into user_behavior values("+parms(0)+","+parms(1)+",\'"+parms(2)+"\');"
            stmt.executeUpdate(sql)
            println(sql)
          })
        })
        ConnectionPool.returnConnection(conn)
    
        ssc.start
        //实时等待流
        ssc.awaitTermination
      }
    }
    

    jar包上传至服务器并执行spark streaming程序

    spark-submit --class "saprkStreaming.KafkaWordCounter" --master local[2] Spark_Study-1.0-SNAPSHOT.jar
    

    3.数据分析

    • 本次分析所使用的模型和体系

    电商分析通常从四个方面展开,即流程效率分析、流量/用户分析、商品分析、产品分析,通过流程效率拆解追踪问题产生环节,通过用户粘性、价值、满意度分析来进行用户分层及流失预警,通过商品生命周期及关联分析来划分商品等级,通过产品分析提升用户浏览-购买过程体验;

    本项目通过常用的电商数据分析指标,采用AARRR漏斗模型拆解用户进入APP后的每一步行为;并使用RFM模型,对用户价值进行评价,找到最有价值的用户群,针对这部分用户进行差异化营销。

    用户:
        年龄:不同年龄段的购物需求
        地区:不同地区的购物需求
        性别:不同性别的购物需求
        以及其他组合分析
    商品:
        类型:
        价格:
    

    4. 数据库设计

    • 采用MySQL 8.0.23 作为spark streaming的下游数据持久层
    1. 用户信息表:
    create table user_info(
       u_id int primary key COMMENT '用户ID',
       u_name varchar(50) COMMENT '用户姓名',
       u_sex varchar(10) COMMENT '用户性别',
       u_province varchar(50) COMMENT '用户所在省',
       u_city varchar(50) COMMENT '用户所在市',
       u_birthday date COMMENT '用户出生日期'
    )character set = utf8;
    
    insert into user_info values(1,'张三','男','北京','北京','1999-12-26');
    insert into user_info values(2,'李四','男','湖北','武汉','1979-04-21');
    insert into user_info values(3,'王五','男','河南','郑州','1984-10-16');
    insert into user_info values(4,'李大壮','男','山东','青岛','2002-09-09');
    insert into user_info values(5,'肖站','男','江西','南昌','1968-11-06');
    insert into user_info values(6,'王伊勃','男','新疆','乌鲁木齐','1996-07-09');
    insert into user_info values(7,'王冰冰','女','辽宁','长春','1990-09-28');
    insert into user_info values(8,'李冰冰','女','黑龙江','哈尔滨','1983-04-11');
    insert into user_info values(9,'范冰冰','女','陕西','西安','1977-12-20');
    insert into user_info values(10,'安吉拉','女','上海','上海','2002-03-23');
    insert into user_info values(11,'罗玉凤','女','海南','海口','1965-03-08');
    insert into user_info values(12,'肖龙女','女','四川','成都','1992-05-06');
    insert into user_info values(13,'洛雪梅','女','云南','昆明','1983-01-06');
    insert into user_info values(14,'马冬梅','女','湖南','长沙','1974-11-06');
    insert into user_info values(15,'苏妲己','女','贵州','贵阳','1974-11-06');
    insert into user_info values(16,'王建国','男','重庆','重庆','1999-11-06');
    insert into user_info values(17,'李旦','男','内蒙古','呼和浩特','1968-11-06');
    insert into user_info values(18,'张晓飞','男','吉林','长春','1968-11-06');
    insert into user_info values(19,'古力娜扎','女','福建','福州','1994-01-06');
    insert into user_info values(20,'允允朴','男','浙江','杭州','2006-11-06');
    
    
    1. 商品信息表:
    create table goods_info(
       g_id int primary key COMMENT '商品ID',
       g_name varchar(50) COMMENT '商品名称',
       g_type int COMMENT '商品类型编号',
       g_price float COMMENT '商品价格'
    )character set = utf8;
    
    insert into goods_info values(1,'安踏运动鞋',1,198);
    insert into goods_info values(2,'李宁板鞋',1,214.99);
    insert into goods_info values(3,'李宁韦德之道9篮球鞋',1,1499);
    insert into goods_info values(4,'Jordan印花套头连帽衫 黑色',1,189);
    insert into goods_info values(5,'遮阳帽',1,49);
    insert into goods_info values(6,'牛仔裤',1,324);
    insert into goods_info values(7,'休闲衬衫',1,88.88);
    insert into goods_info values(8,'皮鞋',1,499);
    insert into goods_info values(9,'T恤',1,79);
    insert into goods_info values(10,'潮流工装裤',1,209);
    insert into goods_info values(11,'AD钙奶',2,45);
    insert into goods_info values(12,'手撕面包',2,36);
    insert into goods_info values(13,'卫龙辣条',2,8);
    insert into goods_info values(14,'螺蛳粉',2,66.66);
    insert into goods_info values(15,'可乐',2,6);
    insert into goods_info values(16,'蛋黄酥',2,28);
    insert into goods_info values(17,'自热火锅',2,60);
    insert into goods_info values(18,'大益普洱茶',2,999);
    insert into goods_info values(19,'飞天茅台酱香型',2,1499);
    insert into goods_info values(20,'零食大礼包',2,120);
    insert into goods_info values(21,'华为Mate40 Pro',3,6499);
    insert into goods_info values(22,'小米11',3,3999);
    insert into goods_info values(23,'自拍杆',3,30);
    insert into goods_info values(24,'数据线',3,25);
    insert into goods_info values(25,'充电宝',3,120);
    insert into goods_info values(26,'平板电脑',3,4299);
    insert into goods_info values(27,'无人机',3,4999);
    insert into goods_info values(28,'游戏机',3,2549);
    insert into goods_info values(29,'笔记本电脑',3,9999);
    insert into goods_info values(30,'数码相机',3,43800);
    insert into goods_info values(31,'小米电视机',4,1499);
    insert into goods_info values(32,'美的洗衣机',4,729);
    insert into goods_info values(33,'电吹风',4,59);
    insert into goods_info values(34,'电饭煲',4,159);
    insert into goods_info values(35,'热水器',4,569);
    insert into goods_info values(36,'空调',4,2399);
    insert into goods_info values(37,'微波炉',4,489);
    insert into goods_info values(38,'净水器',4,259);
    insert into goods_info values(39,'咖啡机',4,4690);
    insert into goods_info values(40,'电扇',4,42);
    insert into goods_info values(41,'纸尿裤',5,99);
    insert into goods_info values(42,'奶瓶',5,39);
    insert into goods_info values(43,'益智玩具',5,26);
    insert into goods_info values(44,'毛绒抱枕',5,35);
    insert into goods_info values(45,'涂色绘画',5,31.5);
    insert into goods_info values(46,'手办',5,199);
    insert into goods_info values(47,'儿童肚兜',5,19.9);
    insert into goods_info values(48,'儿童牙刷',5,14.9);
    insert into goods_info values(49,'儿童餐椅',5,119);
    insert into goods_info values(50,'妈咪包',5,60);
    insert into goods_info values(51,'行李包',6,44.5);
    insert into goods_info values(52,'女生斜挎包',6,139);
    insert into goods_info values(53,'双肩包',6,69.6);
    insert into goods_info values(54,'链条包',6,469);
    insert into goods_info values(55,'旅行箱',6,334);
    insert into goods_info values(56,'帆布包',6,62);
    insert into goods_info values(57,'单肩包',6,199);
    insert into goods_info values(58,'男士胸包',6,62);
    insert into goods_info values(59,'男士真皮包',6,439);
    insert into goods_info values(60,'卡包',6,54);
    insert into goods_info values(61,'口红',7,319);
    insert into goods_info values(62,'面膜',7,99);
    insert into goods_info values(63,'雅思兰黛粉底',7,410);
    insert into goods_info values(64,'OLAY抗老精华',7,229);
    insert into goods_info values(65,'大宝眼霜',7,99.9);
    insert into goods_info values(66,'安耐晒',7,79);
    insert into goods_info values(67,'清扬男士洗发水',7,69.9);
    insert into goods_info values(68,'舒肤佳沐浴露',7,34.9);
    insert into goods_info values(69,'发胶',7,69);
    insert into goods_info values(70,'香皂',7,10);
    insert into goods_info values(71,'六味地黄丸',8,30);
    insert into goods_info values(72,'皮炎宁',8,44);
    insert into goods_info values(73,'999感冒灵',8,99);
    insert into goods_info values(74,'九芝堂阿胶补血颗粒',8,436);
    insert into goods_info values(75,'维C含片',8,34);
    insert into goods_info values(76,'珍视明滴眼液',8,42);
    insert into goods_info values(77,'汤臣倍健复合维A',8,144);
    insert into goods_info values(78,'云南白药创可贴',8,21);
    insert into goods_info values(79,'万通筋骨贴',8,29);
    insert into goods_info values(80,'安眠药',8,169);
    insert into goods_info values(81,'鞋架',9,9.8);
    insert into goods_info values(82,'衣架',9,46);
    insert into goods_info values(83,'折叠床',9,129);
    insert into goods_info values(84,'真皮沙发',9,16999);
    insert into goods_info values(85,'浴缸',9,420);
    insert into goods_info values(86,'台灯',9,66);
    insert into goods_info values(87,'椅子',9,44);
    insert into goods_info values(88,'桌子',9,130);
    insert into goods_info values(89,'傲风电竞椅',9,444);
    insert into goods_info values(90,'床垫',9,239);
    insert into goods_info values(91,'平衡车',10,1629);
    insert into goods_info values(92,'路亚套杆',10,429);
    insert into goods_info values(93,'跑步机',10,599);
    insert into goods_info values(94,'哑铃套件',10,236);
    insert into goods_info values(95,'健腹轮',10,29);
    insert into goods_info values(96,'呼啦圈',10,76);
    insert into goods_info values(97,'轮滑鞋',10,232);
    insert into goods_info values(98,'篮球',10,199);
    insert into goods_info values(99,'羽毛球拍',10,142);
    insert into goods_info values(100,'网球拍',10,64);
    
    
    1. 商品类目表:
    create table goods_type(
       t_id int primary key COMMENT '商品类型ID',
       t_name varchar(50) COMMENT '商品类型名称'
    )character set = utf8;
    
    insert into goods_type values(1,'服饰鞋帽');
    insert into goods_type values(2,'食品饮料');
    insert into goods_type values(3,'数码3C');
    insert into goods_type values(4,'家用电器');
    insert into goods_type values(5,'母婴');
    insert into goods_type values(6,'箱包');
    insert into goods_type values(7,'个护美妆');
    insert into goods_type values(8,'医药');
    insert into goods_type values(9,'家具');
    insert into goods_type values(10,'体育器械');
    
    
    
    1. 行为类目表:
    create table behavior_type(
       b_id varchar(5) primary key COMMENT '行为类型ID',
       b_name varchar(50) COMMENT '行为类型名称'
    )character set = utf8;
    
    insert into behavior_type values('pv','点击');
    insert into behavior_type values('buy','购买');
    insert into behavior_type values('cart','加购物车');
    insert into behavior_type values('fav','收藏');
    
    1. 用户行为数据表:来源spark streaming
    create table user_behavior(
       user_id int COMMENT '用户ID',
       good_id int COMMENT '商品ID',
       behavior_type varchar(5) COMMENT '行为类型ID',
       ddate date COMMENT '行为时间'
    )character set = utf8;
    
    1. 系统用户表:
    create table sys_user(
       userName varchar(50) primary key COMMENT '用户名',
       userPassword varchar(50) COMMENT '密码',
       userEmail varchar(50) COMMENT '邮箱',
       userIdentity int COMMENT '用户身份,0-超级管理员,1-普通用户'
    )character set = utf8;
    
    insert into sys_user values('henry','henry','1332822653@qq.com',0);
    insert into sys_user values('tom','tom','9999999999@163.com',1);
    insert into sys_user values('jack','jack','helloworld@163.com',1);
    
    更多相关内容
  • 基于大数据的用户行为分析系统.pdf
  • 本文设计的移动互联网用户行为分析引擎通过云计算技术实现分布式并发的大规模计算能力,构建移动互联网端到端的大数据挖掘分析系统,实现对DPI和应用平台用户上网行为的偏好分析,提供个性化推荐服务,打通从数据...

    2基于云计算的系统总体设计方案
    2.1系统总体技术架构
    本文设计的移动互联网用户行为分析引擎通过云计算技术实现分布式并发的大规模计算能力,构建移动互联网端到端的大数据挖掘分析系统,实现对DPI和应用平台用户上网行为的偏好分析,提供个性化推荐服务,打通从数据采集、分析到服务提供、营销执行的全过程。
    系统通过FTP服务器获取数据,在接口层采用分布式计算与批量处理相结合的方式,将大数据存入Hbase数据库中,支持海量数据和非结构化数据的存储,数据入库之后利用Hive进行整合层和汇总层的ETL处理,再基于MapReduce计算框架设计大数据分析模型,最后通过Hive数据库将结果导入前端展现数据库。在数据处理层,利用Hbase , Hive的优势进行海量数据的存储和处理,考虑到前端展现要求的灵活性,采用关系型数据库MySQL作为前端展现。系统总体技术架构如图1所示。

    2.2系统总体拓扑和功能分布
    系统的总体拓扑如图2所示,系统由一台服务器作为Hadoop平台和Hbase的主节点服务器,其他服务器为Hadoop平台和Hbase、的从节点服务器,从节点服务器的数量可根据系统处理需求动态扩展。主节点服务器主要负责从节点服务器任务和流量的分配,并对从节点服务器的执行状态进行监控,多台从节点服务器在主节点服务器的控制下执行具体的任务。
    主节点服务器的软件功能架构如图3所示,各模块具体介绍如下。

    (1)任务管理与调度模块
    集中式的任务调度控制台,提供任务的创建、调整和删除等功能,通过业务类型选择、执行周期设置等,定义应用的处理逻辑;自动控制数据抽取、数据整理到数据建模、模型运行、结果输出等过程,根据任务设置的激活处理条件,自动加载任务运行,系统提供任务的暂停、恢复以及优先级管理功能。
    (2)大数据入库与预处理组件
    将DPI用户的上网行为、应用平台的用户行为和内容信息等大数据,及时导入用户行为分析引擎系统,作为数据分析和模型挖掘的数据源。
    (3)大数据用户行为分析模型组件
    基于汇聚到系统中的海量移动互联网用户行为数据,利用MapReduce计算框架构建用户行为分析模型资源池,快速分析用户的偏好、社会关系信息,且支持多类业务实现精准的内容推荐。
    从节点服务器的软件结构与主节点服务器基本相同,区别主要在于从节点服务器不需要部署任务管理和调度模块。

    3大数据入库组件设计
    移动互联网用户行为分析引擎的数据来源主要有两类:应用平台数据和DPI数据。两类数据源的特点不同:应用平台的数据主要集中在一个访问行为表上,每天一个文件,每个文件的大小为GB级;而DPI数据的特点是大量的小文件,每个文件大小在10MB以内,但文件来源频率快,一般2min就有好几个文件,一个省份累计1天的数据量可达1TB。针对上述不同的数据源特点,系统采用不同的技术方案,具体介绍如下。
    (1)应用平台数据入库
    应用平台采用每天批量入库一次的方式,文件大小为GB级。大文件的入库,适合Hadoop平台的使用场景,考虑到使用MapReduce分布式处理的Hbase、入库方式效率不高,系统对该方式进行了优化,采用MapReduce分布式处理结合批量入库的方式。
    由于Hadoop通常使用的TextInputFormat类,在map中读取到的是文件的一行记录。因此,系统使用NLineInputFormat类实现在MapReduce中的批量入库。通过使用NLineInputFormat类,每个分片有N行记录,通过参数的配置,每次可读取文件的N行记录,那么可以在map中直接执行批量入库的操作,效率相对较高。
    (2)DPI数据入库
    由于DPI的行为数据是大量来源频率很快的小文件.

    在Hadoop平台下处理小文件采取的措施通常如下。
    ·利用SequenceFile、将小文件打包上传,可从源头避免小文件产生,但无论是Hadoop shell还是MapReduce,都不能进行灵活读取。
    ·使用HAR将HDFS中的小文件打包归档(从HDFS),可减少既有HDFS中的小文件数量,但HAR文件读取性能差。
    ·Hadoop append可直接追加数据到相同文件中,但每个小文件的大小不同,同时考虑每天的DPI日志有峰值和低谷,对文件数量的控制和处理来说有一定的麻烦。
    ·Flume , FlumeNG , Scribe,可通过中间层汇聚数据的办法减少小文件数量,但FlumeNG和Scribe都不能很好地传输压缩文件。
    通过以上分析可以看到,上述4种方式均存在一定的缺点,因此针对DPI数据的特征,采用Hadoop平台的CombineFileInputFormat类方式,即通过继承CombineFile InputFormat,实现CreateRecordReader,同时设置数据分片的大小,通过这种方式实现DPI大数据的入库。

    4大数据用户行为分析模型组件设计
    大数据用户行为分析模型组件提供多个在Hadoop分布式平台上运行的分析模型,其功能结构及其与其他组件的关系如图4所示

    本组件主要由以下几个模块组成。
    ·模型参数调整:提供对模型算法中的变量设定、参数调整、样本空间规模设置等功能。
    ·模型评估:提供创建模型校验任务,将实际数据与模型计算结果进行比对.输出模型校验指标.进行模型校验和模型有效性评价。
    ·多业务数据关联分析模型:对用户的互联网行为和爱游戏业务平台的行为进行关联分析,判断DPI用户上网行为偏好与在应用平台上的行为偏好是否存在关联关系,采用关联算法找出其中存在的规则,并将规则固化到系统中,从而有助于交叉营销。
    ·个性化推荐模型:以协同过滤技术和内容推荐技术为主,采用混合推荐技术,综合考虑来自产品内容和用户两个维度的影响,按照综合相似度向用户推荐相应的信息,实现用户动态推荐算法
    ·文木挖掘模型:对文木内容(如网页)通过预处理去除噪声(如网页导航栏、页首、页尾、广告等小相关内容),提取出文木主体部分,根据文木(网页)分类标准构造标注语料库,通过分类训练算法进行模型训练和机器学习,建立文木(网页)人工智能分类模型。
    · DPI访问偏好模型:基于网页内容分类,通过用户访问网页分析,计算用户WeI)访问兴趣偏好
    ·DPI应用偏好模型:基于DPI采集数据,通过应用知识库识别应用,计算用户应用兴趣偏好
    ·应用平台用户偏好模型:依据用户在应用平台上的各种操作行为,找出用户对应用平台各种内容的偏好规律。
    ·社交关系挖掘模型:社交关系挖掘包括用户社交图谱和兴趣图谱的构建。社交图谱通过用户的位置轨迹进行挖掘分析,建立用户之间的好友等社交关系;兴趣图谱基于用户偏好模型,计算用户偏好的相似度,得到与用户兴趣最相近的邻居集合,建立用户之间的相同兴趣爱好关系。
    以上模型的建模过程中很多用到了MapReduce计算框架。在MapReduce计算框架中,每个MapReduce作业主要分为两个阶段:map阶段和reduce阶段,分别用map函数和reduce函数实现。map函数对一个

    展开全文
  • 机器学习,用户行为分析的实践与实际运用。通过机器学习算法建立行为基线
  • 电信用户分析

    千次阅读 2020-06-05 22:49:38
    分类变量分布 影响国内电话费用的因素 手机型号矩阵分析 套餐矩阵分析

    变量说明

    Customer_ID:用户编号
    Gender:性别
    Age:年龄
    L_O_S:在网时长
    Tariff:话费类型/话费方案
    Handset:手机品牌
    Peak_calls:高峰时期电话数
    Peak_mins:高峰时期电话时长
    OffPeak_calls:低谷时期电话数
    OffPeak_mins:低谷时期电话时长
    Weekend_calls:周末电话数
    Weekend_mins:周末电话时长
    International_mins:国际电话时长
    Nat_call_cost:国内电话费用
    month:月份

    背景与目标

    运营商能够将客户很好地进行分层是为客户推出差异化的服务的基础,好的用户分析也是提升用户体验的前提。本文通过分析电信客户的相关数据(客户信息与客户通话数据),以期(1)了解客户特征,(2)并通过Kmeans聚类分析对客户进行聚类。

    导入数据

    import pandas as pd
    # 导入数据
    # 用户电话情况
    custcall = pd.read_csv('C:\\Users\\lin\\Desktop\\custcall.csv',sep = ',')
    # 用户信息
    custinfo = pd.read_csv('C:\\Users\\lin\\Desktop\\custinfo.csv',sep = ',')
    

    查看数据

    print(custcall.shape)
    custcall.head()
    

    返回结果:
    在这里插入图片描述

    print(custinfo.shape)
    custinfo.head()
    

    返回结果:
    在这里插入图片描述

    1 数据清洗与整理

    # 求每个用户各指标的平均值
    custcall_avg = custcall.groupby(by = ['Customer_ID']).mean()
    
    # month 的均值为同一值,故剔除 ‘month’
    del custcall_avg['month']
    
    # 合并数据集
    cust = pd.merge(custinfo,custcall_avg,left_on = 'Customer_ID',right_index = True,how = 'inner')
    
    # 查看Customer_ID是否有重复值
    print(cust['Customer_ID'].duplicated().sum())
    
    # 将Customer_ID设为索引
    cust = cust.set_index(keys = ['Customer_ID'])
    cust.head()
    

    返回结果:
    在这里插入图片描述

    # 查看cust的形状并将其导出
    print(cust.shape)
    print(cust.columns.to_list())
    cust.to_excel('C:\\Users\\林\\Desktop\\cust.xlsx')
    

    2 可视化分析

    2.1 单变量——分类变量分布

    将cust导入到Tableau中,分别绘制手机品牌、性别以及套餐的分布情况
    在这里插入图片描述
    从上图可知:

    • 最受欢迎的5种手机品牌分别为:S50、BS110、S80、WC95和ASAD170;
    • 电信的用户群体中,男女比例较均衡,没有显著差异;
    • 从套餐角度看,CAT 200 套餐用户使用量最多,占全部样本的44%,其次为 CAT 100,占比为22%。

    2.2 单变量——连续变量分布

    # 查看连续变量的分布
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    for i in cust.columns:
        if i not in ['Gender','Tariff','Handset','Peak_mins_bin','Peak_calls_bin']:
            plt.figure()
            sns.distplot(cust[i],bins=10,hist_kws=dict(edgecolor='k'),kde=True)
            plt.show()
    

    返回结果:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    从各连续变量的分布中可以看出:

    • 电信用户中,老年人占比少且用户趋向于少龄化。这与现实情况相符,随着互联网与经济、科技的发展,个体接触电子产品的年龄越来越小;
    • 用户在网时长分布均匀,没有明显的趋势;
    • 其余连续变量如:高峰时期电话数、电话时长,低谷时期电话数、电话时长等都呈现偏态分布,且全部右偏,即存在少量的头部用户消费较高。

    2.3 双变量——套餐选择

    这一部分分别绘制了:
    (1)使用各套餐用户的平均年龄、平均高峰电话数通话时间长、平均低谷电话数及通话时长、平均国际通话时长以及平均国内话费数;
    (2)使用某套餐、某品牌手机的用户数;
    (3)使用某套餐的性别分布。
    在这里插入图片描述
    由上图可以得出这样的一些结论:

    • 使用各套餐的用户平均年龄相差无几,则很可能在每个套餐中,用户年龄的分布是类似的。换句话说:各年龄段用户对套餐的偏好是类似的。为验证这一点,在Tableau中对年龄进行分桶,计算各年龄段使用各套餐的用户数,并对其进行可视化,如下图所示:
      在这里插入图片描述
      从图中可以看到,无论是哪个年龄段,用户都更偏好套餐CAT 200,且在各套餐情况下,用户的年龄分布是类似的(与总样本中的年龄分布类似),这表明年龄不是套餐选择的影响因素。
    • 平均国际通话时间、平均高峰期电话数和平均国内电话费用在套餐CAT 200组别中最大,且平均国际通话时间、平均高峰期电话数和平均国内电话费用在套餐维度上的分布是相似的,即这三者之间很有可能正相关;
    • 性别对套餐选择的影响不显著;
    • 手机型号对套餐选择的影响不是特别清晰。

    2.4 双变量——影响国内电话费用的因素

    在2.3节的分析中,猜想国际通话时长、高峰期电话数以及国内电话费用之间可能正相关,为验证这一猜想,这一部分将高峰时期电话次数与国际电话时长分桶,计算这两个维度上的每一个区间的平均国内电话费用,并利用Tableau进行可视化,得到如下图结果(下图上半部分);在这一部分还绘制了手机品牌、套餐与电话费用之间的气泡图。

    #数据分桶的代码
    
    # 计算高峰时期电话数与平均国内电话费用,并将数据导出
    cust['Peak_calls_bin'] = pd.cut(cust['Peak_calls'],bins = 50)
    test = cust.groupby('Peak_calls_bin')['Nat_call_cost'].mean().reset_index()
    test.to_excel('C:\\Users\\lin\\Desktop\\Peak_calls_bin.xlsx')
    
    # 计算国际电话时长与平均国内电话费用,并将数据导出
    cust['International_mins_bin'] = pd.cut(cust['International_mins'],bins = 50)
    test1 = cust.groupby('International_mins_bin')['Nat_call_cost'].mean().reset_index()
    test1.to_excel('C:\\Users\\lin\\Desktop\\International_mins_bin.xlsx')
    

    在这里插入图片描述
    上图对数据的可视化可以得出以下结论:

    • 高峰时期电话数、国际通话时长与国内电话费用之间都存在很明显的正相关关系:随着高峰期电话数与国际电话时长的增加,国内电话费用也在增加;
    • 使用手机品牌为ASAD90 与ASAD170以及S50的用户国内电话费用超过了国内电话费用的均值,即手机品牌为ASAD90 与ASAD170以及S50的用户相较于其他品牌手机的用户为电信带来更多的收入;
    • 套餐为CAT 200 和CAT 100的用户国内电话费用超过了国内电话费用均值,即采用套餐CAT 200 和CAT 100的用户为电信带来了更多的收入;

    2.5 矩阵分析

    2.4节中关于手机品牌、套餐与国内电话费用之间的分析得到这样的结论:(1)手机品牌为ASAD90 与ASAD170以及S50的用户相较于其他品牌手机的用户为电信带来更多的收入;(2)采用套餐CAT200 和CAT100的用户为电信带来了更多的收入。为了判断这两个结论是否稳健,这一部分对手机品牌与套餐进行了矩阵分析。

    2.5.1 手机品牌矩阵分析

    在这里插入图片描述
    关于手机品牌的矩阵分析可知:

    • 手机品牌为ASAD90 与ASAD170的用户,始终处于第一象限。这表明无论是在低谷期还是高峰期,亦或是周末,手机品牌为ASAD90 与ASAD170的用户的电话数与通话时长都超过了平均值;且手机品牌为ASAD90 与ASAD 170的用户的国际通话时长与国内电话费用也都高于平均值;
    • 手机品牌为S50的用户在低谷时期、周末通话数与通话时长都低于均值,而在高峰期是通话数与通话时长高于均值,且手机品牌为S50 的用户的国内电话费用与国际通话时长都高于均值。这表明手机品牌为S50的用户属于相对活跃的用户(在低谷期与周末不活跃);
    • 从手机品牌矩阵分析中还发现:手机品牌为CAS60和BS210的用户在低谷时期和周末较为活跃,但是这部分用户的国内电话费用却低于平均值;
    • 结合手机品牌为S50在高峰时期较为活跃,且其国内电话费用高于均值,而CAS60和BS210在低谷期与周末较为活跃,且其国内电话费用低于均值这一事实,可以剔除这样的猜想:对于电信而言,在高峰期活跃的用户为高价值用户,而在低谷期与周末活跃的用户为低价值用户。换句话讲:高峰期电话数与电话时长与电话费用正相关(2.4中已用可视化证明),低谷期与周末的电话数与电话时长不会给电话费用带来很大影响。为证明这一点,用与2.4类似方法处理数据,并对数据进行可视化,得到下图:
    # 计算低谷时期电话数与平均国内电话费用,并将数据导出
    cust['OffPeak_calls_bin'] = pd.cut(cust['OffPeak_calls'],bins = 50)
    test3 = cust.groupby('OffPeak_calls_bin')['Nat_call_cost'].mean().reset_index()
    test3.to_excel('C:\\Users\\lin\\Desktop\\OffPeak_calls_bin.xlsx')
    
    # 计算周末电话数与平均国内电话费用,并将数据导出
    cust['Weekend_calls_bin'] = pd.cut(cust['Weekend_calls'],bins = 50)
    test4 = cust.groupby('Weekend_calls_bin')['Nat_call_cost'].mean().reset_index()
    test4.to_excel('C:\\Users\\lin\\Desktop\\Weekend_calls_bin.xlsx')
    

    在这里插入图片描述
    由上图可知,用户低谷期与周末的通话数、通话时长与电话费用之间没有明确的正相关关系;

    • 手机品牌矩阵分析还可得到这样的结论:用户高峰时期电话数与高峰时期电话时长、低谷时期电话数与低谷时期电话时长以及周末电话数与周末电话时长正相关(趋势线过原点且与X轴夹角约45°)
    2.5.2 套餐矩阵分析

    在这里插入图片描述
    通过套餐矩阵分析可知:

    • 在先择CAT 200套餐的用户低谷期、周末、以及高峰期都很活跃,且其电话费用与国际通话时长都超过了平均值,则表明选择套餐CAT 200的用户可能为电信的高价值用户;
    • 而选择Play 100与Play 300的用户在低谷期与周末较为活跃,在高峰期不活跃,且这一部分用户的国内电话费用都低于均值,表明这部分用户为低价值用户。
    2.5.3 按低谷(周末)和高峰两个维度对用户分层

    下图左半部分按高峰时期与低谷时期两个维度分类:高峰时期与低谷时期都活跃的用户(称为A类)、高峰时期活跃而低谷时期不活跃的用户(称为B类)、低谷时期活跃高峰时期不活跃的用户(称为C类)和两个时期都不活跃的用户(称为D类)。
    右半部分选择高峰时期与周末两个维度,与左半部分类似。
    计算每一种用户的平均电话费用,并用颜色的深浅表示平均电话费用的大小。
    在这里插入图片描述
    由上图可知:

    • 无论是从手机品牌维度还是套餐维度观察,第一象限的点颜色最深,即在高峰期和低谷期或者周末都活跃的用户电话费用最高;
    • 从手机品牌维度看,ASAD170和ASAD90是典型的A类用户,从套餐维度分析,CAT 200的用户为典型的A类用户;
    • B类用户(手机品牌、套餐)的电话费用排在第二;出乎意料的是D类用户(两个时期都不活跃)的平均电话费用高于C类用户的电话费用(造成这一结果的原因很有可能是因为在低谷活跃的用户会损害电信的收入(即电话费用),如果这种情况成立,那么A类用户的高电话费用就很可能是由于用户在高峰时期的活跃而产生的);
    • 从手机品牌维度看,BS210和CAS60是典型的C类用户,从套餐维度分析,Play 100和Play 300的用户为典型的C类用户;

    2.6 数据可视化分析结论

    • 运营状态:
      1、电信用户使用的手机品牌的top5为:S50、BS110、S80、WC95和ASAD170; 从套餐角度看,CAT 200和CAT 100 套餐用户使用量;
      2、用户中男女比例较平衡,且趋向于少龄化;
      3、用户在网时长分布均匀,没有明显的趋势;
      4、高峰时期电话数、电话时长,低谷时期电话数、电话时长等都呈现偏态分布,且全部右偏,即存在少量的头部用户消费较高。
    • 用户细分:
      在高峰期与低谷期都活跃的用户平均电话费用最高(也有可能只是由于用户在高峰时期活跃导致的),其次为在高峰期活跃而在低谷期不活跃的用户,第三为两个时期都不活跃的用户,最后为在低谷期活跃、高峰期不活跃的用户。

    3 聚类分析

    3.1 处理数据集

    #将类别变量转为虚拟变量,gender为二值型,get_dummies处理后还是一列
    dummies=pd.get_dummies(cust[["Gender",'Tariff','Handset']])   
    
    # 合并数据集,将虚拟变量加入到数据集中
    train = pd.merge(cust,dummies,left_index = True,right_index = True,indicator = True)
    
    # 删除不需要的变量
    for i in ['Gender_x','Tariff','Handset']:
        del train[i]
        
    train.head()
    

    返回结果:
    在这里插入图片描述

    # 查看数据集的列
    # 查看数据集的列
    del train['_merge']
    train.columns.to_list()
    

    返回结果:
    在这里插入图片描述

    3.2 聚类

    # 导入所需库
    from sklearn.cluster import KMeans
    from sklearn.preprocessing import Normalizer
    
    # 数据预处理
    norm = Normalizer()
    norm.fit(train)
    norm_train = norm.transform(train)
    
    # 聚类
    norm_cluser = KMeans(n_clusters = 4)
    norm_cluser.fit(norm_train)
    
    # 为用户数据集cust加一列用户标签,标签为聚类模型的分类结果
    cust['class'] = norm_cluser.predict(norm_train)
    
    # 查看用户分类分布
    cust['class'].value_counts()
    

    返回结果:
    在这里插入图片描述

    3.3 绘图——判断聚类效果

    # 降低纬度
    from sklearn import manifold
    tsne  = manifold.TSNE()
    tsne_data = tsne.fit_transform(norm_train)
    
    # 将降维后的数据与用户标签合并为一个数据集
    tsne_df = pd.DataFrame(tsne_data,columns=['col1','col2'])
    tsne_df.loc[:,"class"] = norm_cluser.predict(norm_train)
    
    # 对降维后的数据集绘图,观察类与类之间是否分明
    import seaborn as sns
    import matplotlib.pyplot as plt
    plt.figure(figsize = (10,8),dpi = 80)
    sns.scatterplot(x = 'col1',y = 'col2',hue = 'class',data = tsne_df)
    plt.show()
    

    返回结果:
    在这里插入图片描述
    上图显示聚类结果比较好,类与类之间界限比较明晰。

    3.4 聚类效果的可视化判断

    将聚类后的用户数据导入到Tableau中进行可视化:

    cust.to_excel('C:\\Users\\lin\\Desktop\\cust_new.xlsx')
    

    在这里插入图片描述
    由上图可发现:

    • 通过各类别用户通话情况分析可知:高峰电话数与电话费用正相关,且观察图示可知类别2与2.5.3章节中描述的类别D特征相似,类别1与2.5.3章节中描述的类别C特征相似。观察下图发现类别2的用户基本全部分布在第三象限,类别1基本分布在第四象,这说明聚类模型返回的类别1跟类别2能够较好地地回溯2.5.3章节中对类别C、D的描述;
    • 观察聚类模型返回的类别0和类别3,发现与前文描述的类别A、B之间有些许差距,这是由于可视化分析中不能将全部的特征纳入到考虑范围内而造成的;
    • 总体而言,聚类模型能够较好地将用户进行聚类。
      在这里插入图片描述
      故此时成功地将电信的用户分为4类,在此基础上能够为每一类用户提供差异化的服务,提升用户体验进而提升企业ARPU值。
    展开全文
  • 为了更好地理解电信用户行为规律,以大规模电信网用户通信详细记录(CDR,call detail record)数据为研究对象,运用混合概率模型与特征工程方法,从用户群体与个体的角度分析了用户呼叫中的通话时长、通话频次、...
  • 即字段名称(2)对字段进行预处理(3)导入数据库3 Hive数据分析3.1 操作Hive3.2 简单查询分析3.3 查询条数统计分析3.4 关键字条件查询分析3.4.1 以关键字的存在区间为条件的查询3.4.2 关键字赋予给定值为

    1 案例简介

    大数据课程实验案例:网站用户行为分析,由厦门大学数据库实验室团队开发,旨在满足全国高校大数据教学对实验案例的迫切需求。本案例涉及数据预处理、存储、查询和可视化分析等数据处理全流程所涉及的各种典型操作,涵盖Linux、MySQL、Hadoop、HBase、Hive、Sqoop、R、Eclipse等系统和软件的安装和使用方法。案例适合高校(高职)大数据教学,可以作为学生学习大数据课程后的综合实践案例。通过本案例,将有助于学生综合运用大数据课程知识以及各种工具软件,实现数据全流程操作。各个高校可以根据自己教学实际需求,对本案例进行补充完善。

    1.1 案例目的

    熟悉Linux系统、MySQL、Hadoop、HBase、Hive、Sqoop、R、Eclipse等系统和软件的安装和使用;
    了解大数据处理的基本流程;
    熟悉数据预处理方法;
    熟悉在不同类型数据库之间进行数据相互导入导出;
    熟悉使用R语言进行可视化分析;
    熟悉使用Elipse编写Java程序操作HBase数据库。

    1.2 适用对象

    高校(高职)教师、学生
    大数据学习者

    1.3 时间安排

    本案例可以作为大数据入门级课程结束后的“大作业”,或者可以作为学生暑期或寒假大数据实习实践基础案例,完成本案例预计耗时7天。

    1.4 预备知识

    需要案例使用者,已经学习过大数据相关课程(比如入门级课程《大数据技术原理与应用》),了解大数据相关技术的基本概念与原理,了解Windows操作系统、Linux操作系统、大数据处理架构Hadoop的关键技术及其基本原理、列族数据库HBase概念及其原理、数据仓库概念与原理、关系型数据库概念与原理、R语言概念与应用。
    不过,由于本案例提供了全部操作细节,包括每个命令和运行结果,所以,即使没有相关背景知识,也可以按照操作说明顺利完成全部实验。

    1.5 硬件要求

    本案例在集群环境下完成。

    1.6 软件工具

    本案例所涉及的系统及软件
    Linux系统(Ubuntu16.04或14.04或18.04)
    MySQL(版本无要求)
    Hadoop(3.0以上版本)
    HBase(1.1.2或1.1.5,HBase版本需要和Hadoop版本兼容)
    Hive(1.2.1,Hive需要和Hadoop版本兼容,不要安装Hive3.0以上版本)
    R(版本无要求)
    Eclipse(版本无要求)
    不需要Sqoop,因为Sqoop无法支持Hadoop3.0以上版本

    1.7 数据集

    网站用户购物行为数据集2000万条记录。

    1.8 案例任务

    安装Linux操作系统
    安装关系型数据库MySQL
    安装大数据处理框架Hadoop
    安装列族数据库HBase
    安装数据仓库Hive
    安装Sqoop
    安装R
    安装Eclipse
    对文本文件形式的原始数据集进行预处理
    把文本文件的数据集导入到数据仓库Hive中
    对数据仓库Hive中的数据进行查询分析
    使用Java API将数据从Hive导入MySQL
    使用Java API将数据从MySQL导入HBase
    使用HBase Java API把数据从本地导入到HBase中
    使用R对MySQL中的数据进行可视化分析

    1.9 实验步骤

    步骤零:实验环境准备
    步骤一:本地数据集上传到数据仓库Hive
    步骤二:Hive数据分析
    步骤三:Hive、MySQL、HBase数据互导
    步骤四:利用R进行数据可视化分析

    2 本地数据上传到数据仓库Hive

    本节介绍数据集的下载、数据集的预处理和导入数据库。

    2.1 实验数据集的下载

    本案例采用的数据集为user.zip,包含了一个大规模数据集raw_user.csv(包含2000万条记录),和一个小数据集small_user.csv(只包含30万条记录)。小数据集small_user.csv是从大规模数据集raw_user.csv中抽取的一小部分数据。之所以抽取出一少部分记录单独构成一个小数据集,是因为,在第一遍跑通整个实验流程时,会遇到各种错误,各种问题,先用小数据集测试,可以大量节约程序运行时间。等到第一次完整实验流程都顺利跑通以后,就可以最后用大规模数据集进行最后的测试。

    在个人电脑中打开百度云网盘页面进行数据集的下载:https://pan.baidu.com/s/1nuOSo7B 。在个人电脑终端使用scp将个人电脑中的数据集上传到服务器/home/hadoop/Download路径。

    下面需要把user.zip进行解压缩,我们需要首先建立一个用于运行本案例的目录bigdatacase,请执行以下命令:

    sudo mkdir bigdatacase
    //这里会提示你输入当前用户(本教程是hadoop用户名)的密码
    //下面给hadoop用户赋予针对bigdatacase目录的各种操作权限
    sudo chown -R hadoop:hadoop ./bigdatacase
    cd bigdatacase
    //下面创建一个dataset目录,用于保存数据集
    mkdir dataset
    

    //下面就可以解压缩user.zip文件
    cd ~/Download
    unzip user.zip -d /usr/local/bigdatacase/dataset
    cd /usr/local/bigdatacase/dataset
    ls
    


    现在你就可以看到在dataset目录下有两个文件:raw_user.csv和small_user.csv。

    我们执行下面命令取出前面5条记录看一下:

    可以看出,每行记录都包含5个字段,数据集中的字段及其含义如下:

    user_id(用户id)
    item_id(商品id)
    behaviour_type(包括浏览、收藏、加购物车、购买,对应取值分别是1、2、3、4)
    user_geohash(用户地理位置哈希值,有些记录中没有这个字段值,所以后面我们会用脚本做数据预处理时把这个字段全部删除)
    item_category(商品分类)
    time(该记录产生时间)
    

    2.2 数据集的预处理

    (1)删除文件第一行记录,即字段名称

    raw_user和small_user中的第一行都是字段名称,我们在文件中的数据导入到数据仓库Hive中时,不需要第一行字段名称,因此,这里在做数据预处理时,删除第一行。

    cd /usr/local/bigdatacase/dataset
    //下面删除raw_user中的第1行
    sed -i '1d' raw_user.csv //1d表示删除第1行,同理,3d表示删除第3行,nd表示删除第n行
    //下面删除small_user中的第1行
    sed -i '1d' small_user.csv
    //下面再用head命令去查看文件的前5行记录,就看不到字段名称这一行了
    head -5 raw_user.csv
    head -5 small_user.csv
    

    (2)对字段进行预处理

    下面对数据集进行一些预处理,包括为每行记录增加一个id字段(让记录具有唯一性)、增加一个省份字段(用来后续进行可视化分析),并且丢弃user_geohash字段(后面分析不需要这个字段)。
    下面我们要建一个脚本文件pre_deal.sh,请把这个脚本文件放在dataset目录下,和数据集small_user.csv放在同一个目录下:

    cd /usr/local/bigdatacase/dataset
    vim pre_deal.sh
    

    上面使用vim编辑器新建了一个pre_deal.sh脚本文件,请在这个脚本文件中加入下面代码:

    #!/bin/bash
    #下面设置输入文件,把用户执行pre_deal.sh命令时提供的第一个参数作为输入文件名称
    infile=$1
    #下面设置输出文件,把用户执行pre_deal.sh命令时提供的第二个参数作为输出文件名称
    outfile=$2
    #注意!!最后的$infile > $outfile必须跟在}’这两个字符的后面
    awk -F "," 'BEGIN{
            srand();
            id=0;
            Province[0]="山东";Province[1]="山西";Province[2]="河南";Province[3]="河北";Province[4]="陕西";Province[5]="内蒙古";Province[6]="上海市";
            Province[7]="北京市";Province[8]="重庆市";Province[9]="天津市";Province[10]="福建";Province[11]="广东";Province[12]="广西";Province[13]="云南"; 
            Province[14]="浙江";Province[15]="贵州";Province[16]="新疆";Province[17]="西藏";Province[18]="江西";Province[19]="湖南";Province[20]="湖北";
            Province[21]="黑龙江";Province[22]="吉林";Province[23]="辽宁"; Province[24]="江苏";Province[25]="甘肃";Province[26]="青海";Province[27]="四川";
            Province[28]="安徽"; Province[29]="宁夏";Province[30]="海南";Province[31]="香港";Province[32]="澳门";Province[33]="台湾";
        }
        {
            id=id+1;
            value=int(rand()*34);       
            print id"\t"$1"\t"$2"\t"$3"\t"$5"\t"substr($6,1,10)"\t"Province[value]
        }' $infile > $outfile
    


    使用awk可以逐行读取输入文件,并对逐行进行相应操作。其中,-F参数用于指出每行记录的不同字段之间用什么字符进行分割,这里是用逗号进行分割。处理逻辑代码需要用两个英文单引号引起来。 $infile是输入文件的名称,我们这里会输入raw_user.csv,$outfile表示处理结束后输出的文件名称,我们后面会使用user_table.txt作为输出文件名称。

    在上面的pre_deal.sh代码的处理逻辑部分,srand()用于生成随机数的种子,id是我们为数据集新增的一个字段,它是一个自增类型,每条记录增加1,这样可以保证每条记录具有唯一性。我们会为数据集新增一个省份字段,用来进行后面的数据可视化分析,为了给每条记录增加一个省份字段的值,这里,我们首先用Province[]数组用来保存全国各个省份信息,然后,在遍历数据集raw_user.csv的时候,每当遍历到其中一条记录,使用value=int(rand()*34)语句随机生成一个0-33的整数,作为Province省份值,然后从Province[]数组当中获取省份名称,增加到该条记录中。

    substr($6,1,10)这个语句是为了截取时间字段time的年月日,方便后续存储为date格式。awk每次遍历到一条记录时,每条记录包含了6个字段,其中,第6个字段是时间字段,substr($6,1,10)语句就表示获取第6个字段的值,截取前10个字符,第6个字段是类似”2014-12-08 18″这样的字符串(也就是表示2014年12月8日18时),substr($6,1,10)截取后,就丢弃了小时,只保留了年月日。
    另外,在

    print id”\t”\$1\t”\$2\t”\$3\t”\$5\t”substr(\$6,1,10)\t”Province[value]
    

    这行语句中,我们丢弃了每行记录的第4个字段,所以,没有出现$4。我们生成后的文件是“\t”进行分割,这样,后续我们去查看数据的时候,效果让人看上去更舒服,每个字段在排版的时候会对齐显示,如果用逗号分隔,显示效果就比较乱。

    最后,保存pre_deal.sh代码文件,退出vim编辑器。
    下面就可以执行pre_deal.sh脚本文件,来对raw_user.csv进行数据预处理,命令如下:

    cd /usr/local/bigdatacase/dataset
    bash ./pre_deal.sh small_user.csv user_table.txt  
    

    可以使用head命令查看生成的user_table.txt,不要直接打开,文件过大,会出错,下面查看前10行数据:

    (3)导入数据库

    下面要把user_table.txt中的数据最终导入到数据仓库Hive中。为了完成这个操作,我们会首先把user_table.txt上传到分布式文件系统HDFS中,然后,在Hive中创建一个外部表,完成数据的导入。

    • a.启动HDFS
      HDFS是Hadoop的核心组件,因此,需要使用HDFS,必须安装Hadoop。这里假设你已经安装了Hadoop,安装目录是“/usr/local/hadoop”。
      下面,请登录Linux系统,打开一个终端,执行下面命令启动Hadoop:
    cd /usr/local/hadoop
    ./sbin/start-all.sh
    

    然后,执行jps命令看一下当前运行的进程:

    说明hadoop启动成功。

    • b.把user_table.txt上传到HDFS中
      现在,我们要把Linux本地文件系统中的user_table.txt上传到分布式文件系统HDFS中,存放在HDFS中的“/bigdatacase/dataset”目录下。
      首先,请执行下面命令,在HDFS的根目录下面创建一个新的目录bigdatacase,并在这个目录下创建一个子目录dataset,如下:
    cd /usr/local/hadoop
    ./bin/hdfs dfs -mkdir -p /bigdatacase/dataset
    

    然后,把Linux本地文件系统中的user_table.txt上传到分布式文件系统HDFS的“/bigdatacase/dataset”目录下,命令如下:

    cd /usr/local/hadoop
    ./bin/hdfs dfs -put /usr/local/bigdatacase/dataset/user_table.txt /bigdatacase/dataset
    

    下面可以查看一下HDFS中的user_table.txt的前10条记录,命令如下:

    cd /usr/local/hadoop
    ./bin/hdfs dfs -cat /bigdatacase/dataset/user_table.txt | head -10
    

    • c.在Hive上创建数据库
      这里假设你已经完成了Hive的安装,并且使用MySQL数据库保存Hive的元数据。本教程安装的是Hive2.1.0版本,安装目录是“/usr/local/hive”。
      下面,请在Linux系统中,再新建一个终端。因为需要借助于MySQL保存Hive的元数据,所以,请首先启动MySQL数据库:
    sudo service mysql start  //可以在Linux的任何目录下执行该命令
    

    由于Hive是基于Hadoop的数据仓库,使用HiveQL语言撰写的查询语句,最终都会被Hive自动解析成MapReduce任务由Hadoop去具体执行,因此,需要启动Hadoop,然后再启动Hive。由于前面我们已经启动了Hadoop,所以,这里不需要再次启动Hadoop。下面,在这个新的终端中执行下面命令进入Hive:

    cd /usr/local/hive
    ./bin/hive   //启动Hive
    


    下面,我们要在Hive中创建一个数据库dblab,命令如下:

    hive>  create database dblab;
    hive>  use dblab;
    
    • d.创建外部表
      这里我们要在数据库dblab中创建一个外部表bigdata_user,它包含字段(id, uid, item_id, behavior_type, item_category, date, province),请在hive命令提示符下输入如下命令:
    hive>  CREATE EXTERNAL TABLE dblab.bigdata_user(id INT,uid STRING,item_id STRING,behavior_type INT,item_category STRING,visit_date DATE,province STRING) COMMENT 'Welcome to xmu dblab!' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE LOCATION '/bigdatacase/dataset';
    
    • e.查询数据
      上面已经成功把HDFS中的“/bigdatacase/dataset”目录下的数据加载到了数据仓库Hive中,我们现在可以使用下面命令查询一下:
    hive>  select * from bigdata_user limit 10;
    hive>  select behavior_type from bigdata_user limit 10;
    

    3 Hive数据分析

    3.1 操作Hive

    在“hive>”命令提示符状态下执行下面命令:

    hive> use dblab; //使用dblab数据库
    hive> show tables; //显示数据库中所有表。
    hive> show create table bigdata_user; //查看bigdata_user表的各种属性;
    

    执行结果如下:


    可以执行下面命令查看表的简单结构:

    hive> desc bigdata_user;
    

    3.2 简单查询分析

    先测试一下简单的指令:

    hive> select behavior_type from bigdata_user limit 10;//查看前10位用户对商品的行为
    


    如果要查出每位用户购买商品时的多种信息,输出语句格式为 select 列1,列2,….,列n from 表名;
    比如我们现在查询前20位用户购买商品时的时间和商品的种类

    hive> select visit_date,item_category from bigdata_user limit 20;
    


    有时我们在表中查询可以利用嵌套语句,如果列名太复杂可以设置该列的别名,以简化我们操作的难度,以下我们可以举个例子:

    hive> select e.bh, e.it  from (select behavior_type as bh, item_category as it from bigdata_user) as e  limit 20;
    


    这里简单的做个讲解,behavior_type as bh ,item_category as it就是把behavior_type 设置别名 bh ,item_category 设置别名 it,FROM的括号里的内容我们也设置了别名e,这样调用时用e.bh,e.it,可以简化代码。

    3.3 查询条数统计分析

    经过简单的查询后我们同样也可以在select后加入更多的条件对表进行查询,下面可以用函数来查找我们想要的内容。
    (1)用聚合函数count()计算出表内有多少条行数据

    hive> select count(*) from bigdata_user;//用聚合函数count()计算出表内有多少条行数据 
    


    (2)在函数内部加上distinct,查出uid不重复的数据有多少条
    下面继续执行操作:

    hive> select count(distinct uid) from bigdata_user;//在函数内部加上distinct,查出uid不重复的数据有多少条
    


    (3)查询不重复的数据有多少条(为了排除客户刷单情况)

    hive>select count(*) from (select uid,item_id,behavior_type,item_category,visit_date,province from bigdata_user group by uid,item_id,behavior_type,item_category,visit_date,province having count(*)=1)a;
    

    3.4 关键字条件查询分析

    3.4.1 以关键字的存在区间为条件的查询

    使用where可以缩小查询分析的范围和精确度,下面用实例来测试一下。
    (1)查询2014年12月10日到2014年12月13日有多少人浏览了商品

    hive>select count(*) from bigdata_user where behavior_type='1' and visit_date<'2014-12-13' and visit_date>'2014-12-10';
    


    (2)以月的第n天为统计单位,依次显示第n天网站卖出去的商品的个数

    hive> select count(distinct uid), day(visit_date) from bigdata_user where behavior_type='4' group by day(visit_date);
    

    3.4.2 关键字赋予给定值为条件,对其他数据进行分析

    取给定时间和给定地点,求当天发出到该地点的货物的数量

    hive> select count(*) from bigdata_user where province='江西' and visit_date='2014-12-12' and behavior_type='4';
    

    3.5 根据用户行为分析

    原始数据集过大,一下实验均使用small_dataset。

    3.5.1 查询一件商品在某天的购买比例或浏览比例

    hive> select count(*) from bigdata_user where visit_date='2014-12-11'and behavior_type='4';//查询有多少用户在2014-12-11购买了商品
    

    hive> select count(*) from bigdata_user where visit_date ='2014-12-11';//查询有多少用户在2014-12-11点击了该店
    


    根据上面语句得到购买数量和点击数量,两个数相除即可得出当天该商品的购买率。

    3.5.2 查询某个用户在某一天点击网站占该天所有点击行为的比例(点击行为包括浏览,加入购物车,收藏,购买)

    hive> select count(*) from bigdata_user where uid=10001082 and visit_date='2014-12-12';//查询用户10001082在2014-12-12点击网站的次数
    

    hive> select count(*) from bigdata_user where visit_date='2014-12-12';//查询所有用户在这一天点击该网站的次数
    


    上面两条语句的结果相除,就得到了要要求的比例。

    3.5.3 给定购买商品的数量范围,查询某一天在该网站的购买该数量商品的用户id

    hive> select uid from bigdata_user where behavior_type='4' and visit_date='2014-12-12' group by uid having count(behavior_type='4')>5;//查询某一天在该网站购买商品超过5次的用户id
    

    3.6 用户实时查询分析

    某个地区的用户当天浏览网站的次数

    hive> create table scan(province STRING,scan INT) COMMENT 'This is the search of bigdataday' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE;//创建新的数据表进行存储
    hive> insert overwrite table scan select province,count(behavior_type) from bigdata_user where behavior_type='1' group by province;//导入数据
    hive> select * from scan;//显示结果
    

    4 Hive、MySQL、HBase数据互导

    4.1 准备工作

    本教程需要安装Hive、MySQL、HBase。在前面的第一个步骤中,我们在安装Hive的时候就已经一起安装了MySQL(因为我们采用MySQL来存储Hive的元数据),所以,现在你只需要再安装HBase。
    Hive预操作
    如果你还没有启动Hive,请首先启动Hive。
    请登录Linux系统(本教程统一采用hadoop用户名登录系统),然后,打开一个终端。
    本教程中,Hadoop的安装目录是“/usr/local/hadoop”,Hive的安装目录是“/usr/local/hive”。
    因为需要借助于MySQL保存Hive的元数据,所以,请首先启动MySQL数据库,请在终端中输入下面命令:

    service mysql start  //可以在Linux的任何目录下执行该命令
    

    由于Hive是基于Hadoop的数据仓库,使用HiveQL语言撰写的查询语句,最终都会被Hive自动解析成MapReduce任务由Hadoop去具体执行,因此,需要启动Hadoop,然后再启动Hive。
    下面,继续执行下面命令启动进入Hive:

    cd /usr/local/hive
    ./bin/hive   //启动Hive
    

    然后,在“hive>”命令提示符状态下执行下面命令:
    1、创建临时表user_action

    hive> create table dblab.user_action(id STRING,uid STRING, item_id STRING, behavior_type STRING, item_category STRING, visit_date DATE, province STRING) COMMENT 'Welcome to XMU dblab! ' ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE;
    

    这个命令执行完以后,Hive会自动在HDFS文件系统中创建对应的数据文件。

    2、将bigdata_user表中的数据插入到user_action(执行时间:10秒左右)
    在第二个步骤——Hive数据分析中,我们已经在Hive中的dblab数据库中创建了一个外部表bigdata_user。下面把dblab.bigdata_user数据插入到dblab.user_action表中,命令如下:

    hive> INSERT OVERWRITE TABLE dblab.user_action select * from dblab.bigdata_user;
    

    请执行下面命令查询上面的插入命令是否成功执行:

    hive>select * from user_action limit 10;
    

    4.2 使用Java API将数据从Hive导入MySQL

    1、启动Hadoop集群、MySQL服务
    前面我们已经启动了Hadoop集群和MySQL服务。这里请确认已经按照前面操作启动成功。
    2、将前面生成的临时表数据从Hive导入到 MySQL 中,包含如下四个步骤。
    (1)登录 MySQL
    请在Linux系统中新建一个终端,执行下面命令:

    sudo mysql –u root –p 
    

    为了简化操作,本教程直接使用root用户登录MySQL数据库,但是,在实际应用中,建议在MySQL中再另外创建一个用户。
    执行上面命令以后,就进入了“mysql>”命令提示符状态。
    (2)创建数据库

    mysql> show databases; #显示所有数据库
    mysql> create database dblab; #创建dblab数据库
    mysql> use dblab; #使用数据库
    



    请使用下面命令查看数据库的编码:

    mysql>show variables like "char%";
    


    请确认当前编码为utf8,否则无法导入中文,请参考Ubuntu安装MySQL及常用操作修改编码http://dblab.xmu.edu.cn/blog/install-mysql/
    下面是笔者电脑上修改了编码格式后的结果:

    (3)创建表
    下面在MySQL的数据库dblab中创建一个新表user_action,并设置其编码为utf-8:

    mysql> CREATE TABLE `dblab`.`user_action` (`id` varchar(50),`uid` varchar(50),`item_id` varchar(50),`behavior_type` varchar(10),`item_category` varchar(50), `visit_date` DATE,`province` varchar(20)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    创建成功后,输入下面命令退出MySQL:

    mysql> exit
    

    (4)导入数据(执行时间:20秒左右)
    通过JDBC连接Hive和MySQL ,将数据从Hive导入MySQL。通过JDBC连接Hive,需要通过Hive的thrift服务实现跨语言访问Hive,实现thrift服务需要开启hiveserver2。
    在Hadoop的配置文件core-site.xml中添加以下配置信息:(目录为/usr/local/hadoop/etc/hadoop/core-site.xml)

    <property>
            <name>hadoop.proxyuser.hadoop.hosts</name>
            <value>*</value>
    </property>
    <property>
            <name>hadoop.proxyuser.hadoop.groups</name>
            <value>*</value>
    </property>
    

    开启hadoop以后,在目录/usr/local/hive下执行以下命令开启hiveserver2,并设置默认端口为10000。

    cd /usr/local/hive
    ./bin/hive --service hiveserver2 -hiveconf hive.server2.thrift.port=10000
    

    在出现了几个Hive Session ID=…之后,出现ok,Hive才会真正启动。
    启动成功后不要退出,新建一个服务器终端,使用如下命令查看10000号端口是否被占用。

    sudo netstat -anp|grep 10000
    

    如图所示,端口10000已被占用,即hiveserver2启动成功。

    在个人电脑使用IDEA新建一个maven project。在pom.xml添加以下依赖文件(可能会有多余的,但是无碍)。

      <dependencies>
            <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
            <dependency>
                <groupId>org.apache.hive</groupId>
                <artifactId>hive-exec</artifactId>
                <version>3.1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc -->
            <dependency>
                <groupId>org.apache.hive</groupId>
                <artifactId>hive-jdbc</artifactId>
                <version>3.1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-metastore -->
            <dependency>
                <groupId>org.apache.hive</groupId>
                <artifactId>hive-metastore</artifactId>
                <version>3.1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-common -->
            <dependency>
                <groupId>org.apache.hive</groupId>
                <artifactId>hive-common</artifactId>
                <version>3.1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-cli -->
            <dependency>
                <groupId>org.apache.hive</groupId>
                <artifactId>hive-cli</artifactId>
                <version>3.1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-contrib -->
            <dependency>
                <groupId>org.apache.hive</groupId>
                <artifactId>hive-contrib</artifactId>
                <version>3.1.2</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.26</version>
            </dependency>
        </dependencies>
    

    在main–>java下新建java文件,命名为HivetoMySQL。内容如下。

    import java.sql.*;
    import java.sql.SQLException;
    
    public class HivetoMySQL {
        private static String driverName = "org.apache.hive.jdbc.HiveDriver";
        private static String driverName_mysql = "com.mysql.jdbc.Driver";
        public static void main(String[] args) throws SQLException {
            try {
                Class.forName(driverName);
            }catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.exit(1);
            }
            Connection con1 = DriverManager.getConnection("jdbc:hive2://101.***.***.168:10000/default", "hive", "hive");//101.***.***.168为你自己的服务器ip地址,后两个参数是用户名密码
    
            if(con1 == null)
                System.out.println("连接失败");
            else {
                Statement stmt = con1.createStatement();
                String sql = "select * from dblab.user_action";
                System.out.println("Running: " + sql);
                ResultSet res = stmt.executeQuery(sql);
    
                //InsertToMysql
                try {
                    System.out.println("begin try");
                    Class.forName(driverName_mysql);
                    Connection con2 = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/dblab","root","********");//********为root密码
                    String sql2 = "insert into user_action(id,uid,item_id,behavior_type,item_category,visit_date,province) values (?,?,?,?,?,?,?)";
                    PreparedStatement ps = con2.prepareStatement(sql2);
                    while (res.next()) {
                        ps.setString(1,res.getString(1));
                        ps.setString(2,res.getString(2));
                        ps.setString(3,res.getString(3));
                        ps.setString(4,res.getString(4));
                        ps.setString(5,res.getString(5));
                        ps.setDate(6,res.getDate(6));
                        ps.setString(7,res.getString(7));
                        ps.executeUpdate();
                    }
                    ps.close();
                    con2.close();
                    res.close();
                    stmt.close();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
            con1.close();
        }
    }
    

    使用IDEA的ssh远程调试服务。

    上面程序执行完毕后,在MySQL中进行查询。

    select count(*) from user_action;
    

    4.3 查看MySQL中user_action表数据

    下面需要再次启动MySQL,进入“mysql>”命令提示符状态:

    mysql -u root -p
    

    然后执行下面命令查询user_action表中的数据:

    mysql> use dblab;
    mysql> select * from user_action limit 10;
    


    至此,数据从Hive导入MySQL的操作顺利完成。

    4.4 使用HBase Java API把数据从本地导入HBase中

    4.4.1 启动Hadoop集群、HBase服务

    确保启动了hadoop集群和HBase服务。如果没有启动就在Linux系统中打开一个终端。输入以下命令。

    cd /usr/local/hadoop
    ./sbin/start-all.sh
    cd /usr/local/hbase
    ./bin/start-hbase.sh
    

    4.4.2 数据准备

    实际上,也可以编写java程序,直接从HDFS中读取数据加载到HBase。但是,这里展示的是如何用Java程序把数据从本地导入HBase中。只要对程序做简单修改,就可以实现从HDFS中读取数据加载到HBase。
    将之前的user_action数据从HDFS复制到Linux系统的本地文件系统中,命令如下:

    cd /usr/local/bigdatacase/dataset
    /usr/local/hadoop/bin/hdfs dfs -get /user/hive/warehouse/dblab.db/user_action .
     #将HDFS上的user_action数据复制到本地当前目录,注意'.'表示当前目录
    cat ./user_action/* | head -10   #查看前10行数据
    cat ./user_action/00000* > user_action.output #将00000*文件复制一份重命名为user_action.output,*表示通配符
    head user_action.output  #查看user_action.output前10行
    


    4.4.3 编写数据导入程序

    这里采用IDEA编写Java程序实现HBase导入功能,具体代码如下:

    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.List; 
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.*;
    import org.apache.hadoop.hbase.client.*;
    import org.apache.hadoop.hbase.util.Bytes; 
    public class ImportHBase extends Thread {
        public Configuration config;
        public Connection conn;
        public Table table;
        public Admin admin;
        public ImportHBase() {
            config = HBaseConfiguration.create();
    //      config.set("hbase.master", "master:60000");
    //      config.set("hbase.zookeeper.quorum", "master");
            try {
                conn = ConnectionFactory.createConnection(config);
                admin = conn.getAdmin();
                table = conn.getTable(TableName.valueOf("user_action"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        } 
        public static void main(String[] args) throws Exception {
            if (args.length == 0) {       //第一个参数是该jar所使用的类,第二个参数是数据集所存放的路径
                throw new Exception("You must set input path!");
            }
            String fileName = args[args.length-1];  //输入的文件路径是最后一个参数
            ImportHBase test = new ImportHBase();
            test.importLocalFileToHBase(fileName);
        }
        public void importLocalFileToHBase(String fileName) {
            long st = System.currentTimeMillis();
            BufferedReader br = null;
            try {
                br = new BufferedReader(new InputStreamReader(new FileInputStream(
                        fileName)));
                String line = null;
                int count = 0;
                while ((line = br.readLine()) != null) {
                    count++;
                    put(line);
                    if (count % 10000 == 0)
                        System.out.println(count);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally { 
                if (br != null) {
                    try {
                        br.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                try {
                    table.close(); // must close the client
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            long en2 = System.currentTimeMillis();
            System.out.println("Total Time: " + (en2 - st) + " ms");
        }
        @SuppressWarnings("deprecation")
        public void put(String line) throws IOException {
            String[] arr = line.split("\t", -1);
            String[] column = {"id","uid","item_id","behavior_type","item_category","date","province"};
     
            if (arr.length == 7) {
                Put put = new Put(Bytes.toBytes(arr[0]));// rowkey
                for(int i=1;i<arr.length;i++){
                    put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes(column[i]),Bytes.toBytes(arr[i]));
                }
                table.put(put); // put to server
            }
        }
        public void get(String rowkey, String columnFamily, String column,
                int versions) throws IOException {
            long st = System.currentTimeMillis();
            Get get = new Get(Bytes.toBytes(rowkey));
            get.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(column));
            Scan scanner = new Scan(get);
            scanner.readVersions(versions);
            ResultScanner rsScanner = table.getScanner(scanner);
            for (Result result : rsScanner) {
                final List<Cell> list = result.listCells();
                for (final Cell kv : list) {
                    System.out.println(Bytes.toStringBinary(kv.getValueArray()) + "\t"
                            + kv.getTimestamp()); // mid + time
                }
            }
            rsScanner.close();
            long en2 = System.currentTimeMillis();
            System.out.println("Total Time: " + (en2 - st) + " ms");
        }
    }
    

    打包之后发送至服务器,存放在/usr/local/bigdatacase/hbase(如果没有需要新建)。

    4.4.4 数据导入

    在导入之前,先新建user_action表,新建HBase Shell窗口。

    hbase shell(在任意位置输入命令)
    

    启动成功后,就进入了“hbase>”命令提示符状态。
    创建表user_action

    hbase> create 'user_action', { NAME => 'f1', VERSIONS => 5}
    

    上面命令在HBase中创建了一个user_action表,这个表中有一个列族f1(你愿意把列族名称取为其他名称也可以,比如列族名称为userinfo),历史版本保留数量为5。

    下面就可以运行hadoop jar命令运行程序:

    /usr/local/hadoop/bin/hadoop jar /usr/local/bigdatacase/hbase/ImportHBase.jar HBaseImportTest /usr/local/bigdatacase/dataset/user_action.output
    

    这个命令大概会执行几分钟左右,执行过程中,屏幕上会打印出执行进度,每执行1万条,对打印出一行信息,所以,整个执行过程屏幕上显示如下信息:

    查看HBase中user_action表数据
    下面,再次切换到HBase Shell窗口,执行下面命令查询数据:

    habse> scan 'user_action',{LIMIT=>10}  #只查询前面10行
    

    就可以得到类似下面的查询结果了:

    5 利用R进行数据可视化分析

    5.1 安装R

    Ubuntu自带的APT包管理器中的R安装包总是落后于标准版,因此需要添加新的镜像源把APT包管理中的R安装包更新到最新版。
    请登录Linux系统,打开一个终端,然后执行下面命令(并注意保持网络连通,可以访问互联网,因为安装过程要下载各种安装文件):
    利用vim打开/etc/apt/sources.list文件

    sudo vim /etc/apt/sources.list
    

    在文件中添加阿里云的镜像源,把如下文件添加进去。其中xenial是Ubuntu16.04的代号。

    deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse  
    deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse
    deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
    

    退出vim,更新软件源列表

    sudo apt-get update
    

    安装R语言

    sudo apt-get install r-base
    

    会提示“您希望继续执行吗?[Y/n]”,可以直接键盘输入“Y”,就可以顺利安装结束。
    安装结束后,可以执行下面命令启动R:

    R
    


    “>”就是R的命令提示符,你可以在后面输入R语言命令。
    可以执行下面命令退出R:

    >q()
    

    安装依赖库
    为了完成可视化功能,我们需要为R安装一些依赖库,包括:RMySQL、ggplot2、devtools和recharts。
    RMySQL是一个提供了访问MySQL数据库的R语言接口程序的R语言依赖库。
    ggplot2和recharts则是R语言中提供绘图可视化功能的依赖库。
    请启动R进入R命令提示符状态,执行如下命令安装RMySQL:

    > install.packages('RMySQL')
    

    执行如下命令安装绘图包ggplot2:

    install.packages('ggplot2')
    

    安装devtools

    install.packages('devtools')
    

    笔者在Ubuntu16.04上执行devtools安装时,出现了错误,笔者根据每次错误的英文提示信息,安装了三个软件libssl-dev、libssh2-1-dev、libcurl4-openssl-dev,安装命令如下:

    sudo apt-get install libssl-dev
    sudo apt-get install libssh2-1-dev
    sudo apt-get install libcurl4-openssl-dev
    

    安装之后重新安装devtools。
    下面在R命令提示符下再执行如下命令安装taiyun/recharts:

    > devtools::install_github('taiyun/recharts')
    


    至此,工具安装已全部完成。

    5.2 可视化分析

    以下分析使用的函数方法,都可以使用如下命令查询函数的相关文档。例如:查询sort()函数如何使用

    ?sort
    

    这时,就会进入冒号“:”提示符状态(也就是帮助文档状态),在冒号后面输入q即可退出帮助文档状态,返回到R提示符状态!

    连接MySQL,并获取数据
    请在Linux系统中新建另外一个终端,然后执行下面命令启动MySQL数据库:

    sudo service mysql start
    

    下面,让我们查看一下MySQL数据库中的数据,请执行下面命令进入MySQL命令提示符状态:

    mysql -u root -p
    

    会提示你输入密码,就进入了“mysql>”提示符状态,下面就可以输入一些SQL语句查询数据:

    mysql> use dblab;
    mysql> select * from user_action limit 10;
    

    这样,就可以查看到数据库dblab中的user_action表的前10行记录,如下:

    然后切换到刚才已经打开的R命令提示符终端窗口:

    library(RMySQL)
    conn <- dbConnect(MySQL(),dbname='dblab',username='root',password='hadoop',host="127.0.0.1",port=3306)
    user_action <- dbGetQuery(conn,'select * from user_action')
    

    分析消费者对商品的行为

    summary(user_action$behavior_type)
    

    summary() 函数可以得到样本数据类型和长度,如果样本是数值型,我们还能得到样本数据的最小值、最大值、四分位数以及均值信息。
    得到结果:

    可以看出原来的MySQL数据中,消费者行为变量的类型是字符型。这样不好做比较,需要把消费者行为变量转换为数值型变量

    summary(as.numeric(user_action$behavior_type))
    

    得到结果:

    接下来用柱状图表示:

    library(ggplot2)
    ggplot(user_action,aes(as.numeric(behavior_type)))+geom_histogram()
    

    在使用ggplot2库的时候,需要使用library导入库。ggplot()绘制时,创建绘图对象,即第一个图层,包含两个参数(数据与变量名称映射).变量名称需要被包含aes函数里面。ggplot2的图层与图层之间用“+”进行连接。ggplot2包中的geom_histogram()可以很方便的实现直方图的绘制。
    由于我们使用ssh远程调试,无法得到图形界面,所以要增加存储图片的步骤。然后传到个人电脑中查看。命令如下:

    > setwd('/usr/local/rpictures') #选取储存目录,建议和R工作表分开
    > future=paste("fig1",".jpg") #通过paste将文件名和后缀连接起来
    > jpeg(file=future)
    > ggplot(user_action,aes(as.numeric(behavior_type)))+geom_histogram()
    > dev.off()
    

    分析结果如下图:

    从上图可以得到:大部分消费者行为仅仅只是浏览。只有很少部分的消费者会购买商品。
    分析哪一类商品被购买总量前十的商品和被购买总量

    temp <- subset(user_action,as.numeric(behavior_type)==4) # 获取子数据集
    count <- sort(table(temp$item_category),decreasing = T) #排序
    print(count[1:10]) # 获取第1到10个排序结果
    

    subset()函数,从某一个数据框中选择出符合某条件的数据或是相关的列.table()对应的就是统计学中的列联表,是一种记录频数的方法.sort()进行排序,返回排序后的数值向量。
    得到结果:

    结果第一行表示商品分类,该类下被消费的数次。
    接下来用散点图表示:

    > result <- as.data.frame(count[1:10]) #将count矩阵结果转换成数据框
    > setwd('/usr/local/rpictures') #选取储存目录,建议和R工作表分开
    > future=paste("fig2",".jpg") #通过paste将文件名和后缀连接起来
    > jpeg(file=future)
    > ggplot(result,aes(Var1,Freq,col=factor(Var1)))+geom_point()
    > dev.off()
    

    通过 as.data.frame() 把矩阵等转换成为数据框.
    分析结果如下图:

    分析每年的哪个月份购买商品的量最多
    从MySQL直接获取的数据中visit_date变量都是2014年份,并没有划分出具体的月份,那么可以在数据集增加一列月份数据。

    month <- substr(user_action$visit_date,6,7) # visit_date变量中截取月份
    user_action <- cbind(user_action,month) # user_action增加一列月份数据
    

    接下来用柱状图分别表示消费者购买量

    ggplot(user_action,aes(as.numeric(behavior_type),col=factor(month)))+geom_histogram()+facet_grid(.~month)
    

    aes()函数中的col属性可以用来设置颜色。factor()函数则是把数值变量转换成分类变量,作用是以不同的颜色表示。如果不使用factor()函数,颜色将以同一种颜色渐变的颜色表现。 facet_grid(.~month)表示柱状图按照不同月份进行分区。
    由于MySQL获取的数据中只有11月份和12月份的数据,所以上图只有显示两个表格。
    分析结果如下图:

    分析国内哪个省份的消费者最有购买欲望

    library(recharts)
    rel <- as.data.frame(table(temp$province))
    provinces <- rel$Var1
    x = c()
    for(n in provinces){
    x[length(x)+1] = nrow(subset(temp,(province==n)))
    }
    mapData <- data.frame(province=rel$Var1,
    count=x, stringsAsFactors=F) # 设置地图信息
    eMap(mapData, namevar=~province, datavar = ~count) #画出中国地图
    

    nrow()用来计算数据集的行数。
    可能会出现无法显示数字的问题,如下所示。

    这是因为R语言读取sql数据时,读入中文出现乱码,所以无法正确识别省份。于是需要读取时先在R里对数据库中文编码进行如下设置。

    dbSendQuery(conn,'SET NAMES gbk')   #设置格式为Gbk
    

    分析结果如下图:

    展开全文
  • 基于Spark的用户行为分析系统

    千次阅读 2020-06-20 13:44:31
    基于Saprk的用户行为分析系统源码下载 一、项目介绍   本项目主要用于互联网电商企业中使用Spark技术开发的大数据统计分析平台,对电商网站的各种用户行为(访问行为、购物行为、广告点击行为等)进行复杂的分析。...
  • 本文章学习的是厦门大学大数据课程的实验案例——网站用户行为分析,着重于Hadoop平台的操作,而不是数据的分析 文章目录软件版本与环境搭建本地数据集上传到数据仓库Hive数据下载数据处理导入数据库在Hive上创建...
  • 网络用户数据挖掘与行为分析
  • 随着电信市场竞争加剧,电信运营商积极主动地向...一旦采用大数据分析电信运营商就会了解客户,做出准确的业务决策。使用正确的技术,电信行业可以几乎实时地访问他们所寻求的信息。  为什么要分析? 人们很难找...
  • 数据挖掘在电信移动用户行为分析中的应用研究:南昌大学硕士学位论文 数据挖掘在电信商业客户行为分析中的应用研究 姓名:张军 申请学位级别:硕士 专业:计算机系统结构 指导教师:石永革 20100107 摘...|下载前务必先...
  • 本次实验采用厦门大学林子雨教授团队开发的实验课程...学习网址:http://dblab.xmu.edu.cn/post/7499/ 大数据课程实验案例:网站用户行为分析(免费共享) 一、大数据案例-步骤一:本地数据集上传到数据仓库Hive ...
  • · 188 · 丝路视野 利用通信数据的移动用户行为分析 蒋立翀 (中国移动通信集团广东有限公司,广东 广州 510623) 【摘要】科技进步和信息产业的高速发展,带动了移动互联网的迅猛发展,智能手机、平板电脑等移动...
  • 本文讨论了 2019 年第二季度电信行业的客户流失分析。 机器学习是数据挖掘的高级发展,用于从大量数据中提取特征。 论文讨论了监督机器学习模型。 通过支持向量机(SVM)分类步骤设计的监督模型,用于将流失客户和...
  • 电信用户流失数据分析及总结

    千次阅读 2021-03-30 16:59:45
    本项目主要对某电信服务商的用户基础数据进行分析以及预测,探索对用户流失有深刻影响的相关指标,帮助服务商制定有针对性的用户挽留计划,提高用户留存率。 二、技术工具 本项目以jupyter notebook为平台,以Python...
  • 首先介绍了大数据发展历程、基本概念、主要影响、应用领域、关键技术、计算模式和产业发展,并阐述了云计算、物联网的概念及其与大数据之间的紧密关系
  • 基于Hadoop平台的电信数据分析系统 毕业论文 仅供参考,因为论文有查重
  • 对此,基于用户浏览行为分析,提出了一种采用自回归模型来检测应用层DDoS攻击的方法。通过AR模型和卡尔曼滤波,学习和预测正常用户的访问并判断异常;当定位异常访问源后,反馈给前端路由器进行限流或过滤。在电信...
  • 摘要:针对电信运营商越发迫切的智能管道需求,提出了一种具有自学习功能的移动互联网用户行为感知系统的解决方案。本方案针对传统监测系统用户感知度低、统计能力不足等缺点,对现行LTE网络S1接口用户面协议进行...
  • 将精细化营销、数据挖掘等营销管理理念和智能计算方法运用到电信产品营销中,提出了基于移动通信客户行为分析的精确营销策略模型。本模型依据客户行为分别建立客户价值模型、客户粘性模型、客户异动模型和客户需求...
  • 电信行业客户行为标签进行了研究,分析了当前数据及信息系统现状,并结合国内外数据经营基础,重点剖析了数据分散、数据安全性及对外经营模式缺失等问题,提出了数据运营系统的构建方案,以实现数据统一汇聚、统一...
  • 使用SQL Server 2005构建移动用户行为分析平台,徐龙,勾学荣,在电信业重组之后,中国移动、中国电信和新联通对移动网络的用户的争夺势必越演越烈。如何根据用户的个人信息数据和消费数据,构
  • 电信客户流失分析

    千次阅读 2021-07-03 11:37:32
    分析目的 现如今,在电信行业蓬勃发展的同时,电信市场也趋于饱和,获取一个新客户的难度要远远高于维系一个老客户的难度,而老客户的流失意味着收益的流失和市场占有率的下降。可以说,电信运营商的竞争就是针对...
  • Kaggle项目之电信用户流失案例

    千次阅读 2022-03-14 18:12:26
    一、项目背景 流失用户指的使用过产品因为某些原因不再使用该产品。...本项目旨在通过分析特征属性确定用户流失的原因,以及哪些因素可能导致用户流失。建立预测模型来判断用户是否流失,并提出用户流失预警策略。.
  • R语言_电信客户流失数据分析

    千次阅读 2021-12-15 14:36:35
    近年来,各行各业往往都会不可避免地面临用户流失的问题。研究表明,发展新用户所花费的宣传...因此,需要对电信客户进行流失分析与预测,发掘客户流失的原因,进而改善自身业务,提高用户的满意度,延长用户生命周期。
  • 面向精确营销的用户行为分析模型研究与应用,电信行业比较详细的基于数据挖掘的用户行为分析报告
  • 移动APP用户行为分析

    千次阅读 2017-01-22 09:53:55
    一、用户行为分析需要解决3个问题 什么样的用户?用户从何而来?用户来到产品里做了什么?(合适来,何时走) 用户从何而来属于渠道范畴,PC互联网产品与移动互联网产品在推广上存在区别,移动互联网更多的是在...
  • 电信大数据来源于运营商通信网络平台的BSS和OSS,沉淀了海量用户7个维度的信息:1维用户真实ID、1维行为数据、1维社交数据、1维时间数据和3维空间数据。运营商构建电信大数据分析平台,通过对7维用户数据建模,可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,138
精华内容 6,855
关键字:

电信用户行为分析