【数据挖掘】国科大刘莹老师数据挖掘课程作业 —— 第一次作业

homewrok 1

1. 假定数据仓库中包含 4 个维:date, product, vendor, location;和两个度量:sales_volume 和 sales_cost。

(a) 画出该数据仓库的星形模式

在这里插入图片描述

图 1    星形模式图

(b) 由基本方体 [date, product, vendor, location] 开始,列出每年在 Los Angles 的每个 vendor 的 sales_volume。

roll up on date from date_key to year
roll up on product from product_key to number
roll up on location from location_key to city
dice with 'city=Los Angles'

© 对于数据仓库,位图索引是有用的。以该立方体为例,简略讨论使用位图索引结构的优点和问题。

以 vendor 表中的 gender 和 marital_status 为例。假设前 4 个 vendor 的 gender 和 marital_status 取值如表 1 1 1 所示,gender 取值为 ”male“ 和 ”female“,marital_status 取值为 ”unmarried“,”married“ 和 ”divorce“,二者对应的 bitmap index 分别如表 2 2 2 和表 3 3 3 所示。

row_id\attributiongendermarital_status
0maledivorce
1femaleunmarried
2femalemarried
3maledivorce

表 1    前 4 个 vendor 对应的 gender 和 marital_status

row_id\valuemalefemale
010
101
201
310

表 2    gender 对应的 bitmap indx

row_id\valueunmarriedmarrieddivorce
0001
1100
2010
3001

表 3    marital_status 对应的 bitmap indx

可见,gender 为 ”male“ 对应的索引值为 10,”female“ 对应的索引值为 01,marital_status 为 ”unmarried“ 对应的索引值为 100,”married“ 对应的索引值为 010,”divorce“ 对应的索引值为 001

将两个 bitmap index 表(顺次)拼接后,0 号 vendor 对应的 index 为 100011 号 vendor 对应的 index 为 011002 号 vendor 对应的 index 为 010103 号 vendor 对应的 index 为 10001

想要查询满足 gender=”female“ 且 martial_status=”unmarried“ 的 vendor,那么只需要让每个 vendor 对应的 index 与 01100 按位相与,结果仍然为 01100,说明该 vendor 满足条件。

优点:

bitmap indx 存储的是每一行数据是否满足一个条件,即用一个二进制位表示该条件是否成立。当需要查询数据满足某些条件时,可以将这些条件的 bitmap index 进行逻辑运算,从而快速得到结果。因此,bitmap index 可以大大提高查询效率。直观上,bitmap index 只存储二进制位,不存储具体的值。因此,它能够节省大量的存储空间提高存储效率

缺点:

① 适用场景有限:通过上面的例子可以看出,bitmap index 适用于表中取值为离散值的属性列,如果需要处理连续数据(比如,unit_price、ID_number 等),则需要先进行离散化处理,而离散化处理的质量依赖于离散化的粒度,可以想象到,离散粒度过大(粗),本质不同的区间可能被划分为同一类,离散粒度过小(细),划分的区间数过多,index 表出现稀疏问题,导致存储效率低下。因此,bitmap index 处理连续数据是比较困难的。另外,如果一个离散属性列的取值本来就很多,这会出现与对连续数据进行细粒度的离散化时相同的问题——存储效率低下

② 更新开销较大:当 bitmap index 对应的属性列发生更新时,需要重新计算每个二进制位的值,这会引起一定的开销。特别是对于频繁更新的列,bitmap index 的维护成本会很高。因此,bitmap index 适用于静态数据。

2.假设一家医院对 18 名随机选择的成年人的年龄和体脂数据进行了测试,结果如下:

id012345678
age232327273941474950
%fat9.526.57.817.831.425.927.427.231.2
id91011121314151617
age525454565758586061
%fat34.642.528.833.430.234.132.941.235.7

(a) 计算年龄和脂肪百分比的平均值、中位数和标准差。

保留四位小数结果如表 4 4 4 所示。

meanmedianstd
age46.444451.000013.2186
%fat28.783330.70009.2544

表 4    均值、中位数和标准差

(b) 绘制年龄和脂肪百分比的箱线图。

对于年龄,直接计算得到的最小值、上四分位数(Q1)、中位数、下四分位数(Q3)、最大值分别为:23、39.5、51、56.75、61。由于可能存在最大值超过 Q3+1.5×(Q3-Q1) 或者最小值不到 Q1-1.5×(Q3-Q1) 的情况,所以可能需要修正。经过测试,无需修正。

对于脂肪百分比,直接计算得到的最小值、上四分位数(Q1)、中位数、下四分位数(Q3)、最大值分别为:7.8、26.675、30.7、33.925、42.5。经过测试发现需要修正,修正后的最小值为 15.8。存在两个离群点(outlier)。

年龄和脂肪百分比的箱线图分别如图 2 2 2 左右所示。(需要注意代码封装的函数是以 1.25IQR 为标准,而老师的PPT是以 1.5IQR 为标准,所以下图右子图不准确)

在这里插入图片描述

图 2    箱线图

代码如下(仅以年龄数据为例):

import numpy as np
import matplotlib.pyplot as plt

x = [23, 23, 27, 27, 39, 41, 47, 49, 50, 52, 54, 54, 56, 57, 58, 58, 60, 61]
y = [9.5, 26.5, 7.8, 17.8, 31.4, 25.9, 27.4, 27.2, 31.2, 34.6, 42.5, 28.8, 33.4, 30.2, 34.1, 32.9, 41.2, 35.7]

x, y = np.array(x), np.array(y)

maximum = np.max(x)
minimum = np.min(x)
median = np.median(x)
Q1 = np.quantile(x, 0.25)
Q3 = np.quantile(x, 0.75)
IQR = Q3-Q1

print(f"最小值: {minimum}")
print(f"上四分位数: {Q1}")
print(f"中位数: {median}")
print(f"下四分位数: {Q3}")
print(f"最大值: {maximum}")
print(f"IQR: {IQR}")
print(f"修正后的最小值: {max(Q1-1.5*IQR, minimum)}")
print(f"修正后的最大值: {min(Q3+1.5*IQR, maximum)}")

plt.boxplot(x)
plt.show()
plt.plot()

补充:使用 np.quantile 函数的计算方法(interpolation 参数采用默认值 ‘linear’)。伪代码如下:

index = (len(a)-1) * p # a 为处理的序列,p 为百分比,如果获取 Q1,则 p=0.25
if index is integer:
 return a[index]
else:
 index_below = floor(indedx)
 index_above = min(index_below + 1, len(a) - 1)

 weight_above = index - index_below
 weight_below = 1 - weight_above

 return a[index_below] * weight_below + a[index_above] * weight_above

根据上面的伪代码可以计算出脂肪百分比的 Q1 = 26.5 × 0.75 + 27.2 × 0.25 = 26.675。

对于做题可以这样理解和记忆:Q1 对应第 ( N + 1 ) / 4 (N+1)/4 (N+1)/4 个位置的数(从 1 1 1 开始计数),如果不是整数,那么就是在该数下取整和加一下取整这两个位置之间,离得近的那一侧的位置对应的数分配更高的权重,远的一侧数分配小权重。比如计算得到的位置是 24.25 24.25 24.25,那么 Q1 为 0.75 0.75 0.75 乘以第 24 24 24 个数与 0.25 0.25 0.25 乘以第 25 25 25 个数之和。Q3 同理。

© 根据这两个变量绘制散点图。

以年龄为横坐标,以脂肪百分比为纵坐标绘制的散点图如图 3 3 3 所示。

图 3    散点图

对应代码如下:

import numpy as np
import matplotlib.pyplot as plt

x = [23, 23, 27, 27, 39, 41, 47, 49, 50, 52, 54, 54, 56, 57, 58, 58, 60, 61]
y = [9.5, 26.5, 7.8, 17.8, 31.4, 25.9, 27.4, 27.2, 31.2, 34.6, 42.5, 28.8, 33.4, 30.2, 34.1, 32.9, 41.2, 35.7]

x, y = np.array(x), np.array(y)

plt.xlabel('age', size=15)
plt.ylabel('%fat', size=15)
plt.scatter(x, y, )
plt.show()

(d) 基于”最小-最大归一化“对两个变量进行归一化。

保留四位小数结果如表 6 6 6 所示。

id012345678
age0.00000.00000.10530.10530.42110.47370.63160.68420.7105
%fat0.04900.53890.00000.28820.68010.52160.56480.55910.6744
id91011121314151617
age0.76320.81580.81580.86840.89470.92110.92110.97371.0000
%fat0.77231.00000.60520.73780.64550.75790.72330.96250.8040

(e) 计算相关系数(Pearson’s product moment coefficient)。这两个变量是正相关还是负相关?

如果以总体数据计算,包括标准差和 Peason 相关系数,即
s t d = 1 n ∑ i = 1 n ( x i − x ˉ ) 2 r x , y = ∑ i = 1 n ( x i − x ˉ ) ( y i − y ˉ ) n σ x σ y \begin{align} {\rm std} &= \sqrt{\frac{1}{n} \sum_{i=1}^n (x_i-\bar x)^2} \tag{1} \\ {\rm r}_{x,y} &= \frac{\sum_{i=1}^n(x_i- \bar x)(y_i - \bar y)}{n\sigma_x\sigma_y} \tag{2} \end{align} stdrx,y=n1i=1n(xixˉ)2 =nσxσyi=1n(xixˉ)(yiyˉ)(1)(2)
其中 σ \sigma σ 为标准差。保留四位的结果为 0.8176。

如果以样本数据计算,即
s t d = 1 n − 1 ∑ i = 1 n ( x i − x ˉ ) 2 r x , y = ∑ i = 1 n ( x i − x ˉ ) ( y i − y ˉ ) ( n − 1 ) σ x σ y \begin{align} {\rm std} &= \sqrt{\frac{1}{n-1} \sum_{i=1}^n (x_i-\bar x)^2} \tag{3} \\ {\rm r}_{x,y} &= \frac{\sum_{i=1}^n(x_i- \bar x)(y_i - \bar y)}{(n-1)\sigma_x\sigma_y} \tag{4} \end{align} stdrx,y=n11i=1n(xixˉ)2 =(n1)σxσyi=1n(xixˉ)(yiyˉ)(3)(4)
保留四位的结果为 0.8657。

两种计算方法对应代码如下:

import numpy as np

x = [23, 23, 27, 27, 39, 41, 47, 49, 50, 52, 54, 54, 56, 57, 58, 58, 60, 61]
y = [9.5, 26.5, 7.8, 17.8, 31.4, 25.9, 27.4, 27.2, 31.2, 34.6, 42.5, 28.8, 33.4, 30.2, 34.1, 32.9, 41.2, 35.7]

x, y = np.array(x), np.array(y)

bar_x, bar_y = x.mean(), y.mean()

# std_x, std_y = x.std(ddof=1), y.std(ddof=1) # 样本标准差
std_x, std_y = x.std(), y.std() # 总体标准差

# r = np.sum((x - bar_x) * (y - bar_y)) / ((len(x)-1) * std_x * std_y)  # 样本
r = np.sum((x - bar_x) * (y - bar_y)) / ((len(x)) * std_x * std_y) # 总体

print(r)

3.下面是一个超市某种商品连续 20 个月的销售数据(单位为百元)

2116192427232221201716202322182426252026

对以上数据进行深度为 5 的 Equal-depth binning。

先排序!,排序后的序列为 {16,16,17,18,19,20,20,20,21,21,22,22,23,23,24,24,25,26,26,27}。

bin 1: 16, 16, 17, 18, 19

bin 2: 20, 20, 20, 21, 21

bin 3: 22, 22, 23, 23, 24

bin 4: 24, 25, 26, 26, 27

代码如下:

import numpy as np

x = [16,16,17,18,19,20,20,20,21,21,22,22,23,23,24,24,25,26,26,27]

x = np.array(x)

equal_depth_binning = np.array_split(x, [i for i in range(5, len(x), 5)])
print(equal_depth_binning)

(a) 采用 bin median 方法进行平滑。

bin 1: 17.2, 17.2, 17.2, 17.2, 17.2

bin 2: 20.4, 20.4, 20.4, 20.4, 20.4

bin 3: 20.8, 20.8, 20.8, 20.8, 20.8

bin 4: 25.6, 25.6, 25.6, 25.6, 25.6

bin_median_smooth = [np.round(i.mean(), 4) for i in equal_depth_binning]
print(bin_median_smooth)

(b) 采用 bin boundaries 方法进行平滑。

bin 1: 16, 16, 16, 19, 19

bin 2: 20, 20, 20, 21, 21

bin 3: 22, 22, 24, 24, 24

bin 4: 24, 24, 27, 27, 27

bin_boundaries_smooth = [np.max(chunk) if np.max(chunk) - i < i - np.min(chunk) else np.min(chunk) for chunk in equal_depth_binning for i in chunk]
print(bin_boundaries_smooth)
  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不牌不改

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值