旅游网站之数据分析

人工智能43

编程要求

在右侧代码窗口完成代码编写:

1:MapReduce类已经配置好,只需完成MapReduce的数据分析;
2:在Map节点执行类中把城市ID当成的输出key,酒店价格当成Mapper类的输出value;
3:在Reduce节点执行类中,统计以城市ID为维度的酒店价格均价,并保存到Hbase;需要满足ROWKEY为城市ID、列族为average_infos、表字段名称为price,计算出的价格均价为表字段值。

t_city_hotels_info表结构如下

列族名称字段对应的文件数据字段描述ROWKEY (格式为:城市ID_酒店ID)cityInfocityIdcity_id城市IDcity_id + "" + idcityInfocityNamecity_name城市名称city_id + "" + idcityInfopinyinpinyin城市拼音city_id + "" + idhotel_infoidid酒店idcity_id + "" + idhotel_infonamename酒店名称city_id + "" + idhotel_infopriceprice酒店价格city_id + "" + idhotel_infolonlon经度city_id + "" + idhotel_infourlurlurl地址hotel_infoimgimg图片city_id + "" + idhotel_infoaddressaddress地址city_id + "" + idhotel_infoscorescore得分city_id + "" + idhotel_infodpscoredpscore用户评分city_id + "" + idhotel_infodpcountdpcount评分个数city_id + "" + idhotel_infostarstar星级city_id + "" + idhotel_infostardescstardesc舒适度city_id + "" + idhotel_infoshortNameshortName酒店简称city_id + "_" + id

测试说明
平台会对你编写的代码进行测试:

测试输入:

t_city_hotels_info,average_table;

预期输出:

row:58
average_infos:price 1145.6170212765958
row:59
average_infos:price 797.2197802197802
package com.processdata;

import java.io.IOException;
import java.util.Scanner;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
import org.apache.hadoop.hbase.mapreduce.TableMapper;
import org.apache.hadoop.hbase.mapreduce.TableReducer;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.DoubleWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

import com.util.HBaseUtil;

public class HBaseMapReduce extends Configured implements Tool {

    public static class MyMapper extends TableMapper<Text, DoubleWritable> {
        public static final byte[] column = "price".getBytes();
        public static final byte[] family = "hotel_info".getBytes();

        @Override
        protected void map(ImmutableBytesWritable rowKey, Result result, Context context)
                throws IOException, InterruptedException {

            String cityId = Bytes.toString(result.getValue("cityInfo".getBytes(), "cityId".getBytes()));
            byte[] value = result.getValue(family, column);
            Double value1 = Double.parseDouble(Bytes.toString(value));
            DoubleWritable i = new DoubleWritable(value1);
            String priceKey = cityId;
            context.write(new Text(priceKey),i);

        }
    }

    public static class MyTableReducer extends TableReducer<Text, DoubleWritable, ImmutableBytesWritable> {
        @Override
        public void reduce(Text key, Iterable<DoubleWritable> values, Context context) throws IOException, InterruptedException {

            double sum = 0;
            int len = 0;
            for (DoubleWritable price : values)
            {
                len ++;
                sum += price.get();
            }
            Put put = new Put(Bytes.toBytes(key.toString()));
            put.addColumn("average_infos".getBytes(),"price".getBytes(),Bytes.toBytes(String.valueOf(sum / len)));
            context.write(null, put);

        }
    }

    public int run(String[] args) throws Exception {

        Configuration conf = HBaseConfiguration.create(getConf());
        conf.set("hbase.zookeeper.quorum", "127.0.0.1");
        conf.set("hbase.zookeeper.property.clientPort", "2181");
        Scanner sc = new Scanner(System.in);
        String arg1 = sc.next();
        String arg2 = sc.next();

        try {
            HBaseUtil.createTable("average_table", new String[] {"average_infos"});
        } catch (Exception e) {

            e.printStackTrace();
        }
        Job job = configureJob(conf,new String[]{arg1,arg2});
        return job.waitForCompletion(true) ? 0 : 1;
    }

    private Job configureJob(Configuration conf, String[] args) throws IOException {
        String tablename = args[0];
        String targetTable = args[1];
        Job job = new Job(conf,tablename);
        Scan scan = new Scan();
        scan.setCaching(300);
        scan.setCacheBlocks(false);

        TableMapReduceUtil.initTableMapperJob(tablename,scan,MyMapper.class, Text.class, DoubleWritable.class,job);

        TableMapReduceUtil.initTableReducerJob(
                targetTable,
                MyTableReducer.class,
                job);
        job.setNumReduceTasks(1);
        return job;
    }
}

编程要求

在右侧代码窗口完成代码编写,MapReduce类已经配置好,只需完成MapReduce的数据分析,你只需将所有分词后的数据存入新表中,平台将会为你输出词频大于100的词组:

1:在Map节点执行类中把评论进行分词当成输出key,Mapper类的输出value为固定值1。

2:在Reduce节点执行类中,统计以评论中分词后的词组为维度的词频数量,并保存到Hbase。需要满足ROWKEY为评论分词、列族为 word_info 、表字段名称为 count 。

t_hotel_comment表结构如下

列族名称字段对应的文件数据字段描述ROWKEY (格式为:城市ID_酒店ID)hotel_infohotel_namehotel_name酒店名称Hotel_id+ "" + idhotel_infohotel_idhotel_id酒店IDHotel_id+ "" + idcomment_infoidid评论idHotel_id+ "" + idcomment_infobaseRoomIdbaseRoomId房间类型Hotel_id+ "" + idcomment_infocontentcontent评论内容Hotel_id+ "" + idcomment_infocheckInDatecheckInDate入住时间Hotel_id+ "" + idcomment_infopostDatepostDate离开时间Hotel_id+ "" + idcomment_infouserNickNameuserNickName用户昵称Hotel_id+ "" + id

测试说明
平台会对你编写的代码进行测试:

测试输入:

t_hotel_comment,comment_word_count;

预期输出:

word:不错
word_info:count 344
word:位置
word_info:count 159
word:住
word_info:count 150
word:免费
word_info:count 110
word:入住
word_info:count 112
word:卫生
word_info:count 106
word:地铁站
word_info:count 144
word:巴士
word_info:count 174
word:干净
word_info:count 211
word:很好
word_info:count 200
word:性价比
word_info:count 123
word:房间
word_info:count 449
word:早餐
word_info:count 116
word:环境
word_info:count 166
word:葵
word_info:count 112
word:酒店
word_info:count 970
word:香港
word_info:count 224
package com.processdata;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
import org.apache.hadoop.hbase.mapreduce.TableMapper;
import org.apache.hadoop.hbase.mapreduce.TableReducer;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
import org.apdplat.word.WordSegmenter;
import org.apdplat.word.segmentation.Word;
import com.util.HBaseUtil;
import com.vdurmont.emoji.EmojiParser;

public class WorldCountMapReduce extends Configured implements Tool {

    public static class MyMapper extends TableMapper<Text, IntWritable> {
        private static byte[] family = "comment_info".getBytes();
        private static byte[] column = "content".getBytes();

        @Override
        protected void map(ImmutableBytesWritable rowKey, Result result, Context context)
                throws IOException, InterruptedException {

            byte[] value = result.getValue(family, column);
            String word = new String(value,"utf-8");
            if(!word.isEmpty())
            {
                String filter = EmojiParser.removeAllEmojis(word);
                List<Word> segs = WordSegmenter.seg(filter);
                for(Word cont : segs)
                {
                    Text text = new Text(cont.getText());
                    IntWritable v = new IntWritable(1);
                    context.write(text,v);
                }
            }

        }
    }

    public static class MyReducer extends TableReducer<Text, IntWritable, ImmutableBytesWritable> {
        private static byte[] family =  "word_info".getBytes();
        private static byte[] column = "count".getBytes();

        @Override
        public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {

            int sum = 0;
            for (IntWritable value : values)
                sum += value.get();
            Put put = new Put(Bytes.toBytes(key.toString()));
            put.addColumn(family,column,Bytes.toBytes(sum));
            context.write(null,put);

        }

    }
    public int run(String[] args) throws Exception {

        Configuration conf = HBaseConfiguration.create(getConf());
        conf.set("hbase.zookeeper.quorum", "127.0.0.1");
        conf.set("hbase.zookeeper.property.clientPort", "2181");
        Scanner sc = new Scanner(System.in);
        String arg1 = sc.next();
        String arg2 = sc.next();
        try {
            HBaseUtil.createTable("comment_word_count", new String[] {"word_info"});
        } catch (Exception e) {

            e.printStackTrace();
        }
        Job job = configureJob(conf,new String[]{arg1,arg2});
        return job.waitForCompletion(true) ? 0 : 1;
    }

    private Job configureJob(Configuration conf, String[] args) throws IOException {
        String tablename = args[0];
        String targetTable = args[1];
        Job job = new Job(conf,tablename);
        Scan scan = new Scan();
        scan.setCaching(300);
        scan.setCacheBlocks(false);

        TableMapReduceUtil.initTableMapperJob(tablename,scan,MyMapper.class, Text.class, IntWritable.class,job);
        TableMapReduceUtil.initTableReducerJob(targetTable,MyReducer.class,job);
        job.setNumReduceTasks(1);
        return job;
    }

}

Original: https://blog.csdn.net/qq_52331221/article/details/127345086
Author: 随兴随缘
Title: 旅游网站之数据分析



相关阅读

Title: 图像分类篇——AlexNet详解

一、概述

AlexNet是由2012年ImageNet竞赛参赛者Hinton和他的学生Alex Krizhevsky设计的。AlexNet在当年赢得了ImageNet图像分类竞赛的冠军,使得CNN成为图像分类问题的核心算法模型,同时引发了神经网络的应用热潮。
1. AlexNet的创新
作为具有历史意义的网络结构,AlexNet包含以下方面的创新。
(1)非线性激活函数 ReLU
在AlexNet出现之前,sigmoid是最为常用的非线性激活函数。sigmoid函数能够把输入的连续实值压缩到0和1之间。但是,它的缺点也非常明显:当输入值非常大或者非常小的时候会出现饱和现象,即这些神经元的梯度接近0,因此存在梯度消失问题。为了解决这个问题,AlexNet使用ReLU作为激活函数。
ReLU函数的表达式为F(x)=max(0,z)。若输入小于0,那么输出为0;若输入大于0,那么输出等于输入。由于导数始终是1,会使得计算量有所减少,且AlexNet的作者在实验中证明了,ReLU 函数的收敛速度要比sigmoid 函数和 tanh函数快。
(2)局部响应归一化
局部响应归一化(local response normalization,LRN)的思想来源于生物学中的"侧抑制",是指被激活的神经元抑制相邻的神经元。采用LRN的目的是,将数据分布调整到合理的范围内,便于计算处理,从而提高泛化能力。虽然ReLu函数对较大的值也有很好的处理效果,但AlexNet的作者仍然采用了LRN的方式。式3.7是Hinton在有关AlexNet的论文中给出的局部响应归一化公式。

旅游网站之数据分析

a表示第i个卷积核在(x,y)处经卷积、池化、ReLU函数计算后的输出,相当于该卷积核提取的局部特征。N表示这一层的卷积核总数;n表示在同一位置的临近卷积核的个数,是预先设定的;k、alpha、beta均为超参数。假设N=20,超参数和n按照论文中的设定,分别为k=2、alpha=10-4、beta=0.75、n=5。第5个卷积核在(x,y)处提取了特征,的作用就是以第5个卷积核为中心,选取前后各5/2=2个(取整,因此n所指个数包含中心卷积核)卷积核,因此有max=3和min=7,卷积核个数就是3、4、5、6、7。
通过分析公式,我们对局部响应归一化的理解会进一步加深。式3.7的存在,使得每个局部特征最后都会被缩小(只是缩小的比例不同),相当于进行了范围控制。一旦在某个卷积核周围提取的特征比它自己提取的特征的值大,那么该卷积核提取的特征就会被缩小。相反,如果在该卷积核周围提取的特征比它自己提取的特征的值小,那么该卷积核提取的特征被缩小的比例就会变小,最终的值与周围的卷积核提取的特征值相比就显得比较大了。
(3) dropout
        dropout通过设置好的概率随机将某个隐藏层神经元的输出设置为0,因此这个神经元将不参与前向传播和反向传播,在下一次迭代中会根据概率重新将某个神经元的输出置0。这样一来,在每次迭代中都能够尝试不同的网络结构,通过组合多个模型的方式有效地减少过拟合。
(4)多GPU训练
        单个GPU的内存限制了网络的训练规模。采用多GPU协同训练,可以大大提高AlexNet的训练速度。

二、AlexNet的结构

下面介绍AlexNet的结构。如图所示,由于采用双GPU协同训练,该网络结构图分为上下两部分,且两个GPU只在特定的层内通信。该模型一共分为8层,包括5个卷积层和3个全连接层,每个卷积层都包含激活函数ReLU、池化和LRN处理。

旅游网站之数据分析

AlexNet架构 层类型特征图大小内核步幅填充激活OUT全连接-1000---ReLUF10全连接-4096---ReLUF9全连接-4096---ReLUs8最大池化25666332valid-C7卷积2561313551sameReLUC6卷积3841313551sameReLUC5卷积3841313551sameReLUS4最大池化2561313332valid-C3卷积2562727551sameReLUS2最大池化962727332valid-C1卷积96555511114validReLUIn输入3(RGB)227*227----

(1)Layer1卷积层
该层接收227×227×3(R、G、B三个通道)的输入图像,使用96个大小为11×11×3的卷积核进行特征提取,步长为1,扩充值为0,通过式3.1可以得到输出特征图的尺寸。由于使用了双GPU,图3.13中的每个GPU处理的卷积核的数量均为48个。卷积后,得到大小为55×55×96的特征图。
对得到的特征图,使用ReLU函数将它的值限定在合适的范围内,然后使用3×3的滤波器进行步长为2的池化操作,得到27×27×96的特征图。最后,进行归一化处理,规模不变。
(2)Layer 2卷积层
Layer 2与Layer 1相似,它接收Layer 1输出的27×27×96的特征图,采用256个5×5×96的卷积核,步长为1,扩充值为2,边缘用0填充,生成27×27×256的特征图。紧随其后的是与Layer 1相同的ReLU函数和池化操作,最后进行归一化处理。
(3) Layer3卷积层与Layer 4卷积层
Layer3和Layer4也采用了卷积层,但只进行卷积和ReLU。不进行池化和归一化操作。Layer3的每个GPU都有192个卷积核,每个卷积核的尺寸是3×3×256.步长为1,扩充值为1,边缘用0填充。最终,每个GPU都生成的个13×13的特征图。
Layer 4与Layer3的区别在于卷积核的尺寸。Layer4不像Layer3那样接收的一层所有GPU的输入,而只接收所在GPU的输出。因此,Layer 4的卷积核的尺寸为3×3×192,每个GPU都有192个卷积核。
与Layer 3相同的是,Layer 4仍然进行扩充值为1的0填充,且步长为1。最终,Layer 4的每个GPU都生成192个13×13的特征图。卷积后,这两个层都会由ReLU函数进行处理。
(4)Layer 5卷积层
Layer 5会依次进行卷积、ReLU和池化操作,但不进行归一化操作。该层中的每个GPU都接收本GPU中 Layer 4的输出,每个GPU使用128个3×3×192的卷积核,步长为1,使用扩充值为1的0填充,各自生成128个13×13的特征图后进行池化操作。池化尺寸为3×3,步长为2,最终生成6×6×128的特征图(两个GPU,共256个)。
(5)Layer 6全连接层
从该层开始,后面的网络层均为全连接层。Layer 6仍然按GPU进行卷积,每个GPU使用2048个6×6×256的卷积核,这意味着该层中的每个GPU都会接收前一层中两个GPU 的输出。卷积后,每个GPU都会生成2048个1×1的特征图。最后,进行ReLU和dropout操作,两个GPU共输出4096个值。
(6)Layer 7全连接层
Layer7与Layer6相似,与Layer6进行全连接,在进行ReLU和dropout操作后,共输出4096个值。
(7)Layer 8全连接层
Layer 8只进行全连接操作,且该层拥有1000个神经元,最终输出1000个float型的值(该值即为预测结果)。

三、构建AlexNet

构建LRN层

LRN层通常用lambda层进行包装,参数一般设置如下:

model.add(keras.layers.lambdas(lambda x: tf.nn.lrn(x, depth_radius=2, alpha=0.00002, beta=0.75, bias=1)))

也可以用自定义层实现:

class LRN(keras.layers.Layer):
    def __init__(self, depth_radius=2, bias=1, alpha=0.00002, beta=0.75, **kwargs):
        super().__init__(**kwargs)
        self.depth_radius = depth_radius
        self.bias = bias
        self.alpha = alpha
        self.beta = beta

    def call(self, input):
        return tf.nn.lrn(input, self.depth_radius, self.bias, self.alpha, self.beta)

    def get_config(self):
        base_config = super().get_config()
        return {**base_config, 'depth_radius': self.depth_radius,
                'bias': self.bias, 'alpha': self.alpha, 'beta': self.beta}

构建模型:

model = keras.Sequential()
# &#x7B2C;&#x4E00;&#x5C42;
model.add(keras.layers.Conv2D(filters=96, kernel_size=(11,11), strides=(4,4), input_shape=(227,227,3), padding="VALID", activation="relu"))
model.add(LRN())
model.add(keras.layers.MaxPooling2D(pool_size=(3,3), strides=(2,2), padding="same"))
# &#x7B2C;&#x4E8C;&#x5C42;
model.add(keras.layers.Conv2D(filters=256, kernel_size=(5,5), strides=(1,1), padding="SAME", activation="relu"))
model.add(LRN())
model.add(keras.layers.MaxPooling2D(pool_size=(3,3), strides=(2,2), padding="same"))
# &#x7B2C;&#x4E09;&#x5C42;
model.add(keras.layers.Conv2D(filters=384, kernel_size=(5,5), strides=(1,1), padding="SAME", activation="relu"))
# &#x7B2C;&#x56DB;&#x5C42;
model.add(keras.layers.Conv2D(filters=384, kernel_size=(5,5), strides=(1,1), padding="SAME", activation="relu"))
# &#x7B2C;&#x4E94;&#x5C42;
model.add(keras.layers.Conv2D(filters=256, kernel_size=(5,5), strides=(1,1), padding="SAME", activation="relu"))
model.add(keras.layers.MaxPooling2D(pool_size=(3,3), strides=(2,2), padding="same"))
# &#x7B2C;&#x516D;&#x5C42;
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(4096, activation="relu"))
model.add(keras.layers.Dropout(0.5))
# &#x7B2C;&#x4E03;&#x5C42;
model.add(keras.layers.Dense(4096, activation="relu"))
model.add(keras.layers.Dropout(0.5))
# &#x7B2C;&#x516B;&#x5C42;
model.add(keras.layers.Dense(10, activation="softmax"))

注:LRN层也可用BatchNormalization替代,性能也还OK

Original: https://blog.csdn.net/qq_52053775/article/details/124377926
Author: 樱花的浪漫
Title: 图像分类篇——AlexNet详解

相关文章
NLP——Tokenizer 人工智能

NLP——Tokenizer

1.什么是Tokenizer 使用文本的第一步就是将其拆分为单词。单词称为标记(token),将文本拆分为标记的过程称为标记化(tokenization),而标记化用到的模型或工具称为tokenize...
TensorFlow学习报告 人工智能

TensorFlow学习报告

创建常量 tensor可以由各种各样的类型,如字符串、布尔值、列表、浮点型等转换 tf.constant(32) tf.constant("Hello") tf.constant(True) 还可以给...
神经网络案例 人工智能

神经网络案例

目录 神经网络案例 * 数据加载 数据处理 模型构建 模型编译 模型训练 模型测试 模型保存 总结 神经网络案例 学习目标 能够利用tf.keras获取数据集 能够网络多层神经网络的构建 能够完成网络...
算法工程师老潘总结的一些经验 人工智能

算法工程师老潘总结的一些经验

算法工程师老潘总结的一些经验 前一段时间一直在优化部署模型。这几天终于来了需求,又要开始重操训练一些新模型了。趁着这次机会总结了下之前的一些训练模型的笔记,可能比较杂,抛砖引玉!当然这是不完全统计的经...
CNN卷积神经网络 入门案例 人工智能

CNN卷积神经网络 入门案例

数据介绍 Clifar 10 数据集 5w张 32x32 的图片 训练 1w张 32x32 的图片 测试 输入是分为10个标签,下面的图的左边已经给出了。 ; 导入数据集 可视化一张图片看看 打印出 ...
Python-机器学习(三)-KMeans聚类算法 人工智能

Python-机器学习(三)-KMeans聚类算法

算法原理 K-means算法是最常用的一种聚类算法。算法的输入为一个样本集(或者称为点集),通过该算法可以将样本进行聚类,具有相似特征的样本聚为一类。针对每个点,计算这个点距离所有中心点最近的那个中心...
NCHW与NHWC格式 人工智能

NCHW与NHWC格式

NCHW与NHWC格式 下图很好的描述了各种不同的格式。 N代表数量, C代表channel,H代表高度,W代表宽度。 NCHW其实代表的是[W H C N],第一个元素是000,第二个元素是沿着w方...