R语言:商业数据分析实例(2)【k-means, t-test】

2023-05-16

适用于初学者。内容包括k-mean和t-test的使用。

使用到的数据:链接:https://pan.baidu.com/s/1yhzQSdquizLayXamM0wygg 
提取码:3b7i

前言:k-means实现

k-means算法,是一种最广泛使用的聚类算法。k-means以k作为参数,把数据分为k个组,通过迭代计算过程,将各个分组内的所有数据样本的均值作为该类的中心点,使得组内数据具有较高的相似度,而组间的相似度最低。(引用自:张丹(Conan))

k-means工作原理:

  1. 初始化数据,选择k个对象作为中心点。
  2. 遍历整个数据集,计算每个点与每个中心点的距离,将它分配给距离中心最近的组。
  3. 重新计算每个组的平均值,作为新的聚类中心。
  4. 上面2-3步,过程不断重复,直到函数收敛,不再新的分组情况出现。

案例简介

用到的数据共4张表(cvs格式),为2003-2019年美国纽约市房地产交易数据。

        NYC_HISTORICAL包含:交易ID,社区ID,地址,建筑类型,时间,价格,面积等;

        BOROUGH包含:BOROUGH_ID和BOROUG名称;

        BUILDING_CLASS包含:建筑ID和建筑类型等;

        NEIGHBORHOOD 包含:街道ID和BOROUGH_ID等;

本案例需要根据ID整合数据,从中提取目标信息。

本章目标

任务1:使用以下KPI执行k-means聚类。描述所选社区所属的聚类。

  • 自2009年以来,住宅物业的价格中值
  • 自2009年以来,住宅物业的销售数量
  • 自2009年以来,住宅物业的价格标准差
  • 自2009年以来,住宅地产的每平方米价格

任务2:选择另一个社区(如 ID:31),并检验以下假设:从2009年开始,社区( ID:29)的平均住宅物业价格大于所选的另外一个社区

开始:载入所需的包,并设置工作地址

library(lubridate)    #year()
library(tidyverse)    #csv2
library(factoextra)
library(cluster)
setwd("C:/Users/10098/Desktop/AD571/571,A34")

读取所有csv文件。第四个NYC_HISTORICAL较大(150M),且用分号隔开,故用csv2读取

BOROUGH        <- read.csv("BOROUGH.csv", header=TRUE)
BUILDING_CLASS <- read.csv("BUILDING_CLASS.csv", header=TRUE)
NEIGHBORHOOD   <- read.csv("NEIGHBORHOOD.csv", header=TRUE)
NYC_HISTORICAL <- read_csv2("NYC_HISTORICAL.csv")   

将各表数据整合

NYC_HISTORICAL <- mutate(NYC_HISTORICAL, Y = year(SALE_DATE))
NEIGHBORHOOD = left_join(NEIGHBORHOOD,BOROUGH,  by = 'BOROUGH_ID')  
df <- NYC_HISTORICAL %>%
  left_join(BUILDING_CLASS, by = c('BUILDING_CLASS_FINAL_ROLL'='BUILDING_CODE_ID')) %>%
  left_join(NEIGHBORHOOD, by = 'NEIGHBORHOOD_ID')  %>%
  select(NEIGHBORHOOD_ID, SALE_DATE,SALE_PRICE,GROSS_SQUARE_FEET,TYPE,SALE_ID,Y) %>%
  filter(TYPE == 'RESIDENTIAL')  %>%
  group_by(NEIGHBORHOOD_ID)   %>% 
  subset(Y>=2009)  %>%
  subset(GROSS_SQUARE_FEET != 0) %>% 
  na.omit()

取出所需KPI ,并重新命名一下列名

median_sale_price  <- summarize(df, median(SALE_PRICE))                        #KPI1
number_of_sales    <- count(df, NEIGHBORHOOD_ID)                               #KPI2
standard_deviation <- summarize(df, sd(SALE_PRICE))                            #KPI3
AVEPRICE_price     <- summarize(df, sum(SALE_PRICE) / sum(GROSS_SQUARE_FEET))  #KPI4

df_2 <- median_sale_price   %>%
  full_join(number_of_sales,    by = 'NEIGHBORHOOD_ID')   %>%
  full_join(standard_deviation, by = 'NEIGHBORHOOD_ID')   %>%
  full_join(AVEPRICE_price,     by = 'NEIGHBORHOOD_ID')   

colnames(df_2) <- c('ID','median', 'amount', 'sd', 'AVEPRICE_price')

做kmeans之前先做scale(),它使数据框的列居中和缩放(也就是每个值减去均值除标准差)

为什么要scale()?

KNN、K-means和SVM 等距离算法受特征范围的影响大。这些算法使用数据点之间的距离来确定相似性。如果不缩放,变量具有不同的尺度,算法可能对具有更高量级的变量赋予更高的权重,进而影响算法的性能

scale_df <- scale(df_2[,-1]) # 此处scale时不用包括第一列‘ID’

开始kmeans,因为会随机取点,可以设置seed保证每次结果不变。

设定不同的center数量做了4次(因为我们不知道分成几个聚类好)

set.seed(123)
k2 <- kmeans(scale_df, center = 2, nstart = 25)
k3 <- kmeans(scale_df, center = 3, nstart = 25)
k4 <- kmeans(scale_df, center = 4, nstart = 25)
k5 <- kmeans(scale_df, center = 5, nstart = 25)

利用fviz_cluster画图看一下(fviz_cluster:基于ggplot2的分区方法的优雅可视化,包括kmeans)

p2 <- fviz_cluster(k2, data = scale_df) + ggtitle("k=2")
p3 <- fviz_cluster(k3, data = scale_df) + ggtitle("k=3")
p4 <- fviz_cluster(k4, data = scale_df) + ggtitle("k=4")
p5 <- fviz_cluster(k5, data = scale_df) + ggtitle("k=5")

单独运行(如p2)即可出图,这个为了好看,将4张图放在一起查看

library(gridExtra)
grid.arrange(p2, p3, p4, p5, nrow = 2)    #把4张图放在一张画布上便于查看

效果如下: 

可以看到,这里133社区单独成了一个聚类(由于随机,每个人的结果可能不同)。

这是因为k-means使用的是欧根距离,容易受到异常值的影响。可以用进阶的PAM改进。

(PAM是对k-means的一种改进算法,能降低异常值对于聚类效果的影响)【以后介绍】

如何确定center数量?

上面做了4种情况,但如何确定center数量?不幸的是,这个问题没有明确答案。聚类的最佳数量某种程度上是主观的,取决于用于测量相似性的方法和用于划分的参数。(kassambara)

实际操作中,具体情况还是要根据business goal去设定个数。

 这里介绍3种方法:

1.肘法(Elbow method)

即使得集群内总变化 [或集群内总平方和 (WSS )] 尽量小。

f1 <- fviz_nbclust(scale_df, kmeans, method = "wss", nstart = 25) 

图如下: 

我们看到随着k的变大, WSS越来越小,经验上说4比较好(因为在4已经明显下降,之后的比较平缓,也就是k增大带来的效果越来越不明显)。这个方法之所以叫肘法也源于此。

2.平均轮廓法(Average silhouette method)

计算平均轮廓宽度。较高的平均轮廓宽度表示良好的聚类。

f2 <- fviz_nbclust(scale_df, kmeans, method = "silhouette", nstart = 25)

 显然该方法建议我们使用2

3.差距统计法(Gap statistic method

由R. Tibshirani、G. Walther 和 T. Hastie 发表(斯坦福大学,2001 年)。该方法可以应用于任何聚类方法。其将不同 k 值的集群内变化的总和与其在数据的空参考分布下的预期值进行比较。最佳聚类的估计值将是使间隙统计量最大化的值。

f3 <- fviz_nbclust(scale_df, kmeans, nstart = 25,  method = "gap_stat", nboot = 50)

该方法建议我们使用1。 (部分是因为之前提到的异常值导致的)

如果是一般情况图如下:

注:如果想同时显示上述三张表,可使用 grid.arrange(f1, f2, f3, nrow = 3) 

分析

按照上述3个方法,选择聚类数(这里选了4)。将聚类属性合并到数据集,计算4个KPI在不用聚类下的均值

df_3  <- mutate(df_2[,-1], cluster=k4$cluster)   #(将所属聚类放入数据)

cluster_mean <- df_3 %>%
                group_by(cluster) %>%
                summarise_all("mean")

t-test

选择另一个社区(如 ID:31),并检验以下假设:从2009年开始,社区( ID:29)的平均住宅物业价格大于所选的另外一个社区。

先筛选出两个社区的数据(可以自制函数取代下面冗杂的方法)

df_29 <- NYC_HISTORICAL %>%
  left_join(BUILDING_CLASS, by = c('BUILDING_CLASS_FINAL_ROLL' = 'BUILDING_CODE_ID'))  %>%
  left_join(NEIGHBORHOOD, by = 'NEIGHBORHOOD_ID')  %>%
  select(NEIGHBORHOOD_ID, SALE_DATE,SALE_PRICE,GROSS_SQUARE_FEET,TYPE,SALE_ID,Y) %>%
  filter(NEIGHBORHOOD_ID =='29') %>%
  filter(TYPE == 'RESIDENTIAL')  %>%
  subset(Y>=2009)  %>%
  subset(GROSS_SQUARE_FEET != 0) %>% 
  group_by(Y)   %>%
  na.omit() 

df_31 <- NYC_HISTORICAL %>%
  left_join(BUILDING_CLASS, by = c('BUILDING_CLASS_FINAL_ROLL' = 'BUILDING_CODE_ID'))  %>%
  left_join(NEIGHBORHOOD, by = 'NEIGHBORHOOD_ID')  %>%
  select(NEIGHBORHOOD_ID, SALE_DATE,SALE_PRICE,GROSS_SQUARE_FEET,TYPE,SALE_ID,Y) %>%
  filter(NEIGHBORHOOD_ID =='31') %>%
  filter(TYPE == 'RESIDENTIAL')  %>%
  subset(Y>=2009)  %>%
  subset(GROSS_SQUARE_FEET != 0) %>% 
  group_by(Y)   %>%
  na.omit() 

进行t-test

X <- df_29$SALE_PRICE   # 29
Y <- df_31$SALE_PRICE   # 31
t.test(X,Y,alternative = "greater", mu = 0, paired = FALSE, conf.level = .95) 

p = 0.1105 > 0.05,  否定原假设(X>Y为假),则X>Y为真,即X>Y。

大功告成!

案例源于波士顿大学,感谢教授Tara Kelly

Reference:
http://blog.fens.me/r-cluster-kmeans/
http://www.sthda.com/english/articles/29-cluster-validation-essentials/96-determiningthe-optimal-number-of-clusters-3-must-know-methods/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R语言:商业数据分析实例(2)【k-means, t-test】 的相关文章

  • 《C语言中分配了动态内存后一定要释放吗?》

    问 xff1a 比如main函数里有一句 malloc 后面没有free 1 那么当main结束后 xff0c 动态分配的内存不会随之释放吗 xff1f 2 如果程序结束能自动释放 xff0c 那么还加上free xff08 xff09 x
  • Qemu使用心得

    使用Qemu的心得体会如下 xff1a xff08 1 xff09 在QEMU源码中增加自己的 c实现 xff0c 编译后出现很多个错误如 xff1a error storage class specified for parameter
  • 转载:malloc和free底层实现

    转载 xff1a malloc和free底层实现 内存管理内幕 Linux内存管理 xff1a Malloc 本文引用了下面这篇文章 xff0c 读完下面 xff0c 应该读下上面两篇文章 xff0c 其中 xff0c 内存管理内幕 提供了
  • qemu tcg代码执行流程

    转自 xff1a http blog csdn net alloc7 article details 7719823 一 qemu简介 qemu是使用动态二进制翻译的cpu模拟器 xff0c 它支持两种运行模式 xff1a 全系统模拟和用户
  • c语言如何调用c++(本文从qemu开发中总结)

    背景 xff1a 有时候一个工程中有c语言编写的代码 c xff0c 也有c 43 43 cpp 编写的 xff0c 分别用 xff43 语言编译器 xff08 这里指 xff47 xff43 xff43 xff09 和 xff43 xff
  • c++常错语法

    1 new T 代表创建一个T类的对象指针 xff0c new T 标识创建T类对象数组指针 2 template模板类只能把成员函数都定义在 h中 xff0c 分开 h和 cpp会报链接错误 3 类A 的成员变量包含B的对象B b xff
  • UEFI EDK2开发环境设置关键点/修改环境变量

    1 问题描述 Linux下当修改了已经编译过的EDK2工程顶层路径后 进入工程顶层路径source edksetup sh会报错 2 解决步骤 有一个隐藏问题非常容易被忽视 那就是EDK2工程的环境变量可能还是原来的旧的 这时候 1 进入工
  • linux静态库.a使用常见错误

    在linux中如果一个程序需要用到 a 有以下几点需要注意 1 如果x o与y o中用到了静态xx a中的函数 不能用gcc xx a o test x o y o这种方式编译 会提示那些函数undefined 正确的做法是gcc o te
  • C/C++多线程常见问题

    1 问题 1 1 创建线程后是否立马开始并行执行 答 主线程创建了子线程之后 后者并不是立即就开始运行了 至少在Linux操作系统下 1 子线程和主线程运行在一个core上 那还需要等待主线程交出core控制权 可能是时间片耗尽 2 子线程
  • 2020 年百度之星·程序设计大赛 - 初赛二 题解

    废话 丑话说在前头 xff0c T8我不会 xff08 没错是指我会出丑 xff09 T1 既然要玩尽可能多轮 xff0c 那么每轮投入的钱就要最少 xff0c 也就是 m m m 元 xff0c 那么可以算出每轮游戏会亏损
  • QEMU内存管理

    QEMU内存管理 1 QEMU中管理的Memory有 xff1a 普通的RAM MMIO 内存控制器 将物理内存动态的映射到不同的虚拟地址空间 2 QEMU的Memory是以一个MemoryRegin为节点组成的非循环图的形式组织的 叶子节
  • Matlab实现基于二维伽马函数的光照不均匀图像自适应校正算法

    Matlab程序 xff1a 基于二维伽马函数的光照不均匀图像自适应校正算法 clc close all tic im 61 imread 39 你的图片 jpg 39 figure imshow im title 39 原图 39 h s
  • SCI回复评审意见模板

    一般反馈回来修改时 xff0c 要给编辑重新写一封cover letter xff0c 表示尊重与感谢 xff0c 范文如下 句式大家可以依照自己的习惯表达修改 xff0c 多参考他人经验 xff09 Dear XX xff08 给你回信的
  • 毕业快乐 —— 写于2020年3月13日

    很久没有经营这个博客了 今天来写点什么罢 2020的春天 xff0c 由于猝不及防的疫情 xff0c 参加了一场特殊的毕业答辩 线上答辩形式 没有西装和鲜花 xff0c 似乎缺少了一些仪式感 但毕业似乎真真切切就是一件水到渠成的事情 xff
  • Mac连上WIFI但是无法上网的3种解决方案

    一般我们最先会认为是DNS问题 xff0c 你可以试下用ip访问一个服务器 xff08 网站 xff09 看下行不行 xff0c 如果也不行那就应该不是DNS的问题了 或者改变一下DNS xff0c 如114 xff0c 或者自己内网要求的
  • 简单粗暴理解支持向量机(SVM)及其MATLAB实例

    目录 SVM概述 SVM的改进 xff1a 解决回归拟合问题的SVR 多分类的SVM QP求解 SVM的MATLAB实现 xff1a Libsvm 实例 用SVM分类 实例 用SVM回归 SVM概述 SVM已经是非常流行 大家都有所耳闻的技
  • 极限学习机(Extreme Learning Machine, ELM)原理详解和MATLAB实现

    目录 引言 极限学习机原理 MATLAB中重点函数解读 极限学习机的MATLAB实践 引言 极限学习机不是一个新的东西 xff0c 只是在算法 xff08 方法 xff09 上有新的内容 在神经网络结构上 xff0c 就是一个前向传播的神经
  • 粒子群优化算法(PSO)简介及MATLAB实现

    目录 粒子群优化算法概述 PSO算法步骤 PSO xff08 粒子群优化算法 xff09 与GA xff08 遗传算法 xff09 对比 PSO的MATLAB实现 粒子群优化算法概述 粒子群优化 PSO particle swarm opt
  • 结构化概率模型

    机器学习的算法经常会涉及到在非常多的随机变量上的概率分布 通常 xff0c 这些概率分布涉及到的直接相互作用都是介于非常少的变量之间的 使用单个函数来描述整个联合概率分布是非常低效的 无论是计算上还是统计上 我们可以把概率分布分解成许多因子
  • Fuzzy C-Means(模糊C均值聚类)算法原理详解与python实现

    目录 模糊理论 Fuzzy C Means算法原理 算法步骤 python实现 参考资料 本文采用数据集为iris 将iris txt放在程序的同一文件夹下 请先自行下载好 模糊理论 模糊控制是自动化控制领域的一项经典方法 其原理则是模糊数

随机推荐