【BI学习作业03

编程入门 行业动态 更新时间:2024-10-28 06:24:51

【BI学习<a href=https://www.elefans.com/category/jswz/34/1771149.html style=作业03"/>

【BI学习作业03

内容目录

    • 1.思考题
      • 1.1如何使用用户标签来指导业务(如何提升业务)
      • 1.2如果给你一堆用户数据,没有打标签。你该如何处理(如何打标签)
        • 1.2.1什么是聚类分析?
        • 1.2.2不同的聚类问题
        • 1.2.3无监督算法之K-means
          • 1.2.3.1概述
          • 1.2.3.2算法核心思想
          • 1.2.3.3算法实现步骤
          • 1.2.3.4算法步骤图解
          • 1.2.3.5K-means术语:
          • 1.2.3.6K-means算法优缺点
          • 1.2.3.7K-means算法的使用
            • scikit-learn中的K-means参数说明
            • K-means算法的实战
      • 1.3准确率和精确率有何不同(评估指标)
      • 1.4如果你使用大众点评,想要给某个餐厅打标签。这时系统可以自动提示一些标签,你会如何设计(标签推荐)
        • 1.4.1数据结构
        • 1.4.2用户画像模块
        • 1.4.3开发上线流程
        • 1.4.4数据指标体系
        • 1.4.4标签维度
    • 2.编程题
      • 2.1针对Delicious数据集,对SimpleTagBased算法进行改进(使用NormTagBased、TagBased-TFIDF算法)
        • 2.1.1NormTagBased算法
        • 2.1.2TagBased-TFIDF算法
      • 2.2对Titanic数据进行清洗,使用之前介绍过的10种模型中的至少2种(包括TPOT)
        • 2.2.1利用tpot实现titanic
        • 2.2.2利用tpot生成的代码文件


1.思考题

1.1如何使用用户标签来指导业务(如何提升业务)

  1. 获客:如何进行拉新,通过更精准的营销获取客户;
  2. 粘客:个性化推荐,搜索排序,场景运营等;
  3. 留客:流失率预测,分析关键节点降低流失率。

1.2如果给你一堆用户数据,没有打标签。你该如何处理(如何打标签)

使用k-means无监督算法,选定一个分类数(k),给没有标签的数据,分成哪一类。那么什么是聚类算法呢?

1.2.1什么是聚类分析?

聚类 (Clustering) 就是将数据对象分组成为多个类或者簇 (Cluster),它的目标是:在同一个簇中的对象之间具有较高的相似度,而不同簇中的对象差别较大。所以,在很多应用中,一个簇中的数据对象可以被作为一个整体来对待,从而减少计算量或者提高计算质量。

其实聚类是一个人们日常生活的常见行为,即所谓“物以类聚,人以群分”,核心的思想也就是聚类。人们总是不断地改进下意识中的聚类模式来学习如何区分各个事物和人。同时,聚类分析已经广泛的应用在许多应用中,包括模式识别,数据分析,图像处理以及市场研究。通过聚类,人们能意识到密集和稀疏的区域,发现全局的分布模式,以及数据属性之间的有趣的相互关系。

聚类同时也在 Web 应用中起到越来越重要的作用。最被广泛使用的既是对 Web 上的文档进行分类,组织信息的发布,给用户一个有效分类的内容浏览系统(门户网站),同时可以加入时间因素,进而发现各个类内容的信息发展,最近被大家关注的主题和话题,或者分析一段时间内人们对什么样的内容比较感兴趣,这些有趣的应用都得建立在聚类的基础之上。作为一个数据挖掘的功能,聚类分析能作为独立的工具来获得数据分布的情况,观察每个簇的特点,集中对特定的某些簇做进一步的分析,此外,聚类分析还可以作为其他算法的预处理步骤,简化计算量,提高分析效率,这也是我们在这里介绍聚类分析的目的。

1.2.2不同的聚类问题

对于一个聚类问题,要挑选最适合最高效的算法必须对要解决的聚类问题本身进行剖析,下面我们就从几个侧面分析一下聚类问题的需求。

  • 聚类结果是排他的还是可重叠的

为了很好理解这个问题,我们以一个例子进行分析,假设你的聚类问题需要得到二个簇:“喜欢詹姆斯卡梅隆电影的用户”和“不喜欢詹姆斯卡梅隆的用户”,这其实是一个排他的聚类问题,对于一个用户,他要么属于“喜欢”的簇,要么属于不喜欢的簇。但如果你的聚类问题是“喜欢詹姆斯卡梅隆电影的用户”和“喜欢里奥纳多电影的用户”,那么这个聚类问题就是一个可重叠的问题,一个用户他可以既喜欢詹姆斯卡梅隆又喜欢里奥纳多。

所以这个问题的核心是,对于一个元素,他是否可以属于聚类结果中的多个簇中,如果是,则是一个可重叠的聚类问题,如果否,那么是一个排他的聚类问题。

  • 基于层次还是基于划分

其实大部分人想到的聚类问题都是“划分”问题,就是拿到一组对象,按照一定的原则将它们分成不同的组,这是典型的划分聚类问题。但除了基于划分的聚类,还有一种在日常生活中也很常见的类型,就是基于层次的聚类问题,它的聚类结果是将这些对象分等级,在顶层将对象进行大致的分组,随后每一组再被进一步的细分,也许所有路径最终都要到达一个单独实例,这是一种“自顶向下”的层次聚类解决方法,对应的,也有“自底向上”的。其实可以简单的理解,“自顶向下”就是一步步的细化分组,而“自底向上”就是一步步的归并分组。

  • 簇数目固定的还是无限制的聚类

这个属性很好理解,就是你的聚类问题是在执行聚类算法前已经确定聚类的结果应该得到多少簇,还是根据数据本身的特征,由聚类算法选择合适的簇的数目。

  • 基于距离还是基于概率分布模型

基于距离的聚类问题应该很好理解,就是将距离近的相似的对象聚在一起。相比起来,基于概率分布模型的,可能不太好理解,那么下面给个简单的例子。

一个概率分布模型可以理解是在 N 维空间的一组点的分布,而它们的分布往往符合一定的特征,比如组成一个特定的形状。基于概率分布模型的聚类问题,就是在一组对象中,找到能符合特定分布模型的点的集合,他们不一定是距离最近的或者最相似的,而是能完美的呈现出概率分布模型所描述的模型。

下面图 1 给出了一个例子,对同样一组点集,应用不同的聚类策略,得到完全不同的聚类结果。左侧给出的结果是基于距离的,核心的原则就是将距离近的点聚在一起,右侧给出的基于概率分布模型的聚类结果,这里采用的概率分布模型是一定弧度的椭圆。图中专门标出了两个红色的点,这两点的距离很近,在基于距离的聚类中,将他们聚在一个类中,但基于概率分布模型的聚类则将它们分在不同的类中,只是为了满足特定的概率分布模型(当然这里我特意举了一个比较极端的例子)。所以我们可以看出,在基于概率分布模型的聚类方法里,核心是模型的定义,不同的模型可能导致完全不同的聚类结果。

图 1 基于距离和基于概率分布模型的聚类问题

1.2.3无监督算法之K-means
1.2.3.1概述

K-means聚类算法也称k均值聚类算法,是集简单和经典于一身的基于距离的聚类算法。它采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为类簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。

1.2.3.2算法核心思想

K-means聚类算法是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。

1.2.3.3算法实现步骤

1、首先确定一个k值,即我们希望将数据集经过聚类得到k个集合。

2、从数据集中随机选择k个数据点作为质心。

3、对数据集中每一个点,计算其与每一个质心的距离(如欧式距离),离哪个质心近,就划分到那个质心所属的集合。

4、把所有数据归好集合后,一共有k个集合。然后重新计算每个集合的质心。

5、如果新计算出来的质心和原来的质心之间的距离小于某一个设置的阈值(表示重新计算的质心的位置变化不大,趋于稳定,或者说收敛),我们可以认为聚类已经达到期望的结果,算法终止。

6、如果新质心和原质心距离变化很大,需要迭代3~5步骤。

1.2.3.4算法步骤图解


上图a表达了初始的数据集,假设k=2。在图b中,我们随机选择了两个k类所对应的类别质心,即图中的红色质心和蓝色质心,然后分别求样本中所有点到这两个质心的距离,并标记每个样本的类别为和该样本距离最小的质心的类别,如图c所示,经过计算样本和红色质心和蓝色质心的距离,我们得到了所有样本点的第一轮迭代后的类别。此时我们对我们当前标记为红色和蓝色的点分别求其新的质心,如图d所示,新的红色质心和蓝色质心的位置已经发生了变动。图e和图f重复了我们在图c和图d的过程,即将所有点的类别标记为距离最近的质心的类别并求新的质心。最终我们得到的两个类别如图f。

1.2.3.5K-means术语:

簇:所有数据的点集合,簇中的对象是相似的。

质心:簇中所有点的中心(计算所有点的中心而来)

1.2.3.6K-means算法优缺点

优点:

1、原理比较简单,实现也是很容易,收敛速度快。

2、当结果簇是密集的,而簇与簇之间区别明显时, 它的效果较好。

3、主要需要调参的参数仅仅是簇数k。

缺点:

1、K值需要预先给定,很多情况下K值的估计是非常困难的。

2、K-Means算法对初始选取的质心点是敏感的,不同的随机种子点得到的聚类结果完全不同 ,对结果影响很大。

3、对噪音和异常点比较的敏感。用来检测异常值。

4、采用迭代方法,可能只能得到局部的最优解,而无法得到全局的最优解。

1.2.3.7K-means算法的使用
scikit-learn中的K-means参数说明
from sklearn.cluster import KMeans
KMeans(n_clusters=8, max_iter=300)
n_clusters:聚类个数,缺省值为8 
max_iter:执行一次k-means算法所进行的最大迭代数,缺省值为300 
K-means算法的实战
# coding: utf-8
from sklearn.cluster import KMeans
from sklearn import preprocessing
import pandas as pd
# 数据加载
data = pd.read_csv('team_cluster_data.csv', encoding='gbk')
train_x = data[["2019国际排名","2018世界杯排名","2015亚洲杯排名"]]
kmeans = KMeans(n_clusters=3)
# 规范化到 [0,1] 空间
min_max_scaler=preprocessing.MinMaxScaler()
train_x=min_max_scaler.fit_transform(train_x)
# kmeans 算法
kmeans.fit(train_x)
predict_y = kmeans.predict(train_x)
# 合并聚类结果,插入到原数据中
result = pd.concat((data,pd.DataFrame(predict_y)),axis=1)
result.rename({0:u'聚类结果'},axis=1,inplace=True)
print(result)
# 将结果导出到CSV文件中
#result.to_csv("team_cluster_result.csv")from sklearn.mixture import GaussianMixture
model = GaussianMixture(n_components=3, covariance_type="full")
model.fit(train_x)
#result = model.predict(train_x)
predict_y = model.predict(train_x)
# 合并聚类结果,插入到原数据中
result = pd.concat((data,pd.DataFrame(predict_y)),axis=1)
result.rename({0:u'聚类结果'},axis=1,inplace=True)
print(result)
# 代码结果如下:
'''国家  2019国际排名  2018世界杯排名  2015亚洲杯排名  聚类结果
0       中国        73         40          7     1
1       日本        60         15          5     2
2       韩国        61         19          2     2
3       伊朗        34         18          6     2
4       沙特        67         26         10     2
5      伊拉克        91         40          4     1
6      卡塔尔       101         40         13     0
7      阿联酋        81         40          6     1
8   乌兹别克斯坦        88         40          8     1
9       泰国       122         40         17     0
10      越南       102         50         17     0
11      阿曼        87         50         12     0
12      朝鲜       110         50         14     0
13      印尼       164         50         17     0
14      澳洲        40         30          1     2
15     叙利亚        76         40         17     0
16      约旦       118         50          9     1
17     科威特       160         50         15     0国家  2019国际排名  2018世界杯排名  2015亚洲杯排名  聚类结果
0       中国        73         40          7     2
1       日本        60         15          5     1
2       韩国        61         19          2     1
3       伊朗        34         18          6     1
4       沙特        67         26         10     1
5      伊拉克        91         40          4     2
6      卡塔尔       101         40         13     2
7      阿联酋        81         40          6     2
8   乌兹别克斯坦        88         40          8     2
9       泰国       122         40         17     0
10      越南       102         50         17     2
11      阿曼        87         50         12     2
12      朝鲜       110         50         14     2
13      印尼       164         50         17     0
14      澳洲        40         30          1     1
15     叙利亚        76         40         17     0
16      约旦       118         50          9     2
17     科威特       160         50         15     0'''

link:

  1. 深入推荐引擎相关算法 - 聚类
  2. K-means聚类算法原理

1.3准确率和精确率有何不同(评估指标)

解释准确率和精确率之前,我们先来看一个例子。我们有10张照片,5张男性、5张女性。如下图:


有一个判断性别的机器学习模型,当我们使用它来判断「是否为男性」时,会出现4种情况。如下图:

  1. 实际为男性,且判断为男性(正确)
  2. 实际为男性,但判断为女性(错误)
  3. 实际为女性,且判断为女性(正确)
  4. 实际为女性,但判断为男性(错误)

这4种情况构成了经典的混淆矩阵,如下图:

TP — True Positive:实际为男性,且判断为男性(正确)

FN — False Negative:实际为男性,但判断为女性(错误)

TN — True Negative:实际为女性,且判断为女性(正确)

FP — False Positive:实际为女性,但判断为男性(错误)

这4个名词初看起来比较晕(尤其是缩写),但是当我们把英文拆分时就很容易理解了,如下图:

所有的评估指标都是围绕上面4种情况来计算的,所以理解上面4种情况是基础!
下面详细介绍一下准确率和精确率评估指标详情和计算公式:

准确率 — Accuracy
预测正确的结果占总样本的百分比,公式如下:

准 确 率 = T P + T N T P + F P + T N + F N 准确率=\frac{TP+TN}{TP+FP+TN+FN} 准确率=TP+FP+TN+FNTP+TN​

虽然准确率可以判断总的正确率,但是在样本不平衡 的情况下,并不能作为很好的指标来衡量结果。举个简单的例子,比如在一个总样本中,正样本占 90%,负样本占 10%,样本是严重不平衡的。对于这种情况,我们只需要将全部样本预测为正样本即可得到 90% 的高准确率,但实际上我们并没有很用心的分类,只是随便无脑一分而已。这就说明了:由于样本不平衡的问题,导致了得到的高准确率结果含有很大的水分。即如果样本不平衡,准确率就会失效。

精确率(差准率)- Precision
所有被预测为正的样本中实际为正的样本的概率,公式如下:

精 确 率 = T P T P + F P 精确率=\frac{TP}{TP+FP} 精确率=TP+FPTP​

精准率和准确率看上去有些类似,但是完全不同的两个概念。精准率代表对正样本结果中的预测准确程度,而准确率则代表整体的预测准确程度,既包括正样本,也包括负样本。

link:一文看懂机器学习指标:准确率、精准率、召回率、F1、ROC曲线、AUC曲线

1.4如果你使用大众点评,想要给某个餐厅打标签。这时系统可以自动提示一些标签,你会如何设计(标签推荐)

我们设计用户标签之前,首先要搞清楚,什么是用户画像?标签应用于用户画像,用户画像包含标签系统。用户画像是通过分析用户的基础信息、特征偏好、社会属性等各维度的数据,刻画出用户的信息全貌,从中挖掘用户价值。它可以帮助数据“起死回生”,提供个性化推荐、精准营销、个性化服务。

一般对用户“打标签”,一般分为三类:

● 统计类标签:最基础常见的标签,从用户注册数据、用户访问数据中统计得出。

● 规则类标签:基于用户行为及规则产生,通常由对业务更为熟悉的运营人员和数据人员共同协商确定。

● 机器学习挖掘类标签:通过机器学习挖掘产生,根据某些用户行为或熟悉进行预测判断。

1.4.1数据结构

画像系统的基础设施包括Spark、Hive、HBase、Airflow、Redis、Elasticsearch。
下图是《用户画像》中的数据仓库架构。

(1)数据仓库ETL加工流程是对每日的业务数据、日志数据、埋点数据等数据经过ETL过程,加工到对应的原始数据层(ODS)、数据仓库(DW)、数据集市层(DM)中。

(2)用户画像不是产生数据的源头,是经过ODS层、DW层、DM层中的数据与用户相关数据的二次建模加工得到的数据。

在ETL过程将用户标签写入Hive,根据不同数据对应不同数据库的应用场景,再将数据同步到MySQL、HBase、Elasticsearch等数据库中。

Hive:存储用户标签、用户人群及用户特征库的计算结果

MySQL:存储标签元数据,监控相关数据,导出到业务系统的数据

HBase:存储线上实时数据

Elasticsearch:支持海量数据的实时查询分析

(3)用户标签在Hive中加工完成后,部分标签通过Sqoop同步到MySQL数据库,提供用于BI报表展示的数据、多为透视分析数据、圈人服务数据;另一部分标签同步到HBase数据库用于产品的线上个性化推荐。

1.4.2用户画像模块

搭建用户画像方案整体考虑以下8个模块

● 用户画像基础

了解和明确用户画像包含的模块,设计数据仓库架构、开发流程、表结构,及ETL的设计。主要就是明确大方向的规划。

● 数据指标体系

建立数据指标体系,根据业务线梳理,包括用户属性、用户行为、用户消费、风险控制等维度的指标体系。

● 标签数据存储

设计好数据指标体系后,考虑不同应用场景使用哪种存储方式。

● 标签数据开发

重点模块。标签数据开发包含统计类、规则雷、挖掘类、流式计算类标签的开发,以及人群计算功能的开发。

重点内容:数据调研、和业务方确认数据口径、标签开发上线。打通画像数据和各业务系统之间的路,提供接口服务

● 开发性能调优

标签数据开发上线后,为了缩短调度时间、保证数据稳定性,需要对标签脚本、调度脚本进行迭代重构、调优。梳理现有标签开发、调度、校验告警、同步到服务层等相关脚本、明确可以优化的地方,迭代优化。

重点内容:减少ETL调度时间,降低调度时的资源消耗。

● 作业流程调度

标签加工、人群计算、同步数据和业务系统、数据监控预警脚本开发完成后,需要调度工具把整套流程调度起来。

重点内容:满足定式调度、监控预警、失败重试,各调度任务之家的复杂依赖关系。

● 用户画像产品化

产品化的模块包括包括标签视图、用户标签查询、用户分群、透视分析等。

重点内容:满足业务方对用户精准营销的需求。

● 用户画像应用

应用场景包括用户特征分析、短信邮件、站内信、Push消息的精准推送,客户针对不同用户的话术、针对高价值用户的极速退款等高级服务应用等。

重点内容:帮助业务方理解和应用用户画像数据,提高用户活跃度和GMV。

1.4.3开发上线流程

1.4.4数据指标体系

数据指标体系是建立用户画像的基础,也是在进入开发前的关键环节,是需要结合业务场景制定的数据指标。

建立用户画像一般从2个维度:

用户维度(userid):基于当前用户账号相关数据推送内容。

设备维度(cookie):当用户没有登陆账户而访问设备时,基于用户在设备的行为对该设备推送相关内容。

  1. 用户标签从标签类型可分为:统计类、规则类、机器学习挖掘类。

  2. 从建立的维度来看,可分为:用户属性类、用户行为类、用户消费类、风险控制类。
    至于标签如何分类,没有严格的规定,符合业务场景和使用者使用即可。

1.4.4标签维度

1.用户属性类

一般是与用户自带属性相关,例如性别、年龄、地域、注册日期、会员类型等。

对于相同的一级标签诶些,需要判断多个标签之间的关系是互斥还是非互斥关系。

例如,在判断性别时,不能既是男、又是女,这就是互斥关系。

对于传统企业来说,更多的是从用户属性类维度去丰富指标体系。而对于互联网企业来说,其拥有海量的用户访问日志数据,所以更容易从用户行为类数据分析用户的行为特性。

2.用户行为类

常见用户行为维度指标包括订单相关行为、下单/访问相关行为、用户近30天行为指标、高频活跃时间段、用户购买类、点击偏好、营销敏感度等相关行为。

3.用户消费类

用户消费维度指标体系建设从用户搜索、流量、加购、收藏、下单商品对应的品类入手。品类越精细,给用户推荐的准确性越高。

例如品类细分到:手机-手机配件-数据线。

4.风险控制类

风控维度主要是预防薅羊毛、恶意刷单、借贷欺诈行为的用户,未防止这类用户给平台带来损失,所以专门设置风控类维度。

结合业务场景,可从账号风险、设备风险、借贷风险等维度考虑指标体系。

5.社交属性维度

该维度主要是了解用户的社交范围,如家庭成员、社交偏好、社交活跃度等等。以此来提供个性化推荐和精准营销。

例如在朋友圈收到的广告,也是基于用户的社交属性进行的推送。

下面是整理的上述5个维度的画像主题:

Thinking5:使用TPOT等AutoML工具,有怎样的好处和不足

优点:可以帮助选择合适的模型和参数
缺点:

  1. 如果数据集量过大,会花费大量时间去迭代更新,寻找最优参数;
  2. 不好做数据清洗
  3. 数据集要很标准,不然不能使用

2.编程题

2.1针对Delicious数据集,对SimpleTagBased算法进行改进(使用NormTagBased、TagBased-TFIDF算法)

Delicious数据集:/
1867名用户,105000个书签,53388个标签 格式:userID bookmarkID tagID timestamp

  1. SimpleTagBased算法

统计每个用户的常用标签;
对每个标签,统计被打过这个标签次数最多的商品;
对于一个用户,找到他常用的标签,然后找到具有这些标签的最热门物品推荐给他
用户u对商品i的兴趣 s c o r e ( u , i ) = ∑ t u s e r t a g s [ u ] [ t ] ∗ t a g i t e m s [ u ] [ i ] score(u,i)=\sum_{t}user_tags[u][t]*tag_items[u][i] score(u,i)=∑t​usert​ags[u][t]∗tagi​tems[u][i]

2.1.1NormTagBased算法

对score进行归一化 s c o r e ( u , i ) = ∑ t u s e r t a g s [ u ] [ t ] u s e r t a g s [ u ] ∗ t a g i t e m s [ t ] [ i ] t a g i t e m s [ t ] score(u,i)=\sum_{t}\frac{user_tags[u][t]}{user_tags[u]}*\frac{tag_items[t][i]}{tag_items[t]} score(u,i)=∑t​usert​ags[u]usert​ags[u][t]​∗tagi​tems[t]tagi​tems[t][i]​

# 使用NormTagBased算法对Delicious2K数据进行推荐
# 原始数据集:/
# 数据格式:userID     bookmarkID     tagID     timestamp
# 1.导入相关模块
import random
import math
import operator
import pandas as pd# 2.定义文件路径,训练集,测试集,用户标签,商品标签的字典
# 文件路径
file_path = "user_taggedbookmarks-timestamps.dat"
# 字典类型,保存了user对item的tag,即{userid: {item1:[tag1, tag2], ...}}
records = {}
# 训练集,测试集
train_data = dict()
test_data = dict()
# 用户标签,商品标签
user_tags = dict()
tag_items = dict()
user_items = dict()# 设置矩阵 mat[index, item] = 1
def addValueToMat(mat, index, item, value=1):if index not in mat:mat.setdefault(index, {})mat[index].setdefault(item, value)else:if item not in mat[index]:mat[index][item] = valueelse:mat[index][item] += value# 数据加载
def load_data():print("开始数据加载...")df = pd.read_csv(file_path, sep='\t')for i in range(len(df)):uid = df['userID'][i]iid = df['bookmarkID'][i]tag = df['tagID'][i]# 键不存在时,设置默认值{}records.setdefault(uid, {})records[uid].setdefault(iid, [])records[uid][iid].append(tag)print("数据集大小为 %d." % (len(df)))print("设置tag的人数 %d." % (len(records)))print("数据加载完成\n")# 将数据集拆分为训练集和测试集
def train_test_split(ratio, seed=100):random.seed(seed)for u in records.keys():for i in records[u].keys():# ratio比例设置为测试集if random.random() < ratio:test_data.setdefault(u, {})test_data[u].setdefault(i, [])for t in records[u][i]:test_data[u][i].append(t)else:train_data.setdefault(u, {})train_data[u].setdefault(i, [])for t in records[u][i]:train_data[u][i].append(t)print("训练集样本数 %d, 测试集样本数 %d" % (len(train_data), len(test_data)))# 使用训练集,初始化user_tags, tag_items, user_items
def initStat():records = train_datafor u, items in records.items():for i, tags in items.items():for tag in tags:# print tag# 用户和tag的关系addValueToMat(user_tags, u, tag, 1)# tag和item的关系addValueToMat(tag_items, tag, i, 1)# 用户和item的关系addValueToMat(user_items, u, i, 1)print("user_tags, tag_items, user_items初始化完成.")print("user_tags大小 %d, tag_items大小 %d, user_items大小 %d" % (len(user_tags), len(tag_items), len(user_items)))# 对用户user推荐Top-N
def recommend(user, N):recommend_items = dict()# 对Item进行打分,分数为所有的(用户对某标签使用的次数 wut, 乘以 商品被打上相同标签的次数 wti)之和tagged_items = user_items[user]for tag, wut in user_tags[user].items():# print(self.user_tags[user].items())for item, wti in tag_items[tag].items():if item in tagged_items:continueif item not in recommend_items:recommend_items[item] = wut * wtielse:recommend_items[item] = recommend_items[item] + wut * wtireturn sorted(recommend_items.items(), key=operator.itemgetter(1), reverse=True)[0:N]# 使用测试集,计算准确率和召回率
def precisionAndRecall(N):hit = 0h_recall = 0h_precision = 0for user, items in test_data.items():if user not in train_data:continue# 获取Top-N推荐列表rank = recommend(user, N)for item, rui in rank:if item in items:hit = hit + 1h_recall = h_recall + len(items)h_precision = h_precision + N# 返回准确率 和 召回率return (hit / (h_precision * 1.0)), (hit / (h_recall * 1.0))# 使用测试集,对推荐结果进行评估
def testRecommend():print("推荐结果评估")print("%3s %10s %10s" % ('N', "精确率", '召回率'))for n in [5, 10, 20, 40, 60, 80, 100]:precision, recall = precisionAndRecall(n)print("%3d %10.3f%% %10.3f%%" % (n, precision * 100, recall * 100))# 3. 数据加载
load_data()
# 4.将训练集,测试集拆分,20%测试集
train_test_split(0.2)
# 5.使用训练集,初始化user_tags, tag_items, user_items
initStat()
# 6.根据数据进行推荐,算出Top-N
testRecommend()# 代码结果如下:
'''开始数据加载...
数据集大小为 437593.
设置tag的人数 1867.
数据加载完成训练集样本数 1860, 测试集样本数 1793
user_tags, tag_items, user_items初始化完成.
user_tags大小 1860, tag_items大小 36884, user_items大小 1860
推荐结果评估N        精确率        召回率5      0.829%      0.355%10      0.633%      0.542%20      0.512%      0.877%40      0.381%      1.304%60      0.318%      1.635%80      0.276%      1.893%
100      0.248%      2.124%'''
2.1.2TagBased-TFIDF算法

如果一个tag很热门,会导致user_tags[t]很大,所以即使tag_items[u,t]很小,也会导致score(u,i)很大。给热门标签过大的权重,不能反应用户个性化的兴趣,TF-IDF的思想,使用tag_users[t]表示标签t被多少个不同的用户使用
s c o r e ( u , i ) = ∑ t u s e r t a g s [ u ] [ t ] l o g ( 1 + ( u s e r t a g s [ t ] ) ∗ t a g i t e m s [ t , i ] score(u,i)=\sum_{t}\frac{user_tags[u][t]}{log(1+(user_tags[t])}*tag_items[t,i] score(u,i)=∑t​log(1+(usert​ags[t])usert​ags[u][t]​∗tagi​tems[t,i]

#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
# @author : biao chen
# @Email : chenbiao@sleepace
# @Project : Python_project
# @File : delicious_tagbased_tfidf.py
# @Software: PyCharm
# @Time : 2020/11/18 15:33
# code is far away from bugs with the god animal protectingI love animals. They taste delicious.┏ ┓    ┏┓┏ ┛┻ ━━━┛┻┓┃     ☃   ┃┃  ┳┛  ┗┳  ┃┃     ┻    ┃┗━┓      ┏━┛┃      ┗━━━┓┃  神兽保佑 ┣┓┃ 永无BUG!┏┛┗┓┓┏━┳┓┏┛┃┫┫  ┃┫┫┗┻┛  ┗┻┛
"""
"""使用TagBased-TFIDF算法对Delicious2K数据进行推荐原始数据集::userID     bookmarkID     tagID     timestamp
"""
# 1.导入相关模块
import random
import math
import operator
import pandas as pd# 2.定义文件路径,训练集,测试集,用户标签,商品标签的字典
# 文件路径
file_path = "user_taggedbookmarks-timestamps.dat"
# 字典类型,保存了user对item的tag,即{userid: {item1:[tag1, tag2], ...}}
records = {}
# 训练集,测试集
train_data = dict()
test_data = dict()
# 用户标签,商品标签
user_tags = dict()
tag_users = dict()
tag_items = dict()
user_items = dict()# 数据加载,records
def load_data():print("开始数据加载...")df = pd.read_csv(file_path, sep='\t')#以\t为数据分隔符print(df.head(5))for i in range(len(df)):uid = df['userID'][i]iid = df['bookmarkID'][i]tag = df['tagID'][i]# 键不存在时,设置默认值{}records.setdefault(uid,{})records[uid].setdefault(iid,[])records[uid][iid].append(tag)print("数据集大小为 %d." % (len(df)))print("设置tag的人数 %d." % (len(records)))print("数据加载完成\n")# 将数据集拆分为训练集和测试集
def train_test_split(ratio, seed=100):random.seed(seed) #设置随机数生成器的种子for u in records.keys():for i in records[u].keys():# ratio比例设置为测试集if random.random()<ratio:test_data.setdefault(u,{})test_data[u].setdefault(i,[])for t in records[u][i]:test_data[u][i].append(t)else:train_data.setdefault(u,{})train_data[u].setdefault(i,[])for t in records[u][i]:train_data[u][i].append(t)print("训练集样本数 %d, 测试集样本数 %d" % (len(train_data),len(test_data)))# 设置矩阵 mat[index, item] = 1
def addValueToMat(mat, index, item, value=1):if index not in mat:mat.setdefault(index,{})mat[index].setdefault(item,value)else:if item not in mat[index]:mat[index][item] = valueelse:mat[index][item] += value# 使用训练集,初始化user_tags, tag_items, user_items
def initStat():records=train_datafor u,items in records.items():for i,tags in items.items():for tag in tags:#print tag# 用户和tag的关系addValueToMat(user_tags, u, tag, 1)# tag和用户的关系addValueToMat(tag_users, tag, u, 1)# tag和item的关系addValueToMat(tag_items, tag, i, 1)# 用户和item的关系addValueToMat(user_items, u, i, 1)print("user_tags, tag_items, user_items,tag_users初始化完成.")print("user_tags大小 %d, tag_items大小 %d, user_items大小 %d, tag_users大小 %d" % (len(user_tags), len(tag_items), len(user_items),len(tag_users)))# 对用户user推荐Top-N
def recommend(user, N):recommend_item=dict()# 对Item进行打分,分数为所有的(用户对某标签使用的次数 utn, 乘以 商品被打上相同标签的次数 utn, 除以( 1加上所有用户打某标签的总数 )的自然对数)之和tagged_items = user_items[user]for tag, utn in user_tags[user].items():for item, wti in tag_items[tag].items():if item in tagged_items:continueif item not in recommend_item:recommend_item[item] = utn * utn / math.log(1 + sum(tag_users[tag].values()))else:recommend_item[item] += utn * utn / math.log(1 + sum(tag_users[tag].values()))return sorted(recommend_item.items(), key=operator.itemgetter(1), reverse=True)[0:N]# 使用测试集,计算准确率和召回率
def precisionAndRecall(N):hit = 0h_recall = 0h_precision = 0for user,items in test_data.items():if user not in train_data: # 对user不属于train_data的跳过continue# 获取Top-N推荐列表rank = recommend(user, N)for item,rui in rank:if item in items:hit = hit + 1h_recall = h_recall + len(items)h_precision = h_precision + N#print('一共命中 %d 个, 一共推荐 %d 个, 用户设置tag总数 %d 个' %(hit, h_precision, h_recall))# 返回准确率 和 召回率return (hit/(h_precision*1.0)), (hit/(h_recall*1.0))# 使用测试集,对推荐结果进行评估
def testRecommend():print("推荐结果评估")print("%3s %10s %10s" % ('N',"精确率",'召回率'))for n in [5,10,20,40,60,80,100]:precision,recall = precisionAndRecall(n)print("%3d %10.3f%% %10.3f%%" % (n, precision * 100, recall * 100))# 3. 数据加载
load_data()
# 4.将训练集,测试集拆分,20%测试集
train_test_split(0.2)
# 5.使用训练集,初始化user_tags, tag_items, user_items
initStat()
# 6.根据数据进行推荐,算出Top-N
testRecommend()
# 代码结果如下:
'''开始数据加载...userID  bookmarkID  tagID      timestamp0       8           1      1  12892553620001       8           2      1  12892551590002       8           7      1  12892389010003       8           7      6  12892389010004       8           7      7  1289238901000数据集大小为 437593.设置tag的人数 1867.数据加载完成训练集样本数 1860, 测试集样本数 1793user_tags, tag_items, user_items,tag_users初始化完成.user_tags大小 1860, tag_items大小 36884, user_items大小 1860, tag_users大小 36884推荐结果评估N        精确率        召回率5      0.739%      0.316%10      0.521%      0.446%20      0.378%      0.647%40      0.283%      0.968%60      0.234%      1.203%80      0.216%      1.481%100      0.195%     1.673%
'''

2.2对Titanic数据进行清洗,使用之前介绍过的10种模型中的至少2种(包括TPOT)

数据集地址:

# -*- encoding: utf-8 -*-
"""
@File    : titanic_svc.py
@Time    : 2020/11/15 12:50
@Author  : biao chen
@Email   : 1259319710@qq
@Software: PyCharm
"""
"""实现步骤:1.导入相关模块2.读取数据3.数据处理4.特征选择5.训练模型6.调用模型"""
# 忽略警告
import warnings
warnings.filterwarnings('ignore')# 引入数据处理包
import numpy as np
import pandas as pd# 引入算法包
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import BaggingRegressor
from sklearn.svm import SVC, LinearSVC
from sklearn.ensemble import RandomForestClassifier,GradientBoostingClassifier
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.linear_model import Perceptron
from sklearn.linear_model import SGDClassifier
from sklearn.linear_model import Perceptron
from xgboost import XGBClassifier# 引入帮助分析数据的包
from sklearn.model_selection import train_test_split,StratifiedKFold,cross_val_score
from sklearn.feature_selection import RFECV
import sklearn.preprocessing as preprocessing
from sklearn.metrics import accuracy_score
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score# 2.数据加载
train_data = pd.read_csv('train.csv')
test_data = pd.read_csv('test.csv')
full = train_data.append(test_data, ignore_index=True)   # 保证train和test的数据格式一样# 3.数据处理
titanic = full[:891]
titanic_pre = full[891:]
full = full.drop(['Cabin', 'PassengerId', 'Ticket'], axis=1)full['Sex'] = full['Sex'].map({'female': 1, 'male': 4}).astype(int)full['Pclass*Sex'] = full.Pclass * full.Sexfull['Pclass*Sex'] = pd.factorize(full['Pclass*Sex'])[0]full['Title'] = full.Name.str.extract(' ([A-Za-z]+)\.', expand=False)full['Title'] = full['Title'].replace(['Capt', 'Col', 'Don', 'Dr','Jonkheer','Major', 'Rev', 'Sir'], 'Male_Rare')full['Title'] = full['Title'].replace(['Countess', 'Lady','Mlle', 'Mme', 'Ms'], 'Female_Rare')title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Female_Rare": 5, 'Male_Rale':6}
full['Title'] = full['Title'].map(title_mapping)
full['Title'] = full['Title'].fillna(0)full['FamilySize'] = full['Parch'] + full['SibSp'] + 1full.loc[full['FamilySize'] == 1, 'Family'] = 0
full.loc[(full['FamilySize'] > 1) & (full['FamilySize'] < 5), 'Family'] = 1
full.loc[(full['FamilySize'] >= 5), 'Family'] = 2dataset = full[['Age', 'Sex', 'Pclass']]guess_ages = np.zeros((2, 3))l = [1, 4]
for i in range(len(l)):for j in range(0, 3):guess_df = dataset[(dataset['Sex'] == l[i]) & (dataset['Pclass'] == j + 1)]['Age'].dropna()age_guess = guess_df.median()# Convert random age float to nearest .5 ageguess_ages[i, j] = int(age_guess / 0.5 + 0.5) * 0.5print(guess_ages)for i in range(len(l)):for j in range(0, 3):dataset.loc[(dataset.Age.isnull()) & (dataset.Sex == l[i]) & (dataset.Pclass == j + 1), 'Age'] = guess_ages[i, j]full['Age'] = dataset['Age'].astype(int)full.loc[full['Age'] <= 20, 'Age'] = 4
full.loc[(full['Age'] > 20) & (full['Age'] <= 40), 'Age'] = 5
full.loc[(full['Age'] > 40) & (full['Age'] <= 60), 'Age'] = 6
full.loc[full['Age'] > 60, 'Age'] = 7full['Pclass*Age'] = full.Pclass * full.Agefreq_port = full.Embarked.dropna().mode()[0]
full['Embarked'] = full['Embarked'].fillna(freq_port)full[['Embarked', 'Survived']].groupby(['Embarked'], as_index=False).mean().sort_values(by='Survived', ascending=False)full['Embarked'] = full['Embarked'].map({'S': 0, 'C': 1, 'Q': 2}).astype(int)# Fare预测数据特征里面也有缺失值,需要填充
# 用中位数进行填充, 然后划分Fare段full['Fare'].fillna(full['Fare'].dropna().median(), inplace=True)full.loc[full['Fare'] <= 128.082, 'Fare'] = 0
full.loc[(full['Fare'] > 128.082) & (full['Fare'] <= 256.165), 'Fare'] = 1
full.loc[(full['Fare'] > 256.165) & (full['Fare'] <= 384.247), 'Fare'] = 2
full.loc[full['Fare'] > 384.247, 'Fare'] = 3
full['Fare'] = full['Fare'].astype(int)full = full.drop(['Name'], axis=1)full = full.drop(['Parch', 'SibSp', 'FamilySize'], axis=1)full['Sex'] = full['Sex'].astype('int').astype('str')
full = pd.get_dummies(full, prefix='Sex')full['Embarked'] = full['Embarked'].astype('str')
full = pd.get_dummies(full, prefix='Embarked')full['Title'] = full['Title'].astype('str')full = pd.get_dummies(full, prefix='Title')full = full.drop(['Survived'], axis=1)def COMPARE_MODEL(train_valid_X, train_valid_y):def cross_model(model, train_X, train_y):cvscores = cross_val_score(model, train_X, train_y, cv=3, n_jobs=-1)return round(cvscores.mean() * 100, 2)train_X, valid_X, train_y, valid_y = train_test_split(train_valid_X, train_valid_y, train_size=.78, random_state=0)def once_model(clf):clf.fit(train_X, train_y)y_pred = clf.predict(valid_X)return round(accuracy_score(y_pred, valid_y) * 100, 2)logreg = LogisticRegression()acc_log = cross_model(logreg, train_valid_X, train_valid_y)acc_log_once = once_model(logreg)xgbc = XGBClassifier()acc_xgbc = cross_model(xgbc, train_valid_X, train_valid_y)acc_xgbc_once = once_model(xgbc)svc = SVC()acc_svc = cross_model(svc, train_valid_X, train_valid_y)acc_svc_once = once_model(svc)knn = KNeighborsClassifier(n_neighbors=3)acc_knn = cross_model(knn, train_valid_X, train_valid_y)acc_knn_once = once_model(knn)gaussian = GaussianNB()acc_gaussian = cross_model(gaussian, train_valid_X, train_valid_y)acc_gaussian_once = once_model(gaussian)perceptron = Perceptron()acc_perceptron = cross_model(perceptron, train_valid_X, train_valid_y)acc_perceptron_once = once_model(perceptron)linear_svc = LinearSVC()acc_linear_svc = cross_model(linear_svc, train_valid_X, train_valid_y)acc_linear_svc_once = once_model(linear_svc)sgd = SGDClassifier()acc_sgd = cross_model(sgd, train_valid_X, train_valid_y)acc_sgd_once = once_model(sgd)decision_tree = DecisionTreeClassifier()acc_decision_tree = cross_model(decision_tree, train_valid_X, train_valid_y)acc_decision_tree_once = once_model(decision_tree)random_forest = RandomForestClassifier(n_estimators=100)acc_random_forest = cross_model(random_forest, train_valid_X, train_valid_y)acc_random_forest_once = once_model(random_forest)gbc = GradientBoostingClassifier()acc_gbc = cross_model(gbc, train_valid_X, train_valid_y)acc_gbc_once = once_model(gbc)models = pd.DataFrame({'Model': ['XGBC', 'Support Vector Machines', 'KNN', 'Logistic Regression','Random Forest', 'Naive Bayes', 'Perceptron','Stochastic Gradient Decent', 'Linear SVC','Decision Tree', 'GradientBoostingClassifier'],'Score': [acc_xgbc, acc_svc, acc_knn, acc_log,acc_random_forest, acc_gaussian, acc_perceptron,acc_sgd, acc_linear_svc, acc_decision_tree, acc_gbc]})models_once = pd.DataFrame({'Model': ['XGBC', 'Support Vector Machines', 'KNN', 'Logistic Regression','Random Forest', 'Naive Bayes', 'Perceptron','Stochastic Gradient Decent', 'Linear SVC','Decision Tree', 'GradientBoostingClassifier'],'Score': [acc_xgbc_once, acc_svc_once, acc_knn_once, acc_log_once,acc_random_forest_once, acc_gaussian_once, acc_perceptron_once,acc_sgd_once, acc_linear_svc_once, acc_decision_tree_once, acc_gbc_once]})models = models.sort_values(by='Score', ascending=False)models_once = models_once.sort_values(by='Score', ascending=False)return models, models_oncetrain_valid_X = full[0:891]
train_valid_y = titanic.Survived
test_X = full[891:]
train_X, valid_X, train_y, valid_y = train_test_split(train_valid_X, train_valid_y, train_size=.78, random_state=0)print(full.shape, train_X.shape, valid_X.shape, train_y.shape, valid_y.shape, test_X.shape)models_cross, models_once = COMPARE_MODEL(train_valid_X, train_valid_y)xgbc = XGBClassifier()
xgbc.fit(train_valid_X, train_valid_y)
test_Y_xgbc = xgbc.predict(test_X)
passenger_id = titanic_pre.PassengerIdtest = pd.DataFrame({'PassengerId': passenger_id, 'Survived': np.round(test_Y_xgbc).astype('int32')})
test.to_csv('titanic_pred_gbdc_sc.csv', index=False)
2.2.1利用tpot实现titanic
# -*- encoding: utf-8 -*-
"""
@File    : titanic_tpot.py
@Time    : 2020/11/14 23:55
@Author  : biao chen
@Email   : 1259319710@qq
@Software: PyCharm
"""# 使用TPOP对titanic进行分类
# 1. 导入相关模块
from tpot import TPOTClassifier
from sklearn.model_selection import train_test_split
import pandas as pd# 2. 读取数据
data = pd.read_csv('train.csv')# 3. 数据处理
data['Survived'].value_counts().plot.pie(autopct='%0.2f%%')
data.Embarked[data.Embarked.isnull()] = data.Embarked.dropna().mode().values#众数填充
from sklearn.ensemble import RandomForestRegressor
age_df = data[['Age','Survived','Fare', 'Parch', 'SibSp', 'Pclass']]
age_df_notnull = age_df.loc[(data['Age'].notnull())] #选择age不为空的行
age_df_isnull = age_df.loc[(data['Age'].isnull())]X = age_df_notnull.values[:,1:]
Y = age_df_notnull.values[:,0]RFR = RandomForestRegressor(n_estimators=1000, n_jobs=-1)
RFR.fit(X,Y)
predictAges = RFR.predict(age_df_isnull.values[:,1:])
data.loc[data['Age'].isnull(), ['Age']]= predictAges
df =pd.get_dummies(data)
x=df.drop('Survived',1)
y=df.Survived
x_train,x_test,y_train,y_test = train_test_split(x, y, test_size=0.2, random_state=0)# 划分数据集
# 4. 使用TPOT寻找最佳模型和参数
tpot = TPOTClassifier(generations=5, population_size=20, verbosity=2)
tpot.fit(x_train, y_train)
print(tpot.score(x_test, y_test))
tpot.export('tpot_titanic_pipeline.py') # 生成最佳代码文件
2.2.2利用tpot生成的代码文件
# tpot_titanic_pipeline.py
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline, make_union
from tpot.builtins import StackingEstimator
from sklearn.ensemble import RandomForestRegressor
from xgboost import XGBClassifier# NOTE: Make sure that the outcome column is labeled 'target' in the data file
data = pd.read_csv('train.csv')
data['Survived'].value_counts().plot.pie(autopct='%0.2f%%')
data.Embarked[data.Embarked.isnull()] = data.Embarked.dropna().mode().values#众数填充age_df = data[['Age','Survived','Fare', 'Parch', 'SibSp', 'Pclass']]
age_df_notnull = age_df.loc[(data['Age'].notnull())] #选择age不为空的行
age_df_isnull = age_df.loc[(data['Age'].isnull())]X = age_df_notnull.values[:,1:]
Y = age_df_notnull.values[:,0]RFR = RandomForestRegressor(n_estimators=1000, n_jobs=-1)
RFR.fit(X,Y)
predictAges = RFR.predict(age_df_isnull.values[:,1:])
data.loc[data['Age'].isnull(), ['Age']]= predictAges
df =pd.get_dummies(data)
x=df.drop('Survived',1)
y = df.Survived
x_train,x_test,y_train,y_test = train_test_split(x, y, test_size=0.2, random_state=0)# 划分数据集# Average CV score on the training set was: 0.8272628779671033
exported_pipeline = make_pipeline(StackingEstimator(estimator=MultinomialNB(alpha=1.0, fit_prior=False)),XGBClassifier(learning_rate=0.01, max_depth=10, min_child_weight=2, n_estimators=100, nthread=1, subsample=0.9000000000000001)
)exported_pipeline.fit(x_train, y_train)
results = exported_pipeline.predict(x_test)
acc_xgb = round(exported_pipeline.score(x_train, y_train) * 100, 2)
# xgboost 准确率: 90.17
print("xgboost 准确率:",acc_xgb)

更多推荐

【BI学习作业03

本文发布于:2024-02-12 18:09:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1688850.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:作业   BI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!