1. 1. 智能化应用(shell)
    1. 1.1. 1.1 创建主目录及各层级目录
    2. 1.2. 1.2 为目录添加文件
    3. 1.3. 1.3 验证目录和文件结构
    4. 1.4. 2 编写脚本文件write_log.sh,用于将时间信息写入服务日志文件(service.log),保存路径为/root/scripts/。
    5. 1.5. 3 将任务1中创建的项目smart-police-system远程复制至主机jupyter对应的 /root目录下。
    6. 1.6. 4. 为更好监控服务状态,使用cron来实现定时任务,要求每五分钟执行一次write_log.sh脚本。
  2. 2. 伪分布式集群搭建
    1. 2.1. 基础配置
      1. 2.1.1. 1. 修改主机名为 qingjiao
      2. 2.1.2. 2. 创建文件夹 /root/task
      3. 2.1.3. 3. 创建文件 /root/task/student
      4. 2.1.4. 4. 修改 hosts 文件添加主机名映射
      5. 2.1.5. 5. 修改时区为上海时间
      6. 2.1.6. 6. 添加定时任务
    2. 2.2. SSH免密配置
      1. 2.2.1. 1. 节点中生成公钥文件id_rsa.pub(数字签名RSA,用户root,主机名qingjiao)
      2. 2.2.2. 2. 建⽴qingjiao⾃身使⽤root⽤户ssh访问localhost免密登录(自行完成首次公钥匙认证)
    3. 2.3. JDK安装
      1. 2.3.1. 1.将jdk安装包解压到/usr/java目录(安装包存放于/usr/package277,路径自行创建,解压后文件夹为默认名称,其他安装同理)
    4. 2.4. Hadoo伪集群部署
      1. 2.4.1. 1. 将Hadoop安装包解压到指定路径/usr/hadoop(安装包存放于/usr/package277/)
      2. 2.4.2. 2. 配置环境变量HADOOP_HOME,将Hadoop安装路径中bin目录和sbin目录加入PATH系统变量,注意生效变量
      3. 2.4.3. 3. 配置Hadoop运行环境JAVA_HOME(hadoop-env.sh)
      4. 2.4.4. 4. 设置全局参数,指定HDFS上NameNode地址为qingjiao,端口默认为9000(core-site.xml)
      5. 2.4.5. 5. 设置全局参数,指定临时存储目录为本地/root/hadoopData/tmp(要求为绝对路径,下同)
      6. 2.4.6. 6. 设置HDFS参数,指定备份文本数量为1(hdfs-site.xml)
      7. 2.4.7. 7. 设置HDFS参数,指定NN存放元数据信息路径为本地/root/hadoopData/name;指定DN存放元数据信息路径为本地/root/hadoopData/data(要求为绝对路径)
      8. 2.4.8. 8. 设置HDFS参数,关闭hadoop集群权限校验(安全配置),允许其他用户连接集群
      9. 2.4.9. 9. 设置YARN运行环境$JAVA_HOME参数(yarn-env.sh)
      10. 2.4.10. 10. 设置YARN核心参数,指定mapreduce 获取数据的方式为mapreduce_shuffle(yarn-site.xml)
      11. 2.4.11. 11. 设置计算框架参数,指定MR运行在yarn上(mapred-site.xml)
      12. 2.4.12. 12. 设置节点文件slaves,要求qingjiao为子节点
      13. 2.4.13. 13. 对文件系统进行格式化
      14. 2.4.14. 14. 启动Hadoop集群查看各节点服务
      15. 2.4.15. 15. 查看集群运行状态是否正常
  3. 3. 交通事故数据分析
  4. 4. 电信诈骗数据分析(Python)
    1. 4.0.1. 背景说明
  • 一、探索性分析
  • 二、整体特征分析,观察特征之间的相关性
  • 三、分组聚合分析
    1. 1. 3.2 任务一:分析 distance_from_home与fraud之间的关系
    2. 2. 3.2 任务二:分析 ratio_to_median_purchase_price与 fraud之间的关系
    3. 3. 3.3 任务三:分析 repeat_retailer与 fraud之间的关系
    4. 4. Mysql
      1. 4.1. 1. 开启 MySQL 服务
      2. 4.2. 2. 创建数据库 relation
      3. 4.3. 3. 创建数据表 user 并导入数据
      4. 4.4. 4. 创建数据表 friend 并导入数据
      5. 4.5. 5. 分析不同用户的好友数并存储为视图 table1
      6. 4.6. 6. 查找用户“系乐”的所有朋友信息并存储为视图 table2
      7. 4.7. 7. 查询用户的所有好友信息并存储为视图 table3
      8. 4.8. 8. 查询“系乐”和“姚欣然”的共同好友信息并存储为视图 table4
      9. 4.9. 9. 进行社交网络挖掘并存储为视图 table5
    5. 5. 数据库安全管理
      1. 5.1. 1. 启动 MySQL 服务并查看服务状态
      2. 5.2. 2. 创建用户 qingjiao
      3. 5.3. 3. 授予 qingjiao 用户在 datatest 库下的 CREATE 权限
      4. 5.4. 4. 切换到 qingjiao 用户并创建数据库和表
  • 大数据模拟赛题解

    智能化应用(shell)

    1.1 创建主目录及各层级目录

    1
    2
    3
    4
    5
    6
    7
    8
    # 创建主目录
    mkdir -p /root/smart-police-system/

    # 创建基础层目录
    mkdir -p /root/smart-police-system/Infrastructure_Layer/Network_Configuration

    # 创建服务层目录
    mkdir -p /root/smart-police-system/Service_Layer/Logging_Service

    1.2 为目录添加文件

    1
    2
    3
    4
    5
    # 在网络配置目录下创建 network.conf 配置文件
    touch /root/smart-police-system/Infrastructure_Layer/Network_Configuration/network.conf

    # 在日志服务目录下创建 service.log 日志文件
    touch /root/smart-police-system/Service_Layer/Logging_Service/service.log

    1.3 验证目录和文件结构

    1
    tree

    2 编写脚本文件write_log.sh,用于将时间信息写入服务日志文件(service.log),保存路径为/root/scripts/

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    # 定义日志文件路径
    LOG_FILE="/root/smart-police-system/Service_Layer/Logging_Service/service.log"

    # 获取当前时间
    CURRENT_TIME=$(date "+%Y-%m-%d %H:%M:%S")

    # 写入日志信息
    echo "[$CURRENT_TIME] Service is running normally." >> "$LOG_FILE"

    给予下文件权限

    1
    chmod +x /path/to/write_log.sh

    3 将任务1中创建的项目smart-police-system远程复制至主机jupyter对应的 /root目录下。

    1
    scp -r /root/smart-police-system/ root@jupyter:/root/

    4. 为更好监控服务状态,使用cron来实现定时任务,要求每五分钟执行一次write_log.sh脚本。

    1
    crontab -e

    ==注意== 如果没有给予脚本权限,可能会出错

    1
    */5 * * * * /bin/bash /path/to/write_log.sh

    伪分布式集群搭建

    基础配置

    1. 修改主机名为 qingjiao

    1
    2
    3
    sudo hostnamectl set-hostname qingjiao

    bash

    2. 创建文件夹 /root/task

    1
    mkdir /root/task

    3. 创建文件 /root/task/student

    1
    touch /root/task/student

    4. 修改 hosts 文件添加主机名映射

    1
    touch /root/task/student

    5. 修改时区为上海时间

    1
    sudo timedatectl set-timezone Asia/Shanghai

    该命令将系统时区更改为上海时区(CST+0800时区)。

    6. 添加定时任务

    编辑 crontab 文件:

    1
    crontab -e

    crontab 文件中添加以下行:

    1
    0 10 * * * date >> /root/task/student

    SSH免密配置

    1. 节点中生成公钥文件id_rsa.pub(数字签名RSA,用户root,主机名qingjiao)

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 在 master 上执行如下命令生成公私密钥:(注意 master 上执行,默认为 rsa 类型)

    ssh-keygen

    # 然后将公钥文件内容添加到授权文件。

    ssh-copy-id -i /root/.ssh/id_rsa.pub qingjiao

    # (或者使用 localhost 也可已完成本地免密)

    2. 建⽴qingjiao⾃身使⽤root⽤户ssh访问localhost免密登录(自行完成首次公钥匙认证)

    1
    ssh root@localhost

    JDK安装

    1.将jdk安装包解压到/usr/java目录(安装包存放于/usr/package277,路径自行创建,解压后文件夹为默认名称,其他安装同理)

    1
    2
    3
    mkdir -p /usr/java
    cd /usr/java
    tar -zxvf /usr/package277/jdk-8u221-linux-x64.tar.gz -C /usr/java/

    配置系统环境变量JAVA_HOME,同时将JDK安装路径中bin目录加入PATH系统变量,注意生效变量,查看JDK版本

    1
    vim /etc/profile

    添加

    1
    2
    3
    4
    export JAVA_HOME=/usr/java/jdk1.8.0_221
    export CLASSPATH=$JAVA_HOME/lib/
    export PATH=$PATH:$JAVA_HOME/bin
    export PATH JAVA_HOME CLASSPATH
    • 生效环境变量:source /etc/profile
    • 查看 java 版本:java -version

    Hadoo伪集群部署

    1. 将Hadoop安装包解压到指定路径/usr/hadoop(安装包存放于/usr/package277/)

    1
    2
    3
    mkdir -p /usr/hadoop && cd /usr/hadoop

    tar -zxvf /usr/package277/hadoop-2.7.7.tar.gz -C /usr/hadoop/

    2. 配置环境变量HADOOP_HOME,将Hadoop安装路径中bin目录和sbin目录加入PATH系统变量,注意生效变量

    1
    vim /etc/profile

    添加

    1
    2
    3
    4
    5
    #hadoop
    #配置 Hadoop 安装目录
    export HADOOP_HOME=/usr/hadoop/hadoop-2.7.7
    #在原 PATH 基础上加入 Hadoop 的 bin 和 sbin 目录
    export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
    1
    source /etc/profile

    3. 配置Hadoop运行环境JAVA_HOME(hadoop-env.sh)

    1
    2
    cd $HADOOP_HOME/etc/hadoop
    vim hadoop-env.sh

    添加

    1
    export JAVA_HOME=/usr/java/jdk1.8.0_221

    4. 设置全局参数,指定HDFS上NameNode地址为qingjiao,端口默认为9000(core-site.xml)

    1
    vim core-site.xml
    1
    2
    <configuration>
    </configuration>中添加
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <property> 
    <name>fs.default.name</name>
    <!-- 用于指定 NameNode 的地址 -->
    <value>hdfs://qingjiao:9000</value>
    </property>

    <property>
    <name>hadoop.tmp.dir</name>
    <!-- Hadoop 运行时产生文件的临时存储目录 -->
    <value>/root/hadoopData/tmp</value>
    </property>

    5. 设置全局参数,指定临时存储目录为本地/root/hadoopData/tmp(要求为绝对路径,下同)

    接上

    6. 设置HDFS参数,指定备份文本数量为1(hdfs-site.xml)

    1
    vim hdfs-site.xml
    1
    2
    <configuration>
    </configuration>中添加
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <property>
    <name>dfs.replication</name>
    <!-- 数据块副本的数量,默认为 3 -->
    <value>1</value>
    </property>

    <property>
    <name>dfs.namenode.name.dir</name>
    <!-- NameNode 在本地文件系统中持久存储命名空间和事务日志的路径 -->
    <value>/root/hadoopData/name</value>
    </property>

    <property>
    <name>dfs.datanode.data.dir</name>
    <!-- DataNode 在本地文件系统中存放块的路径 -->
    <value>/root/hadoopData/data</value>
    </property>

    <property>
    <name>dfs.permissions</name>
    <!-- 关闭 hadoop 集群权限校验 -->
    <value>false</value>
    </property>

    <property>
    <name>dfs.datanode.use.datanode.hostname</name>
    <!-- datanode 之间的通信也通过域名方式 -->
    <value>true</value>
    </property>

    7. 设置HDFS参数,指定NN存放元数据信息路径为本地/root/hadoopData/name;指定DN存放元数据信息路径为本地/root/hadoopData/data(要求为绝对路径)

    接上

    8. 设置HDFS参数,关闭hadoop集群权限校验(安全配置),允许其他用户连接集群

    接上

    9. 设置YARN运行环境$JAVA_HOME参数(yarn-env.sh)

    1
    vim yarn-env.sh
    1
    export JAVA_HOME=/usr/java/jdk1.8.0_221

    10. 设置YARN核心参数,指定mapreduce 获取数据的方式为mapreduce_shuffle(yarn-site.xml)

    1
    vim hdfs-site.xml
    1
    2
    <configuration>
    </configuration>中添加
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <property>
    <name>yarn.resourcemanager.admin.address</name>
    <value>master:18141</value>
    </property>

    <property>
    <name>yarn.nodemanager.aux-services</name>
    <!-- 指定 reducer 获取数据的方式-->
    <!-- NodeManager 上运行的附属服务,也可以理解为 mapreduce 获取数据的方式 -->
    <value>mapreduce_shuffle</value>
    </property>

    <property>
    <name>yarn.nodemanager.auxservices.mapreduce.shuffle.class</name>
    <value>org.apache.hadoop.mapred.ShuffleHandler</value>
    </property>

    11. 设置计算框架参数,指定MR运行在yarn上(mapred-site.xml)

    1
    cp mapred-site.xml.template mapred-site.xml && vim mapred-site.xml
    1
    2
    <configuration>
    </configuration>中添加
    1
    2
    3
    4
    5
    6
    <property>
    <!--指定 Mapreduce 运行在 yarn 上-->
    <!-- 指定使用 YARN 运行 MapReduce 程序,默认为 local -->
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
    </property>

    12. 设置节点文件slaves,要求qingjiao为子节点

    1
    echo qingjiao > slaves

    13. 对文件系统进行格式化

    1
    hadoop namenode -format

    14. 启动Hadoop集群查看各节点服务

    1
    start-all.sh

    出错的话

    1
    2
    stop-all.sh
    start-all.sh

    15. 查看集群运行状态是否正常

    1
    hdfs dfsadmin -report

    交通事故数据分析

    1
    2
    import pandas as pd
    import numpy as np
    1
    data = pd.read_excel("./事故数据.xlsx")
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import pandas as pd

    # 1. 对全量数据的"事故严重性"分布构成进行分析
    severity_distribution = data['事故严重性'].value_counts(normalize=True).reset_index()
    severity_distribution.columns = ['事故严重性', '占比']
    severity_distribution['事故数'] = severity_distribution['占比'] * len(data)
    severity_distribution['占比'] = severity_distribution['占比'].apply(lambda x: f"{x:.2%}")
    severity_distribution.drop_duplicates(inplace=True)
    severity_distribution.to_csv('01.txt', index=False, sep=' ', header=False)
    1
    2
    3
    # 2. 在“特别严重”的事故数据中,对“事故车辆“的分布构成进行分析
    severe_data = data[data['事故严重性'] == 3]
    severe_data
    1
    2
    3
    # 3. 分析“高速”道路中5车及以上事故车辆对应的“平均伤亡人数”
    highway_data = data[(data['一类道路'] == 1) & (data['事故车辆'] >= 5)]
    highway_data
    1
    2
    3
    4
    average_casualties = highway_data.groupby('事故车辆')['伤亡人数'].mean().reset_index()
    average_casualties.columns = ['事故车辆', '平均伤亡人数']
    average_casualties['事故数'] = highway_data['事故车辆'].value_counts().reindex(average_casualties['事故车辆'], fill_value=0)
    average_casualties.to_csv('03.txt', index=False, sep=' ', header=False)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 4. 对全量数据进行时间(周)分布分析
    # 咨询全量数据中周的分布情况
    weekly_distribution = data['周(星期)'].value_counts().reset_index()
    # 重命名列名
    weekly_distribution.columns = ['周', '事故数']
    # 计算各周事故数占总事故数的比例
    weekly_distribution['事故占比'] = weekly_distribution['事故数'] / len(data)
    # 按周的顺序排序(可选操作,若周的数值本身没有顺序则无需排序)
    weekly_distribution.sort_values(by='周', inplace=True)
    # 将结果保存到04.txt文件中,指定分隔符为空格,不包含索引和列名
    weekly_distribution.to_csv('04.txt', index=False, sep=' ', header=False)
    1
    2
    3
    4
    5
    6
    7

    # 5. 对全量数据进行道路类型分布分析
    road_type_distribution = data['道路类型'].value_counts(normalize=True).reset_index()
    road_type_distribution.columns = ['道路类型', '占比']
    road_type_distribution['事故数'] = road_type_distribution['占比'] * len(data)
    road_type_distribution['占比'] = road_type_distribution['占比'].apply(lambda x: f"{x:.2%}")
    road_type_distribution.to_csv('05.txt', index=False, sep=' ', header=False)
    1
    2
    3
    4
    5
    6
    7
    8
    # 6. 分析“学校道路”下事故限速情况分布
    school_road_data = data[data['道路类型'] == 9]
    speed_limit_distribution = school_road_data['限速情况'].value_counts().reset_index()
    speed_limit_distribution.columns = ['限速情况', '事故数']
    speed_limit_distribution['数据占比'] = speed_limit_distribution['事故数'] / len(school_road_data)
    speed_limit_distribution['数据占比(%)'] = speed_limit_distribution['数据占比'].apply(lambda x: f"{x * 100:.2f}%")
    speed_limit_distribution = speed_limit_distribution[['限速情况', '事故数', '数据占比(%)']]
    speed_limit_distribution.to_csv('06.txt', index=False, sep=' ', header=False)
    1
    2
    3
    4
    5
    6
    7
    8
    # 7. 分析“乡村道路”事故中“灯光情况”构成
    rural_road_data = data[data['道路类型'] == 3]
    lighting_distribution = rural_road_data['灯光情况'].value_counts().reset_index()
    lighting_distribution.columns = ['灯光情况', '事故数']
    lighting_distribution['数据占比'] = lighting_distribution['事故数'] / len(rural_road_data)
    lighting_distribution['数据占比(%)'] = lighting_distribution['数据占比'].apply(lambda x: f"{x * 100:.2f}%")
    lighting_distribution = lighting_distribution[['灯光情况', '事故数', '数据占比(%)']]
    lighting_distribution.to_csv('07.txt', index=False, sep=' ', header=False)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 8. 分析“城市道路”事故中“天气情况”构成
    urban_road_data = data[data['道路类型'] == 2]
    weather_distribution = urban_road_data['天气情况'].value_counts().reset_index()
    weather_distribution.columns = ['天气情况', '事故数']
    weather_distribution['数据占比'] = weather_distribution['事故数'] / len(urban_road_data)
    weather_distribution['数据占比(%)'] = weather_distribution['数据占比'].apply(lambda x: f"{x * 100:.2f}%")
    weather_distribution = weather_distribution[['天气情况', '事故数', '数据占比(%)']]
    weather_distribution.to_csv('08.txt', index=False, sep=' ', header=False)

    电信诈骗数据分析(Python)

    背景说明

    随着移动支付的迅速发展,电信诈骗案件不断增加。在如此严峻的形势下,如何有效地检测欺诈行为成为一个亟待解决的挑战。为了应对这一挑战,我们收集了约40万条银行卡交易记录,其中包含了七个关键特征以及一个标签”fraud”。这些特征包括交易地点、最近交易金额与历史交易金额的对比、是否使用PIN码等。通过对这些给定数据集的探索性分析,我们可以揭示被骗者的银行卡交易特征,从而协助反诈警务人员及时发出预警信息,有效保护人民的财产安全。我们的研究旨在利用这些数据和特征,为社会提供更有效的防范措施,减少诈骗事件对个人和社会造成的损失。

    列名 类型 说明
    distance_from_home float64 银行卡交易地点与家的距离
    distance_from_last_transaction float64 与上次交易发生的距离
    ratio_to_median_purchase_price float64 近一次交易与以往交易价格中位数的比率
    repeat_retailer float64 交易是否发生在同一个商户
    used_chip float64 是通过芯片(银行卡)进行的交易
    used_pin_number float64 交易时是否使用了PIN码
    online_order float64 是否是在线交易订单
    fraud float64 诈骗片行为(标签)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    # 导包
    %matplotlib inline
    import numpy as np
    import pandas as pd
    import math
    import seaborn as sns

    import matplotlib.pyplot as plt
    import matplotlib.ticker as ticker

    from datetime import tzinfo,timedelta,datetime
    # 消除一些警告
    import warnings
    warnings.simplefilter('ignore')

    # 设置显示中文字体,
    # 设置font.sans-serif 或 font.family 均可
    plt.rcParams["font.sans-serif"] = ["Arial Unicode MS"] ## mac
    plt.rcParams['font.family']=['Arial Unicode MS'] ## mac
    plt.rcParams["font.sans-serif"] = ["SimHei"] ## win
    plt.rcParams['font.family']=['SimHei'] ## win
    # 设置正常显示符号
    plt.rcParams["axes.unicode_minus"] = False

    一、探索性分析

    • 读取数据
    • 查看数据类型
    • 空值检测
    • 异常值检测
    • 正负样本分布
    1
    2
    3
    4
    5
    # 读取CSV文件

    data = pd.read_csv('./data/Card_data.csv')
    print(data.shape) # 查看数量形状
    data.head(10) # 查看前十条数据
    1
    2
    # 查看表 data中各列基本信息,包括:列名、数量、数据类型等。
    data.info()
    1
    2
    3
    # 查看数据集各列的数据统计情况

    data.describe()

    可以观察到distance_from_home(银行卡交易地点与家的距离)和distance_from_last_transaction(与上次交易发生的距离)的方差相对于其他特征很大

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 统计是否被诈骗数量分布

    num_fraud = data[data['fraud'] == 1.0].shape[0] # fraud = 1.0 表示 被诈骗数据
    num_no_fraud = data[data['fraud'] == 0.0].shape[0] # fraud = 0.0 表示 未被诈骗数据

    print(num_fraud,num_no_fraud)

    ##绘制正负样本百分比图

    # 数据
    labels = ['fraud', 'Not fraud']
    sizes = [num_fraud, num_no_fraud]

    # 绘制饼图
    plt.pie(sizes, labels=labels,colors=['#fdbf9c','#d6f9d1'], autopct='%1.1f%%', textprops={'fontsize': 13},startangle=90)

    # 添加标题
    plt.title('是否被诈骗数量分布百分比图',fontsize=15)

    # 显示图形
    plt.show()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 基于箱型图,检测异常值

    # 数据
    d1 = data['distance_from_home']
    d2 = data['distance_from_last_transaction']
    d3 = data['ratio_to_median_purchase_price']
    d4 = data['repeat_retailer']
    d5 = data['used_chip']
    d6 = data['used_pin_number']
    d7 = data['online_order']

    # 绘制各类别异常值分析箱型图
    fig = plt.figure(figsize=(16, 8))
    plt.title('各类别异常值分析箱型图', fontsize=15)
    label = 'distance_from_home', 'distance_from_last_transaction', 'ratio_to_median_purchase_price', 'repeat_retailer', 'used_chip', 'used_pin_number', 'online_order'
    plt.boxplot([d1, d2, d3, d4, d5, d6, d7], labels=label) # label设置横轴每个箱图对应的横坐标
    plt.xticks(rotation=45, fontsize=13)
    plt.xlabel('变量', fontsize=13)
    plt.ylabel('变量值', fontsize=13)

    plt.show()

    二、整体特征分析,观察特征之间的相关性

    • 第一步:创建2个新表, Fraud 和 NotFraud, 分别对应 被诈骗数据 和 未被诈骗数据
    • 第二步:求得相关性,画出热力图进行分析
    1
    2
    3
    4
    5
    # 第一步:创建新表Fraud 【被诈骗数据】

    Fraud = data[data['fraud'] == 1]
    print('查看表Fraud的形状:', Fraud.shape)
    Fraud.head() # 查看 表Fraud 的前5行
    1
    2
    3
    4
    # 创建新表 NotFraud 【未被诈骗数据】
    NotFraud = data[data['fraud'] == 0]
    print('查看表NotFraud的形状:', NotFraud.shape)
    NotFraud.head() # 查看 表NotFraud 的前5行
    1
    2
    3
    4
    5
    6
    7
    #第 2步:计算 表NotFraud 的相关性 

    # 这里计算 除 fraud列 的剩余7列的相关性
    corr_Fraud = Fraud.loc[:, Fraud.columns != 'fraud'].corr()

    # 查看计算结果
    corr_Fraud
    1
    2
    3
    4
    5
    6
    #计算 表NotFraud 的相关性 

    # 这里计算 除 fraud列 的剩余7列的相关性,因为 fraud是标签不算特征
    corr_NotFraud = NotFraud.loc[:, NotFraud.columns != 'fraud'].corr()
    # 查看计算结果
    corr_NotFraud
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    # 绘制热力图,观察各个特征之间的相关性

    # 创建图像
    grid_kws = {"width_ratios": (.9, .9, .05), "wspace": 0.2}
    f, (ax1, ax2, cbar_ax) = plt.subplots(1, 3, gridspec_kw=grid_kws, figsize = (18, 9))
    # 定义调色板
    cmap = sns.diverging_palette(0, 230, 90, 60, as_cmap=True)

    # 画 NotFraud 表中的各个特征间相关性热力图
    # 计算上三角mask矩阵
    mask1 = np.zeros_like(corr_NotFraud)
    indices = np.triu_indices_from(corr_NotFraud)
    mask1[indices] = True

    # 过滤空值
    mask1 = mask1[1:, :-1]
    corr_NotFraud = corr_NotFraud.iloc[1:, :-1].copy()
    ax1 =sns.heatmap(corr_NotFraud, ax = ax1, vmin = -1, vmax = 1, cmap = cmap, square = False, \
    annot=True, fmt=".2f", linewidths = 0.5, mask = mask1, cbar = False)
    ax1.set_xticklabels(ax1.get_xticklabels(), size = 16);
    ax1.set_yticklabels(ax1.get_yticklabels(), size = 16);
    ax1.set_title('fraud=1的热力图', size = 20)

    # 画 Fraud 表中的各个特征间相关性热力图

    # 计算上三角mask矩阵
    mask2 = np.zeros_like(corr_Fraud)
    indices = np.triu_indices_from(corr_Fraud)
    mask2[indices] = True

    # 过滤空值
    mask2 = mask2[1:, :-1]
    corr_Fraud = corr_Fraud.iloc[1:, :-1].copy()

    ax2 = sns.heatmap(corr_Fraud, vmin = -1, vmax = 1, cmap = cmap, ax = ax2, square = False, \
    linewidths = 0.5, mask = mask2, yticklabels = False, \
    annot=True, fmt=".2f", cbar_ax = cbar_ax, cbar_kws={'orientation': 'vertical', 'ticks': [-1, -0.5, 0, 0.5, 1]})

    ax2.set_xticklabels(ax2.get_xticklabels(), size = 16);
    ax2.set_title('fraud=0的热力图', size = 20);

    cbar_ax.set_yticklabels(cbar_ax.get_yticklabels(), size = 14);

    plt.show() # 展示图像

    三、分组聚合分析

    • 任务一:分析 distance_from_homefraud之间的关系,旨在协助反诈警务人员锁定诈骗集团的位置范围;

    • 任务二:分析 ratio_to_median_purchase_price近一次交易与以往交易价格中位数的比率 fraud 之间的关系,若比率增大,考虑有被电信诈骗的可能【这里假设比率超过10就有被骗的风险】。

    • 任务三:分析 repeat_retailer:交易是否发生在同一个商户fraud 之间的关系,假设一直在同一个商户进行交易,风险率最高。

    3.2 任务一:分析 distance_from_home与fraud之间的关系

    1
    2
    3
    4
    # 提取 'distance_from_home' 和 'fraud' 两列 创建新表 sub_data1
    sub_data1 = data[['distance_from_home', 'fraud']]
    print('查看sub_data1的形状:', sub_data1.shape)
    sub_data1.head(10)
    查看sub_data1的形状: (187403, 2)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    ## 可视化分析: `distance_from_home交易与家间的距离` 和 `fraud是否诈骗` 之间的关系

    # 构建两个子图
    f, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(10,4))

    # 设置柱状宽度
    bins = 30

    # 统计欺诈案例的交易金额
    ax1.hist(sub_data1["distance_from_home"][sub_data1["fraud"]== 1], bins = bins, color='#a7dbf7')
    ax1.set_title('与诈骗有关')
    ax1.set_ylabel('交易数量')

    # 统计正常案例的交易金额
    ax2.hist(sub_data1["distance_from_home"][sub_data1["fraud"]== 0], bins = bins, color='#e9a8f3')
    ax2.set_title('与诈骗无关')
    # 画坐标系
    plt.xlabel('距离')
    plt.ylabel('交易数量')
    plt.yscale('log')
    plt.show() # 展示图像

    3.2 任务二:分析 ratio_to_median_purchase_pricefraud之间的关系

    1
    2
    3
    4
    # 创建子表sub_data2 , 该表包含 ratio_to_median_purchase_price 和 fraud 两列
    sub_data2 = data[['ratio_to_median_purchase_price', 'fraud']]
    # 查看 sub_data2 的前5行
    sub_data2.head()
    1
    2
    # 查看 ratio_to_median_purchase_price 的 数据分布
    sub_data2.ratio_to_median_purchase_price.describe()
    count    187403.000000
    mean          3.565375
    std           4.653129
    min           0.007278
    25%           0.664047
    50%           1.841595
    75%           5.058910
    max         266.689692
    Name: ratio_to_median_purchase_price, dtype: float64
    
    1
    2
    3
    4
    5
    6
    7
    # 筛选出 ratio_to_median_purchase_price 中 大于 10 的数据,并分析他们的 fraud 的比例

    ratio = sub_data2[data['ratio_to_median_purchase_price'] > 10]

    print('查看表ratio的形状:', ratio.shape)

    ratio.head(10) # 查看 ratio的前十行
    查看表ratio的形状: (12103, 2)
    
    1
    2
    3
    4
    5
    6
    7
    8
    # 计算 表ratio中, fraud=0 以及 fraud=1的数量

    num_fraud_0 = ratio[ratio['fraud'] == 0]
    num_fraud_1 = ratio[ratio['fraud'] == 1]

    # 打印数值
    print('表ratio与诈骗无关的数据数量统计:', num_fraud_0.shape[0])
    print('表ratio与诈骗有关的数据数量统计:', num_fraud_1.shape[0])
    表ratio与诈骗无关的数据数量统计: 742
    表ratio与诈骗有关的数据数量统计: 11361
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 可视化分析:ratio_to_median_purchase_price近一次交易与以往交易价格中位数的比率 与 fraud 之间的关系

    # 数据
    labels = ['未被诈骗', '被诈骗']
    sizes = [num_fraud_0.shape[0], num_fraud_1.shape[0]]

    # 绘制饼图
    plt.pie(sizes, labels=labels,colors=['#B6A1DE','#97ece5'], autopct='%1.1f%%', textprops={'fontsize': 13},startangle=90)

    # 添加标题
    plt.title('`近一次交易与以往交易价格中位数的比率` 与 `fraud` 之间关系分布图',fontsize=15)

    # 显示图形
    plt.show()

    3.3 任务三:分析 repeat_retailerfraud之间的关系

    1
    2
    3
    4
    5
    6
    # 创建子表sub_data3 , 该表包含 repeat_retailer 和 fraud 两列

    sub_data3 = data[['repeat_retailer', 'fraud']]
    print('查看表sub_data3的形状:', sub_data3.shape)

    sub_data3.head(10) # 查看 表sub_data3
    1
    2
    # 查看 repeat_retailer 中的数据分布
    sub_data3.repeat_retailer.value_counts()
    1.0    165030
    0.0     22373
    Name: repeat_retailer, dtype: int64
    
    1
    2
    3
    # 统计 repeat_retailer 中的数据 fraud =1 的数据有多少条

    sub_data3['repeat_retailer'][sub_data3["fraud"] == 1].value_counts()
    1.0    76925
    0.0    10478
    Name: repeat_retailer, dtype: int64
    
    1
    2
    3
    # 统计 repeat_retailer 中的数据 fraud =0 的数据有多少条

    sub_data3['repeat_retailer'][sub_data3["fraud"] == 0].value_counts()
    1.0    88105
    0.0    11895
    Name: repeat_retailer, dtype: int64
    
    1
    2
    3
    4
    5
    6
    7
    8
    # 可视化分析:`repeat_retailer`是否与 `fraud` 诈骗有关
    fig = plt.figure(figsize=(16, 6))
    sns.distplot(sub_data3['repeat_retailer'][sub_data3["fraud"] == 1], bins=10)
    sns.distplot(sub_data3['repeat_retailer'][sub_data3["fraud"] == 0], bins=20)
    plt.xlabel('repeat_retailer与 fraud', fontsize=13)
    plt.title('repeat_retailer与 fraud关系分布图', fontsize=15)
    plt.xticks([0, 1])
    plt.show() # 展示图像

    Mysql

    1. 开启 MySQL 服务

    1
    2
    # 启动 MySQL 服务
    sudo systemctl start mysql

    2. 创建数据库 relation

    1
    2
    CREATE DATABASE IF NOT EXISTS relation;
    USE relation;

    3. 创建数据表 user 并导入数据

    navicat导入

    4. 创建数据表 friend 并导入数据

    navicat导入

    注意时间格式

    5. 分析不同用户的好友数并存储为视图 table1

    1
    2
    3
    4
    5
    6
    7
    USE relation;

    CREATE VIEW table1 AS
    SELECT u.user_name, COUNT(f.friend_id) AS f_num
    FROM user u
    LEFT JOIN friend f ON u.user_id = f.user_id
    GROUP BY u.user_id;

    6. 查找用户“系乐”的所有朋友信息并存储为视图 table2

    1
    2
    3
    4
    5
    6
    7
    8
    USE relation;

    CREATE VIEW table2 AS
    SELECT u1.user_name AS user_name, u2.user_name AS f_name
    FROM friend f
    JOIN user u1 ON f.user_id = u1.user_id
    JOIN user u2 ON f.friend_id = u2.user_id
    WHERE u1.user_name = '系乐';

    7. 查询用户的所有好友信息并存储为视图 table3

    1
    2
    3
    4
    5
    6
    7
    8
    USE relation;

    CREATE VIEW table3 AS
    SELECT u1.user_name AS user_name, GROUP_CONCAT(u2.user_name) AS f_name
    FROM friend f
    JOIN user u1 ON f.user_id = u1.user_id
    JOIN user u2 ON f.friend_id = u2.user_id
    GROUP BY u1.user_id;

    8. 查询“系乐”和“姚欣然”的共同好友信息并存储为视图 table4

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    USE relation;

    CREATE VIEW table4 AS
    SELECT
    u1.user_name AS user_name1,
    u2.user_name AS user_name2,
    f.friend_id
    FROM friend f
    JOIN user u1 ON f.user_id = u1.user_id
    JOIN user u2 ON f.friend_id = u2.user_id
    WHERE u1.user_name = '系乐' AND u2.user_name = '姚欣然';

    9. 进行社交网络挖掘并存储为视图 table5

    1
    2
    3
    4
    5
    6
    7
    8
    USE relation;

    CREATE VIEW table5 AS
    SELECT u.user_id, u.user_name
    FROM user u
    JOIN friend f1 ON u.user_id = f1.user_id
    JOIN friend f2 ON f1.friend_id = f2.user_id
    WHERE f2.friend_id = 2 AND u.user_id != 2;

    数据库安全管理

    以下是针对上述要求的操作步骤:

    1. 启动 MySQL 服务并查看服务状态

    1
    2
    3
    4
    5
    # 启动 MySQL 服务
    sudo systemctl start mysql

    # 查看 MySQL 服务状态
    sudo systemctl status mysql

    2. 创建用户 qingjiao

    1
    2
    3
    4
    5
    6
    7
    -- 使用 root 用户登录 MySQL
    mysql -u root -p

    -- 输入 root 用户密码:123456

    -- 创建新用户 qingjiao
    CREATE USER 'qingjiao'@'localhost' IDENTIFIED BY 'Qingjiao@qaz#123';

    3. 授予 qingjiao 用户在 datatest 库下的 CREATE 权限

    1
    2
    3
    4
    5
    -- 授予 CREATE 权限
    GRANT CREATE ON datatest.* TO 'qingjiao'@'localhost';

    -- 刷新权限
    FLUSH PRIVILEGES;

    4. 切换到 qingjiao 用户并创建数据库和表

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # 切换到 qingjiao 用户
    mysql -u qingjiao -p

    # 创建数据库 datatest
    CREATE DATABASE datatest;

    # 切换到 datatest 数据库
    USE datatest;

    # 创建 userinfo 表
    CREATE TABLE userinfo (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    age INT
    );

    # 插入示例数据
    INSERT INTO userinfo (name, age) VALUES ('张三', 28), ('李四', 22), ('王五', 35);

    # 查看插入的数据
    SELECT * FROM userinfo;