使用探索数据分析(EDA)笔记本探索预测模型的基于Web的数据

NOTE
数据科学Workspace不再可供购买。
本文档面向之前有权访问数据科学Workspace的现有客户。

探索性数据分析(EDA)笔记本旨在帮助您发现数据中的模式、检查数据完整性并总结预测模型的相关数据。

EDA笔记本示例以基于Web的数据为出发点进行了优化,该示例由两部分组成。 第一部分首先使用Query Service查看趋势和数据快照。 接下来,考虑到探索性数据分析的目标,在配置文件和访问者级别聚合数据。

第二部分从使用Python库对聚合数据执行描述性分析开始。 此笔记本展示一些可视化图表,如直方图、散点图、方框图和关联矩阵,从中可得出可用于确定哪些功能最可能有助于预测目标的可操作洞察。

快速入门

在阅读本指南之前,请查看用户指南🔗JupyterLab 了解数据科学工作区及其JupyterLab在数据科学工作区中的角色。此外,如果您使用的是自己的数据,请查看有关笔记本中 Jupyterlab 数据访问的文档。本指南包含有关笔记本数据限制的重要信息。

此笔记本使用Analytics Analysis Workspace中提供的Adobe Analytics Experience Events数据形式的midvalues数据集。 为了使用EDA笔记本,您需要定义数据表,使其具有下列值target_tabletarget_table_id。 可以使用任何midvalues数据集。

要查找这些值,请按照JupyterLab数据访问指南的写入python中的数据集部分中所述的步骤进行操作。 数据集名称(target_table)位于数据集目录中。 右键单击数据集以在笔记本中浏览或写入数据后,将在可执行代码项中提供数据集ID (target_table_id)。

数据发现

本节包含用于查看趋势的配置步骤和示例查询,例如“按用户活动排名前十的城市”或“查看次数排名前十的产品”。

库的配置

JupyterLab支持多个库。 可以将以下代码粘贴到代码单元格中并运行,以收集和安装此示例中使用的所有必需包。 您可以在本示例之外使用其他或替代包来进行您自己的数据分析。 有关支持的包列表,请将!pip list --format=columns复制并粘贴到新单元格中。

!pip install colorama
import chart_studio.plotly as py
import plotly.graph_objs as go
from plotly.offline import iplot
from scipy import stats
import numpy as np
import warnings
warnings.filterwarnings('ignore')
from scipy.stats import pearsonr
import matplotlib.pyplot as plt
from scipy.stats import pearsonr
import pandas as pd
import math
import re
import seaborn as sns
from datetime import datetime
import colorama
from colorama import Fore, Style
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
pd.set_option('display.width', 1000)
pd.set_option('display.expand_frame_repr', False)
pd.set_option('display.max_colwidth', -1)

连接到 Adobe Experience Platform Query Service

JupyterLabon Platform 允许您在笔记本中使用 Python SQL 通过查询服务🔗访问数据。由于其 Query Service 优越的运行时间,通过访问数据对于处理大型数据集非常有用。 请注意,使用 Query Service 查询数据的处理时间限制为十分钟。

在 中使用 Query Service 之前 JupyterLab, Query Service 请确保您对 SQL 语法有一定的了解。

为了在 JupyterLab 中使用查询服务,您必须首先在工作 Python 笔记本和查询服务之间创建连接。 这可以通过执行以下单元格来实现。

qs_connect()

定义用于探索的midvalues数据集

要开始查询和浏览数据,必须提供midvalues数据集表。 复制table_nametable_id值,并将其替换为您自己的数据表值。

target_table = "table_name"
target_table_id = "table_id"

完成后,此单元格应类似于以下示例:

target_table = "cross_industry_demo_midvalues"
target_table_id = "5f7c40ef488de5194ba0157a"

浏览数据集以查看可用日期

使用下面提供的单元格,您可以查看表中包含的日期范围。 探索天数、第一个日期和最后一个日期的目的是帮助选择日期范围以供进一步分析。

%%read_sql -c QS_CONNECTION
SELECT distinct Year(timestamp) as Year, Month(timestamp) as Month, count(distinct DAY(timestamp)) as Count_days, min(DAY(timestamp)) as First_date, max(DAY(timestamp)) as Last_date, count(timestamp) as Count_hits
from {target_table}
group by Month(timestamp), Year(timestamp)
order by Year, Month;

运行单元格会产生以下输出:

查询日期输出

配置数据集发现的日期

在确定数据集发现的可用日期后,需要更新以下参数。 此单元格中配置的日期仅用于查询形式的数据发现。 在本指南后面的探索性数据分析中,日期将再次更新到合适的范围。

target_year = "2020" ## The target year
target_month = "02" ## The target month
target_day = "(01,02,03)" ## The target days

数据集发现

配置完所有参数、启动Query Service并设定日期范围后,即可开始读取数据行。 您应该限制读取的行数。

from platform_sdk.dataset_reader import DatasetReader
from datetime import date
dataset_reader = DatasetReader(PLATFORM_SDK_CLIENT_CONTEXT, dataset_id=target_table_id)
# If you do not see any data or would like to expand the default date range, change the following query
Table = dataset_reader.limit(5).read()

要查看数据集中可用的列数,请使用以下单元格:

print("\nNumber of columns:",len(Table.columns))

要查看数据集的行,请使用以下单元格。 在此示例中,行数限制为5。

Table.head(5)

表行输出

了解数据集中包含哪些数据后,进一步划分数据集会很有价值。 在此示例中,列出了每个列的列名和数据类型,而输出用于检查数据类型是否正确。

ColumnNames_Types = pd.DataFrame(Table.dtypes)
ColumnNames_Types = ColumnNames_Types.reset_index()
ColumnNames_Types.columns = ["Column_Name", "Data_Type"]
ColumnNames_Types

列名和数据类型列表

数据集趋势探究

以下部分包含四个用于探索数据趋势和模式的示例查询。 下面提供的示例并非详尽无遗,但涵盖了一些更常见的功能。

给定日期的​ 小时活动计数

此查询分析一天内操作和点击的次数。 输出以表的形式表示,其中包含一天中每个小时的活动计数量度。

%%read_sql query_2_df -c QS_CONNECTION

SELECT Substring(timestamp, 12, 2)                        AS Hour,
       Count(enduserids._experience.aaid.id) AS Count
FROM   {target_table}
WHERE  Year(timestamp) = {target_year}
       AND Month(timestamp) = {target_month}
       AND Day(timestamp) in {target_day}
GROUP  BY Hour
ORDER  BY Hour;

查询1输出

确认查询工作后,数据可以呈现在单变量直方图中,以便更加清晰地显示。

trace = go.Bar(
    x = query_2_df['Hour'],
    y = query_2_df['Count'],
    name = "Activity Count"
)

layout = go.Layout(
    title = 'Activity Count by Hour of Day',
    width = 1200,
    height = 600,
    xaxis = dict(title = 'Hour of Day'),
    yaxis = dict(title = 'Count')
)

fig = go.Figure(data = [trace], layout = layout)
iplot(fig)

查询1 的条形图输出

给定日期查看的前10个页面

此查询分析给定日期查看次数最多的页面。 输出以表格的形式表示,其中包含有关页面名称和页面查看计数的指标。

%%read_sql query_4_df -c QS_CONNECTION

SELECT web.webpagedetails.name                 AS Page_Name,
       Sum(web.webpagedetails.pageviews.value) AS Page_Views
FROM   {target_table}
WHERE  Year(timestamp) = {target_year}
       AND Month(timestamp) = {target_month}
       AND Day(timestamp) in {target_day}
GROUP  BY web.webpagedetails.name
ORDER  BY page_views DESC
LIMIT  10;

确认查询有效后,数据可以用单变量图直方图中显示,以便直观地显示。

trace = go.Bar(
    x = query_4_df['Page_Name'],
    y = query_4_df['Page_Views'],
    name = "Page Views"
)

layout = go.Layout(
    title = 'Top Ten Viewed Pages For a Given Day',
    width = 1000,
    height = 600,
    xaxis = dict(title = 'Page_Name'),
    yaxis = dict(title = 'Page_Views')
)

fig = go.Figure(data = [trace], layout = layout)
iplot(fig)

查看次数前十的页面

按用户活动分组的前十个城市

此查询分析数据来自哪些城市。

%%read_sql query_6_df -c QS_CONNECTION

SELECT concat(placeContext.geo.stateProvince, ' - ', placeContext.geo.city) AS state_city,
       Count(timestamp)                                                     AS Count
FROM   {target_table}
WHERE  Year(timestamp) = {target_year}
       AND Month(timestamp) = {target_month}
       AND Day(timestamp) in {target_day}
GROUP  BY state_city
ORDER  BY Count DESC
LIMIT  10;

确认查询工作后,数据可以呈现在单变量直方图中,以便更加清晰地显示。

trace = go.Bar(
    x = query_6_df['state_city'],
    y = query_6_df['Count'],
    name = "Activity by City"
)

layout = go.Layout(
    title = 'Top Ten Cities by User Activity',
    width = 1200,
    height = 600,
    xaxis = dict(title = 'City'),
    yaxis = dict(title = 'Count')
)

fig = go.Figure(data = [trace], layout = layout)
iplot(fig)

前十个城市

查看的十大产品

此查询提供查看的前10个产品的列表。 在下面的示例中,Explode()函数用于将productlistitems对象中的每个产品返回到其自己的行。 这样,您就可以执行嵌套查询来聚合不同SKU的产品视图。

%%read_sql query_7_df -c QS_CONNECTION

SELECT Product_List_Items.sku AS Product_SKU,
       Sum(Product_Views) AS Total_Product_Views
FROM  (SELECT Explode(productlistitems) AS Product_List_Items,
              commerce.productviews.value   AS Product_Views
       FROM   {target_table}
       WHERE  Year(timestamp) = {target_year}
              AND Month(timestamp) = {target_month}
              AND Day(timestamp) in {target_day}
              AND commerce.productviews.value IS NOT NULL)
GROUP BY Product_SKU
ORDER BY Total_Product_Views DESC
LIMIT  10;

在确认查询工作之后,数据可以在单变量绘图直方图中呈现,以便直观地清晰显示。

trace = go.Bar(
    x = "SKU-" + query_7_df['Product_SKU'],
    y = query_7_df['Total_Product_Views'],
    name = "Product View"
)

layout = go.Layout(
    title = 'Top Ten Viewed Products',
    width = 1200,
    height = 600,
    xaxis = dict(title = 'SKU'),
    yaxis = dict(title = 'Product View Count')
)

fig = go.Figure(data = [trace], layout = layout)
iplot(fig)

十大产品视图

在探索数据的趋势和模式后,您应该清楚知道要为预测目标而构建哪些功能。 快速浏览表格可以快速突出显示每个数据属性的形式、明显的错误表示和值中的大型离群值,并开始建议候选关系以探索属性之间的关系。

探索性数据分析

探索性数据分析用于完善您对数据的理解,并为可以用作建模基础的引人注目的问题建立直觉。

完成数据发现步骤后,您将在事件级别浏览事件级别数据以及事件、城市或用户 ID 级别的一些聚合,以查看一天的趋势。 尽管这些数据很重要,但它并不能提供全貌。 您仍然不了解是什么促使您的网站上进行了购买。

要了解这一点,您需要在配置文件/访问者级别聚合数据,定义购买目标,并应用统计概念,如相关性、框图和散点图。 这些方法用于在您定义的预测窗口中比较买方与非买方的活动模式。

本节将创建并探索以下功能:

  • COUNT_UNIQUE_PRODUCTS_PURCHASED:购买的唯一产品数量。
  • COUNT_CHECK_OUTS:签出次数。
  • COUNT_PURCHASES:购买次数。
  • COUNT_INSTANCE_PRODUCTADDS:产品添加实例的数量。
  • NUMBER_VISITS:访问次数。
  • COUNT_PAID_SEARCHES:付费搜索数。
  • DAYS_SINCE_VISIT:自上次访问以来的天数。
  • TOTAL_ORDER_REVENUE:订单总收入。
  • DAYS_SINCE_PURCHASE:自上次购买以来的天数。
  • AVG_GAP_BETWEEN_ORDERS_DAYS:购买之间的平均间隔(以天为单位)。
  • STATE_CITY:包含州和城市。

在继续数据聚合之前,需要定义用于探索性数据分析中的预测变量的参数。 换句话说,您希望从数据科学模型中得到什么? 常用参数包括目标、预测周期和分析周期。

如果您正在使用EDA笔记本,则需要在继续之前替换以下值。

goal = "commerce.`order`.purchaseID" #### prediction variable
goal_column_type = "numerical" #### choose either "categorical" or "numerical"
prediction_window_day_start = "2020-01-01" #### YYYY-MM-DD
prediction_window_day_end = "2020-01-31" #### YYYY-MM-DD
analysis_period_day_start = "2020-02-01" #### YYYY-MM-DD
analysis_period_day_end = "2020-02-28" #### YYYY-MM-DD

### If the goal is a categorical goal then select threshold for the defining category and creating bins. 0 is no order placed, and 1 is at least one order placed:
threshold = 1

用于创建功能和目标的数据聚合

要开始探索性分析,您需要在用户档案级别创建目标,然后聚合数据集。 在此示例中,提供了两个查询。 第一个查询包含创建目标。 第二个查询需要更新以包括除第一个查询中的变量以外的任何变量。 您可能想要更新查询的limit。 在执行以下查询后,聚合数据现在可用于探索。

%%read_sql target_df -d -c QS_CONNECTION

SELECT DISTINCT endUserIDs._experience.aaid.id                  AS ID,
       Count({goal})                                            AS TARGET
FROM   {target_table}
WHERE DATE(TIMESTAMP) BETWEEN '{prediction_window_day_start}' AND '{prediction_window_day_end}'
GROUP BY endUserIDs._experience.aaid.id;
%%read_sql agg_data -d -c QS_CONNECTION

SELECT z.*, z1.state_city as STATE_CITY
from
((SELECT y.*,a2.AVG_GAP_BETWEEN_ORDERS_DAYS as AVG_GAP_BETWEEN_ORDERS_DAYS
from
(select a1.*, f.DAYS_SINCE_PURCHASE as DAYS_SINCE_PURCHASE
from
(SELECT DISTINCT a.ID  AS ID,
COUNT(DISTINCT Product_Items.SKU) as COUNT_UNIQUE_PRODUCTS_PURCHASED,
COUNT(a.check_out) as COUNT_CHECK_OUTS,
COUNT(a.purchases) as COUNT_PURCHASES,
COUNT(a.product_list_adds) as COUNT_INSTANCE_PRODUCTADDS,
sum(CASE WHEN a.search_paid = 'TRUE' THEN 1 ELSE 0 END) as COUNT_PAID_SEARCHES,
DATEDIFF('{analysis_period_day_end}', MAX(a.date_a)) as DAYS_SINCE_VISIT,
ROUND(SUM(Product_Items.priceTotal * Product_Items.quantity), 2) AS TOTAL_ORDER_REVENUE
from
(SELECT endUserIDs._experience.aaid.id as ID,
commerce.`checkouts`.value as check_out,
commerce.`order`.purchaseID as purchases,
commerce.`productListAdds`.value as product_list_adds,
search.isPaid as search_paid,
DATE(TIMESTAMP) as date_a,
Explode(productlistitems) AS Product_Items
from {target_table}
Where DATE(TIMESTAMP) BETWEEN '{analysis_period_day_start}' AND '{analysis_period_day_end}') as a
group by a.ID) as a1
left join
(SELECT DISTINCT endUserIDs._experience.aaid.id as ID,
DATEDIFF('{analysis_period_day_end}', max(DATE(TIMESTAMP))) as DAYS_SINCE_PURCHASE
from {target_table}
where DATE(TIMESTAMP) BETWEEN '{analysis_period_day_start}' AND '{analysis_period_day_end}'
and commerce.`order`.purchaseid is not null
GROUP BY endUserIDs._experience.aaid.id) as f
on f.ID = a1.ID
where a1.COUNT_PURCHASES>0) as y
left join
(select ab.ID, avg(DATEDIFF(ab.ORDER_DATES, ab.PriorDate)) as AVG_GAP_BETWEEN_ORDERS_DAYS
from
(SELECT distinct endUserIDs._experience.aaid.id as ID, TO_DATE(DATE(TIMESTAMP)) as ORDER_DATES,
TO_DATE(LAG(DATE(TIMESTAMP),1) OVER (PARTITION BY endUserIDs._experience.aaid.id ORDER BY DATE(TIMESTAMP))) as PriorDate
FROM {target_table}
where DATE(TIMESTAMP) BETWEEN '{analysis_period_day_start}' AND '{analysis_period_day_end}'
AND commerce.`order`.purchaseid is not null) AS ab
where ab.PriorDate is not null
GROUP BY ab.ID) as a2
on a2.ID = y.ID) z
left join
(select t.ID, t.state_city from
(
SELECT DISTINCT endUserIDs._experience.aaid.id as ID,
concat(placeContext.geo.stateProvince, ' - ', placeContext.geo.city) as state_city,
ROW_NUMBER() OVER(PARTITION BY endUserIDs._experience.aaid.id ORDER BY DATE(TIMESTAMP) DESC) AS ROWNUMBER
FROM   {target_table}
WHERE  DATE(TIMESTAMP) BETWEEN '{analysis_period_day_start}' AND '{analysis_period_day_end}') as t
where t.ROWNUMBER = 1) z1
on z.ID = z1.ID)
limit 500000;

将聚合数据集中的功能与目标合并

以下单元格用于将上例中概述的聚合数据集中的功能与您的预测目标合并。

Data = pd.merge(agg_data,target_df, on='ID',how='left')
Data['TARGET'].fillna(0, inplace=True)

下面三个示例单元格用于确保合并成功。

Data.shape返回列数后跟行数,例如: (11913, 12)。

Data.shape

Data.head(5)返回一个包含5行数据的表。 返回的表包含映射到用户档案ID的所有12列聚合数据。

Data.head(5)

示例表

此单元格打印唯一配置文件的数量。

print("Count of unique profiles:", (len(Data)))

检测缺少的值和离群值

完成数据聚合并将其与目标合并后,您需要查看有时称为数据运行状况检查的数据。

此过程涉及识别缺少的值和离群值。 确定问题后,下一个任务是提出处理这些问题的具体策略。

NOTE
在此步骤中,您可能会发现值损坏,这可能表示数据记录过程中出现了故障。
Missing = pd.DataFrame(round(Data.isnull().sum()*100/len(Data),2))
Missing.columns =['Percentage_missing_values']
Missing['Features'] = Missing.index

以下单元格用于显示缺少的值。

trace = go.Bar(
    x = Missing['Features'],
    y = Missing['Percentage_missing_values'],
    name = "Percentage_missing_values")

layout = go.Layout(
    title = 'Missing values',
    width = 1200,
    height = 600,
    xaxis = dict(title = 'Features'),
    yaxis = dict(title = 'Percentage of missing values')
)

fig = go.Figure(data = [trace], layout = layout)
iplot(fig)

缺少值

在检测到缺失值后,识别异常值至关重要。 参数统计量如平均值、标准差和相关性对异常值高度敏感。 此外,常见的统计程序(如线性回归)的假设也基于这些统计。 这意味着,离群值可能真的会扰乱分析。

为了识别离群值,此示例使用四分位数之间的范围。 四分位数范围(IQR)是指介于第一个和第三个四分位数(第25个和第75个百分位数)之间的范围。 此示例收集的所有数据点要么位于第25百分位数以下IQR的1.5倍,要么位于第75百分位数以上IQR的1.5倍。 属于其中任一情况的值在后续单元格中定义为离群值。

TIP
纠正离群值需要您了解您从事的业务和行业。 有时,您不能仅仅因为观察值是异常值而放弃观察值。 异常值可以是合理的观察值,并且通常是最有趣的观察值。 要了解有关删除异常值的更多信息,请访问 可选的数据清理步骤
TARGET = Data.TARGET

Data_numerical = Data.select_dtypes(include=['float64', 'int64'])
Data_numerical.drop(['TARGET'],axis = 1,inplace = True)
Data_numerical1 = Data_numerical

for i in range(0,len(Data_numerical1.columns)):
    Q1 = Data_numerical1.iloc[:,i].quantile(0.25)
    Q3 = Data_numerical1.iloc[:,i].quantile(0.75)
    IQR = Q3 - Q1
    Data_numerical1.iloc[:,i] = np.where(Data_numerical1.iloc[:,i]<(Q1 - 1.5 * IQR),np.nan, np.where(Data_numerical1.iloc[:,i]>(Q3 + 1.5 * IQR),
                                                                                                    np.nan,Data_numerical1.iloc[:,i]))

Outlier = pd.DataFrame(round(Data_numerical1.isnull().sum()*100/len(Data),2))
Outlier.columns =['Percentage_outliers']
Outlier['Features'] = Outlier.index

与往常一样,可视化结果很重要。

trace = go.Bar(
    x = Outlier['Features'],
    y = Outlier['Percentage_outliers'],
    name = "Percentage_outlier")

layout = go.Layout(
    title = 'Outliers',
    width = 1200,
    height = 600,
    xaxis = dict(title = 'Features'),
    yaxis = dict(title = 'Percentage of outliers')
)

fig = go.Figure(data = [trace], layout = layout)
iplot(fig)

异常值图

单变量分析

更正数据的缺失值和异常值后,即可开始分析。 有三种类型的分析:单变量、双变量和多变量分析。 单变量分析使用单变量关系获取数据、总结和查找数据中的模式。 双变量分析一次查看多个变量,而多变量分析一次查看三个或更多变量。

下面的示例生成一个表以可视化特征的分布。

Data_numerical = Data.select_dtypes(include=['float64', 'int64'])
distribution = pd.DataFrame([Data_numerical.count(),Data_numerical.mean(),Data_numerical.quantile(0), Data_numerical.quantile(0.01),
                             Data_numerical.quantile(0.05),Data_numerical.quantile(0.25), Data_numerical.quantile(0.5),
                        Data_numerical.quantile(0.75),  Data_numerical.quantile(0.95),Data_numerical.quantile(0.99), Data_numerical.max()])
distribution = distribution.T
distribution.columns = ['Count', 'Mean', 'Min', '1st_perc','5th_perc','25th_perc', '50th_perc','75th_perc','95th_perc','99th_perc','Max']
distribution

功能的分发

功能分布完毕后,即可使用数组创建可视化数据图表。 以下单元格用于使用数值数据可视化上表。

A = sns.palplot(sns.color_palette("Blues"))
for column in Data_numerical.columns[0:]:
    plt.figure(figsize=(5, 4))
    plt.ticklabel_format(style='plain', axis='y')
    sns.distplot(Data_numerical[column], color = A, kde=False, bins=6, hist_kws={'alpha': 0.4});

数值数据图

分类数据

分组分类数据用于了解聚集数据的每个列及其分布中包含的值。 此示例使用前10个类别来帮助绘制分配。 必须指出的是,列中包含的数千个唯一值。 你不想让一个杂乱的阴谋变得难以辨认。 根据您的业务目标,分组数据可产生更有意义的结果。

Data_categorical = Data.select_dtypes(include='object')
Data_categorical.drop(['ID'], axis = 1, inplace = True, errors = 'ignore')
for column in Data_categorical.columns[0:]:
    if (len(Data_categorical[column].value_counts())>10):
        plt.figure(figsize=(12, 8))
        sns.countplot(x=column, data = Data_categorical, order = Data_categorical[column].value_counts().iloc[:10].index, palette="Set2");
    else:
        plt.figure(figsize=(12, 8))
        sns.countplot(x=column, data = Data_categorical, palette="Set2");

类别列

删除仅具有一个非重复值的列

仅具有值 1 的列不会向分析添加任何信息,可以删除。

for col in Data.columns:
    if len(Data[col].unique()) == 1:
        if col == 'TARGET':
            print(Fore.RED + '\033[1m' + 'WARNING: TARGET HAS A SINGLE UNIQUE VALUE, ANY BIVARIATE ANALYSIS (NEXT STEP IN THIS NOTEBOOK) OR PREDICTION WILL BE MEANINGLESS' + Fore.RESET + '\x1b[21m')
        elif col == 'ID':
            print(Fore.RED + '\033[1m' + 'WARNING: THERE IS ONLY ONE PROFILE IN THE DATA, ANY BIVARIATE ANALYSIS (NEXT STEP IN THIS NOTEBOOK) OR PREDICTION WILL BE MEANINGLESS' + Fore.RESET + '\x1b[21m')
        else:
            print('Dropped column:',col)
            Data.drop(col,inplace=True,axis=1)

删除单值列后,在新单元格中使用Data.columns命令检查其余列是否有任何错误。

更正缺少的值

下一节包含一些对缺失值进行更正的示例方法。 事件,虽然在上面的数据中,只有一列缺少值,但下面这些示例单元格为所有数据类型提供了正确的值。 其中包括:

  • 数值数据类型:输入 0 或最大值(如适用)
  • 分类数据类型:输入模态值
#### Select only numerical data
Data_numerical = Data.select_dtypes(include=['float64', 'int64'])

#### For columns that contain days we impute max days of history for null values, for rest all we impute 0

# Imputing days with max days of history
Days_cols = [col for col in Data_numerical.columns if 'DAYS_' in col]
d1 = datetime.strptime(analysis_period_day_start, "%Y-%m-%d")
d2 = datetime.strptime(analysis_period_day_end, "%Y-%m-%d")
A = abs((d2 - d1).days)

for column in Days_cols:
    Data[column].fillna(A, inplace=True)

# Imputing 0
Data_numerical = Data.select_dtypes(include=['float64', 'int64'])
Missing_numerical = Data_numerical.columns[Data_numerical.isnull().any()].tolist()

for column in Missing_numerical:
    Data[column].fillna(0, inplace=True)
#### Correct for missing values in categorical columns (Replace with mode)
Data_categorical = Data.select_dtypes(include='object')
Missing_cat = Data_categorical.columns[Data_categorical.isnull().any()].tolist()
for column in Missing_cat:
    Data[column].fillna(Data[column].mode()[0], inplace=True)

完成后,干净的数据就可以进行双变量分析了。

二元分析

二元分析用于帮助了解两组值(如特征和目标变量)之间的关系。 由于不同的图形适用于分类和数字数据类型,因此应分别针对每种数据类型进行此分析。 建议使用以下图表进行双变量分析:

  • 相关性:相关系数是两个特征之间关系强度的度量。 相关值介于–1和1之间,其中:1表示强正关系,-1表示强负关系,而结果为0则表示完全没关系。
  • 对图:对图是一种直观显示每个变量之间关系的简单方法。 它生成数据中每个变量之间的关系矩阵。
  • 热图:热图是数据集中所有变量的相关系数。
  • 框图:框图是一种基于五个数字汇总(最小值、第一个四分位数(Q1)、中间值、第三个四分位数(Q3)和最大值)来显示数据分布的标准化方式。
  • 计数图:计数图类似于某些分类特征的直方图或条形图。 它根据特定类别显示项目的发生次数。

为了了解“目标”变量与预测器/功能之间的关系,会根据数据类型使用图表。 对于数字功能,如果“目标”变量是分类变量,则应该使用方框图;如果“目标”变量是数字,则应该使用配对图和热图。

对于分类功能,如果“目标”变量是分类的,您应该使用计数图;如果“目标”变量是数字,您应该使用方框图。 使用这些方法有助于了解关系。 这些关系可以是特征或预测值和目标的形式。

数值预测值

if len(Data) == 1:
    print(Fore.RED + '\033[1m' + 'THERE IS ONLY ONE PROFILE IN THE DATA, BIVARIATE ANALYSIS IS NOT APPLICABLE, PLEASE INCLUDE AT LEAST ONE MORE PROFILE TO DO BIVARIATE ANALYSIS')
elif len(Data['TARGET'].unique()) == 1:
    print(Fore.RED + '\033[1m' + 'TARGET HAS A SINGLE UNIQUE VALUE, BIVARIATE ANALYSIS IS NOT APPLICABLE, PLEASE INCLUDE PROFILES WITH ATLEAST ONE DIFFERENT VALUE OF TARGET TO DO BIVARIATE ANALYSIS')
else:
    if (goal_column_type == "categorical"):
        TARGET_categorical = pd.DataFrame(np.where(TARGET>=threshold,"1","0"))
        TARGET_categorical.rename(columns={TARGET_categorical.columns[0]: "TARGET_categorical" }, inplace = True)
        Data_numerical = Data.select_dtypes(include=['float64', 'int64'])
        Data_numerical.drop(['TARGET'],inplace=True,axis=1)
        Data_numerical = pd.concat([Data_numerical, TARGET_categorical.astype(int)], axis = 1)
        ncols_for_charts = len(Data_numerical.columns)-1
        nrows_for_charts = math.ceil(ncols_for_charts/4)
        fig, axes = plt.subplots(nrows=nrows_for_charts, ncols=4, figsize=(18, 15))
        for idx, feat in enumerate(Data_numerical.columns[:-1]):
            ax = axes[int(idx // 4), idx % 4]
            sns.boxplot(x='TARGET_categorical', y=feat, data=Data_numerical, ax=ax)
            ax.set_xlabel('')
            ax.set_ylabel(feat)
            fig.tight_layout();
    else:
        Data_numerical = Data.select_dtypes(include=['float64', 'int64'])
        TARGET = pd.DataFrame(Data_numerical.TARGET)
        Data_numerical = Data.select_dtypes(include=['float64', 'int64'])
        Data_numerical.drop(['TARGET'],inplace=True,axis=1)
        Data_numerical = pd.concat([Data_numerical, TARGET.astype(int)], axis = 1)
        for i in Data_numerical.columns[:-1]:
            sns.pairplot(x_vars=i, y_vars=['TARGET'], data=Data_numerical, height = 4)
        f, ax = plt.subplots(figsize = (10,8))
        corr = Data_numerical.corr()

运行单元格将产生以下输出:

绘图

热图

类别预测值

以下示例用于绘制和查看每个分类变量前10个类别的频率图。

if len(Data) == 1:
    print(Fore.RED + '\033[1m' + 'THERE IS ONLY ONE PROFILE IN THE DATA, BIVARIATE ANALYSIS IS NOT APPLICABLE, PLEASE INCLUDE AT LEAST ONE MORE PROFILE TO DO BIVARIATE ANALYSIS')
elif len(Data['TARGET'].unique()) == 1:
    print(Fore.RED + '\033[1m' + 'TARGET HAS A SINGLE UNIQUE VALUE, BIVARIATE ANALYSIS IS NOT APPLICABLE, PLEASE INCLUDE PROFILES WITH ATLEAST ONE DIFFERENT VALUE OF TARGET TO DO BIVARIATE ANALYSIS')
else:
    if (goal_column_type == "categorical"):
        TARGET_categorical = pd.DataFrame(np.where(TARGET>=threshold,"1","0"))
        TARGET_categorical.rename(columns={TARGET_categorical.columns[0]: "TARGET_categorical" }, inplace = True)
        Data_categorical = Data.select_dtypes(include='object')
        Data_categorical.drop(["ID"], axis =1, inplace = True)
        Cat_columns = Data_categorical
        Data_categorical = pd.concat([TARGET_categorical,Data_categorical], axis =1)
        for column in Cat_columns.columns:
            A = Data_categorical[column].value_counts().iloc[:10].index
            Data_categorical1 = Data_categorical[Data_categorical[column].isin(A)]
            plt.figure(figsize=(12, 8))
            sns.countplot(x="TARGET_categorical",hue=column, data = Data_categorical1, palette = 'Blues')
            plt.xlabel("GOAL")
            plt.ylabel("COUNT")
            plt.show();
    else:
        Data_categorical = Data.select_dtypes(include='object')
        Data_categorical.drop(["ID"], axis =1, inplace = True)
        Target = Data.TARGET
        Data_categorical = pd.concat([Data_categorical,Target], axis =1)
        for column in Data_categorical.columns[:-1]:
            A = Data_categorical[column].value_counts().iloc[:10].index
            Data_categorical1 = Data_categorical[Data_categorical[column].isin(A)]
            sns.catplot(x=column, y="TARGET", kind = "boxen", data =Data_categorical1, height=5, aspect=13/5);

运行单元格将产生以下输出:

类别关系

重要数字特征

使用相关性分析,可以创建前10个重要数字特征的列表。 这些特征都可以用于预测“目标”特征。 此列表可用作开始构建模型时的特征列表。

if len(Data) == 1:
    print(Fore.RED + '\033[1m' + 'THERE IS ONLY ONE PROFILE IN THE DATA, BIVARIATE ANALYSIS IS NOT APPLICABLE, PLEASE INCLUDE AT LEAST ONE MORE PROFILE TO FIND IMPORTANT VARIABLES')
elif len(Data['TARGET'].unique()) == 1:
    print(Fore.RED + '\033[1m' + 'TARGET HAS A SINGLE UNIQUE VALUE, BIVARIATE ANALYSIS IS NOT APPLICABLE, PLEASE INCLUDE PROFILES WITH ATLEAST ONE DIFFERENT VALUE OF TARGET TO FIND IMPORTANT VARIABLES')
else:
    Data_numerical = Data.select_dtypes(include=['float64', 'int64'])
    Correlation = pd.DataFrame(Data_numerical.drop("TARGET", axis=1).apply(lambda x: x.corr(Data_numerical.TARGET)))
    Correlation['Corr_abs'] = abs(Correlation)
    Correlation = Correlation.sort_values(by = 'Corr_abs', ascending = False)
    Imp_features = pd.DataFrame(Correlation.index[0:10])
    Imp_features.rename(columns={0:'Important Feature'}, inplace=True)
    print(Imp_features)

重要功能

示例分析

当您在分析数据的过程中,发现洞察是很常见的事。 以下示例是一个见解,该见解映射了目标事件的回访间隔和货币值。

# Proxy for monetary value is TOTAL_ORDER_REVENUE and proxy for frequency is NUMBER_VISITS
if len(Data) == 1:
    print(Fore.RED + '\033[1m' + 'THERE IS ONLY ONE PROFILE IN THE DATA, INSIGHTS ANALYSIS IS NOT APPLICABLE, PLEASE INCLUDE AT LEAST ONE MORE PROFILE TO FIND IMPORTANT VARIABLES')
elif len(Data['TARGET'].unique()) == 1:
    print(Fore.RED + '\033[1m' + 'TARGET HAS A SINGLE UNIQUE VALUE, INSIGHTS ANALYSIS IS NOT APPLICABLE, PLEASE INCLUDE PROFILES WITH ATLEAST ONE DIFFERENT VALUE OF TARGET TO FIND IMPORTANT VARIABLES')
else:
    sns.lmplot("DAYS_SINCE_VISIT", "TOTAL_ORDER_REVENUE", Data, hue="TARGET", fit_reg=False);

示例分析

可选的数据清理步骤 optional-data-clean

纠正离群值需要您了解您从事的业务和行业。 有时,您不能仅仅因为观察值是异常值而放弃观察值。 离群值可能是合理的观察结果,通常是最有趣的观察结果。

有关离群值以及是否删除离群值的详细信息,请从分析因子中读取此条目。

以下示例单元格大写值和大写值数据点是使用四分位数范围的离群值。

TARGET = Data.TARGET

Data_numerical = Data.select_dtypes(include=['float64', 'int64'])
Data_numerical.drop(['TARGET'],axis = 1,inplace = True)

for i in range(0,len(Data_numerical.columns)):
    Q1 = Data_numerical.iloc[:,i].quantile(0.25)
    Q3 = Data_numerical.iloc[:,i].quantile(0.75)
    IQR = Q3 - Q1
    Data_numerical.iloc[:,i] = np.where(Data_numerical.iloc[:,i]<(Q1 - 1.5 * IQR), (Q1 - 1.5 * IQR), np.where(Data_numerical.iloc[:,i]>(Q3 + 1.5 * IQR),
                                                                                                     (Q3 + 1.5 * IQR),Data_numerical.iloc[:,i]))
Data_categorical = Data.select_dtypes(include='object')
Data = pd.concat([Data_categorical, Data_numerical, TARGET], axis = 1)

后续步骤

完成探索性数据分析后,您就可以开始创建模型了。 或者,可以使用派生的数据和见解,使用 Power BI 等工具创建仪表板。

Adobe Experience Platform 将模型创建过程分为两个不同的阶段:配方(模型实例)和模型。 要开始配方创建过程,请访问在 JupyerLab 笔记本🔗中创建配方的文档。本文档包含有关在笔记本中创建 JupyterLab 、训练和评分(一个配方)的信息和示例。

recommendation-more-help
cc79fe26-64da-411e-a6b9-5b650f53e4e9