《精通特征工程》学习笔记(3):特征缩放的效果-从词袋到tf-idf

news2025/4/15 14:45:56

1.TF-IDF原理

tf-idf 是在词袋方法基础上的一种简单扩展,它表示词频 - 逆文档频率。tf-idf 计算的不是数据集中每个单词在每个文档中的原本计数,而是一个归一化的计数,其中每个单词的计数要除以这个单词出现在其中的文档数量。

  • 词袋bow(w, d) = 单词 w 在文档 d 中出现的次数
  • tf-idf(w, d) = bow(w, d) * N / ( 单词 w 出现在其中的文档数量 )

N 是数据集中的文档总数。分数 N / ( 单词 w 出现在其中的文档的数量 ) 就是所谓的逆文档频率。如果一个单词出现在很多文档中,那么它的逆文档频率就接近于 1。如果一个单词只出现在少数几个文档中,那么它的逆文档频率就会高得多。

也可以使用逆文档频率的对数变换,而不是它的原始形式,那么就可以有效地将一个几乎出现在所有单个文档中的单词的计数归零,而一个只出现在
少数几个文档中的单词的计数将会被放大。即对数变换可以将 1 转换为0,并使大的数值(那些远远大于 1 的值)变小:

  • tf-idf(w, d) = bow(w, d) * log(N / 单词 w 出现在其中的文档数量 )

tf-idf 突出了罕见词,并有效地忽略了常见词。

tf-idf 通过乘以一个常数,对单词计数特征进行了转换。因此,它是一种特征缩放方法。比较一下缩放特征和未缩放特征的效果:
练习的目的是比较一下词袋、tf-idf 和 ℓ 2 归一化在线性分类问题中的效果。

1.1数据读取、拼接

import json
import numpy as np
import pandas as pd
from sklearn.feature_extraction import text
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import sklearn.preprocessing as preproc


# 加载商家数据
biz_f = open(r'..\data\yelp_academic_dataset_business.json')
biz_df = pd.DataFrame([json.loads(x) for x in biz_f.readlines()])
biz_f.close()

# 加载点评数据
review_file = open(r'..\data\yelp_academic_dataset_review.json')
review_df = pd.DataFrame([json.loads(x) for x in review_file.readlines()])
review_file.close()

# 选出夜店和餐馆
two_biz = biz_df[biz_df.apply(lambda x: 'Nightlife' in x['categories'] or 'Restaurants' in x['categories'],axis=1)]
two_biz.head(3)
# 与点评数据连接,得到两种类型商家的所有点评
twobiz_reviews = two_biz.merge(review_df, on='business_id', how='inner')
twobiz_reviews.head()
# 去除不需要的特征
twobiz_reviews = twobiz_reviews[['business_id','name','stars_y','text','categories']]
twobiz_reviews.head()
# 创建目标列——夜店类型的商家为True,否则为False
twobiz_reviews['target'] = twobiz_reviews.apply(lambda x: 'Nightlife' in x['categories'],axis=1)
twobiz_reviews.head(20)

在这里插入图片描述

序列化特征并保存特征到文件

twobiz_reviews.to_pickle('twobiz_reviews.pkl')

从文件读取序列化特征到程序并转为二维表

twobiz_reviews = pd.read_pickle('twobiz_reviews.pkl')
twobiz_reviews.head(3)

在这里插入图片描述

1.2创建分类数据集(拆分数据)

看看能否通过点评数据区分出一个商家是餐馆还是夜店。为了节省训练时间,我们可以取点评数据的一个子集。在这个例子中,两类商家的点评数量相差很大,这称为类别不平衡数据集。不平衡数据集的建模有些问题,因为模型会将大部分努力用于拟合优势类别。因为在两个类别中我们都有很多数据,所以解决这个问题的一种好的做法是对优势类别(餐馆)进行下采样,使它的数量与劣势类别(夜店)基本相当。

  • 对夜店点评数据进行 10% 的随机抽样,对餐馆点评数据进行 2.1% 的随机抽样(选择这样的比例可以使两个类别的抽样数据基本相当)。
  • 按照 70/30 的比例将这个数据集划分为训练集和测试集。在这个例子中,训练集有 29264 条点评数据,测试集有 12 542 条点评数据。
  • 训练数据包含 46 924 个唯一单词,这就是词袋表示法的特征数量。
# 创建一个类别平衡的子样本,供练习使用
nightlife = twobiz_reviews[twobiz_reviews.apply(lambda x: 'Nightlife' in x['categories'], axis=1)]
restaurants = twobiz_reviews[twobiz_reviews.apply(lambda x: 'Restaurants' in x['categories'], axis=1)]
#如下目前类别极度不平衡
print(nightlife.shape)
print(restaurants.shape)

# 进行随机取样,达到类别平衡
nightlife_subset = nightlife.sample(frac=0.1, random_state=123)
restaurant_subset = restaurants.sample(frac=0.021, random_state=123)
print(nightlife_subset.shape)
print(restaurant_subset.shape)
# 序列化:
nightlife_subset.to_pickle('nightlife_subset.pkl')
restaurant_subset.to_pickle('restaurant_subset.pkl')

nightlife_subset = pd.read_pickle('nightlife_subset.pkl')
restaurant_subset = pd.read_pickle('restaurant_subset.pkl')
# 拼接两个类型的店起来:
combined = pd.concat([nightlife_subset, restaurant_subset])
combined['target'] = combined.apply(lambda x: 'Nightlife' in x['categories'],axis=1)#添加一列作为标签
combined
# 划分训练集和测试集
from sklearn.model_selection import train_test_split
training_data, test_data = train_test_split(combined, train_size=0.7, random_state=123)
print(training_data.shape)
print(test_data.shape)

1.3使用tf-idf变换来缩放词袋

做完 tf-idf 后再进行 ℓ 2 归一化等同于只做 ℓ2归一化。所以,我们只需要测试三组特征:词袋、tf-idf,以及词袋基础上的 ℓ 2 归一化。

# 用词袋表示点评文本
bow_transform = text.CountVectorizer()
X_tr_bow = bow_transform.fit_transform(training_data['text'])
X_te_bow = bow_transform.transform(test_data['text'])
y_tr = training_data['target']
y_te = test_data['target']
# 使用词袋矩阵创建tf-idf表示
tfidf_trfm = text.TfidfTransformer(norm=None)
X_tr_tfidf = tfidf_trfm.fit_transform(X_tr_bow)
X_te_tfidf = tfidf_trfm.transform(X_te_bow)
# 对词袋表示进行l2归一化
X_tr_l2 = preproc.normalize(X_tr_bow, axis=0)
X_te_l2 = preproc.normalize(X_te_bow, axis=0)

特征缩放的微妙之处在于,它要求我们知道一些实际中我们很可能不知道的特征统计量,比如均值、方差、文档频率、ℓ 2 范数,等等。为了计算出 tf-idf表示,我们必须基于训练数据计算出逆文档频率,并用这些统计量既缩放训练数据也缩放测试数据。

在 scikit-learn 中,在训练数据上拟合特征转换器相当于收集相关统计量。然后可以将拟合好的特征转换器应用到测试数据上。特征缩放的微妙之处在于,它要求我们知道一些实际中我们很可能不知道的特征统计量,比如均值、方差、文档频率、ℓ 2 范数,等等。

为了计算出 tf-idf表示,我们必须基于训练数据计算出逆文档频率,并用这些统计量既缩放训练数据也缩放测试数据。在 scikit-learn 中,在训练数据上拟合特征转换器相当于收集相关统计量。然后可以将拟合好的特征转换器应用到测试数据上。

1.4使用逻辑回归进行分类

# 使用不同的特征(上面那三种)进行逻辑回归分类:
def simple_logistic_classify(X_tr, y_tr, X_test, y_test, description, _C=1.0):
    ## 函数训练一个逻辑分类器,并对测试数据进行评分
    m = LogisticRegression(C=_C).fit(X_tr, y_tr)
    s = m.score(X_test, y_test)
    print ('Test score with', description, 'features:', s)
    return m
m1 = simple_logistic_classify(X_tr_bow, y_tr, X_te_bow, y_te, 'bow')
m2 = simple_logistic_classify(X_tr_l2, y_tr, X_te_l2, y_te, 'l2-normalized')
m3 = simple_logistic_classify(X_tr_tfidf, y_tr, X_te_tfidf, y_te, 'tf-idf')

1.5使用正则化对逻辑回归进行调参优化

当特征数量大于数据点数量时,找出最佳模型这个问题就变得不确定了。解决这个问题的一种方法是在训练过程中加入额外的限制条件,这就是正则化。

种基本的超参数调优方法称为网格搜索:先确定一个超参数网格,然后使用调优程序自动搜索,找到网格中的最优超参数设置。找到最优超参数设置之后,你可以使用该设置在整个训练集上训练一个模型,然后使用它在测试集上的表现作为这类模型的最终评价。(这里要调正则化参数)

tf-idf 和词袋之间的准确度差别是否是由噪声造成的。为此,我们使用k-折交叉验证来模拟多个统计独立的数据集,把数据集分成 k 折。交叉验证过程会在这些
数据子集中迭代进行,使用除一折数据之外的所有数据进行训练,而用保留的那一折数据来验证结果。

# 使用网格搜索对逻辑回归进行调优
import sklearn.model_selection as modsel

param_grid_ = {'C': [1e-5, 1e-3, 1e-1, 1e0, 1e1, 1e2]}
# 为词袋表示法进行分类器调优
bow_search = modsel.GridSearchCV(LogisticRegression(), cv=5, param_grid=param_grid_)
# 为L2-归一化词向量进行分类器调优
l2_search = modsel.GridSearchCV(LogisticRegression(), cv=5,param_grid=param_grid_)
# 为tf-idf进行分类器调优
tfidf_search = modsel.GridSearchCV(LogisticRegression(), cv=5,param_grid=param_grid_)

1.5.1为词袋表示法进行分类器调优

bow_search.fit(X_tr_bow, y_tr)
print(bow_search.best_score_)
bow_search.best_params_

1.5.2为L2-归一化词向量进行分类器调优

l2_search.fit(X_tr_bow, y_tr)
print(l2_search.best_score_)
l2_search.best_params_

1.5.3为tf-idf进行分类器调优

tfidf_search.fit(X_tr_bow, y_tr)
print(tfidf_search.best_score_)
tfidf_search.best_params_

1.5.4可以查看网格所受的cv结果看看它的过程

bow_search.cv_results_
l2_search.cv_results_
tfidf_search.cv_results_

1.5.5对三个分类器性能进行可视化比较

# 对三个分类器性能进行可视化比较
search_results = pd.DataFrame.from_dict({'bow': bow_search.cv_results_['mean_test_score'],
                               'tfidf': tfidf_search.cv_results_['mean_test_score'],
                               'l2': l2_search.cv_results_['mean_test_score']})
search_results

在这里插入图片描述

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("whitegrid")

ax = sns.boxplot(data=search_results, width=0.4)
ax.set_ylabel('Accuracy', size=14)
ax.tick_params(labelsize=14)
plt.savefig('tfidf_gridcv_results.png')
# 如下

在这里插入图片描述

1.5.6使用最佳参数去拟合模型

# 使用最佳参数去拟合模型
m1 = simple_logistic_classify(X_tr_bow, y_tr, X_te_bow, y_te, 'bow', 
                              _C=bow_search.best_params_['C'])
m2 = simple_logistic_classify(X_tr_l2, y_tr, X_te_l2, y_te, 'l2-normalized', 
                              _C=l2_search.best_params_['C'])
m3 = simple_logistic_classify(X_tr_tfidf, y_tr, X_te_tfidf, y_te, 'tf-idf', 
                              _C=tfidf_search.best_params_['C'])
Test score with bow features: 0.7682606410930111
Test score with l2-normalized features: 0.6784025223331581
Test score with tf-idf features: 0.766684182869154

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/619578.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

面向对象的特征三:多态性

1.多态性的理解: 可以理解为一个事物的多种形态。 2.何为多态性: 对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用) 可以直接应用在抽象类和接口上 举例:Person p new Man(); O…

场景营销解密:出海品牌在全球市场的差异化策略

品牌出海是企业扩大国际市场份额、实现全球化发展的必经之路。然而,面对激烈的全球竞争和多样化的消费者需求,仅仅依靠传统的广告宣传手段已经无法满足品牌推广的需求。而场景营销则通过创造具有情境感的消费体验,更好地满足了消费者的参与需…

手写分布式事务的一种回滚方案。

1:项目架构 我一个朋友的公司基于实际业务的考虑,选择了多个单体项目来组建成一个分布式系统。(对于目前来说分布式的系统最好采用微服务的架构来实现项目搭建。但基于许多客户只能采用内网的使用,微服务反而会影响项目的复杂度&a…

STM32ADC学习(一)

ADC 模拟/数字转换器 常见ADC类型 并联比较型工作示意图 ADC的特性参数 分辨率:ADC能辨别的最小模拟量,用二进制位数来表示。例如3.3V,12位,能辨别的最小模拟量就是:(3.3/4096)转换时间&#x…

【面试题HTTP中的两种请求方法】GET 和 POST 有什么区别?

GET 和 POST 有什么区别? 1.相同点和最本质的区别1.1 相同点1.2 最本质的区别 2.非本质区别2.1 缓存不同2.2 参数长度限制不同2.3 回退和刷新不同2.4 历史记录不同2.5 书签不同 总结代码示例 GET 和 POST 是 HTTP 请求中最常用的两种请求方法,在日常开发…

练手必备,20个Python实战项目含源代码

“读”代码是不能给你带来任何收益的,正如“读书”一样,如果在读的时候你不琢磨,保管你读完仨月准忘了一大半。真正需要的是去“试”代码,动手去调调代码,改改这改改那,看看把A变成B这个代码的结果会有什么…

c#使用RSA公钥解密

文章目录 前言一、解密函数1、上代码!2、传入的字符串不是base64格式 二、在线验证总结 前言 新项目对接第三方,会把用户信息反正url里面rsa加密传过来,拿到后我解密出用户数据,只给了一个公钥,他们用的java、我用的c…

SpringBoot生成RESTful API文档

由于我一开始学习的SpringBoot是3以上版本,所以我这里用到的也是支持和SpringBoot3能够整合的SpringDoc 这里先说一下,其实SpringDoc就是Swagger3版本,我一开始整合的2版本,比较麻烦况且最后SpringBoot程序都启动不了了&#xff0…

怎样书写专业的落地性能测试计划?

目录 引言 什么是性能测试计划 性能测试计划包含的内容 背景 性能目标 压测范围 启停准则 性能指标 系统架构图 压测前准备 工具准备 数据准备 性能设计 监控设计 项目组织架构 成果输出 项目风险分析 引言 测试计划是软件测试流程中的一个重要步骤,它涉及到对软件…

面向教育行业的MDM(移动设备管理)解决方案

什么是面向教育的MDM 学校和教育机构的移动设备管理 (MDM) 通过将智能设备配置为适合教育用途,支持通过这些设备进行学习。面向教育的 MDM 解决方案允许组织的 IT 管理员或教学人员管理有助于学习的设备,如智能手机、平板电脑、笔…

十三、输出多个立方体并深度测试

第一部分概念 1)由来: 深度测试:opengl的深度测试是指在片段着色器执行之后,利用深度缓冲所保存的深度值决定当前片段是否被丢弃的过程。 深度缓冲区和颜色缓冲区是差不多的,有相同的宽高度,并且一般在窗…

实验篇(7.2) 06. 通过安全隧道访问远端内网服务器 (FortiClient-SSL) ❀ 远程访问

【简介】直接映射服务器到公网,没有验证不安全;通过Web浏览器访问远程内网服务器,有验证也安全,但是支持的协议太少。那有没有即安全,又能支持所有协议的访问方法呢?我们来看看SSL VPN的隧道模式。 实验要求…

智能动环监控系统,实时排查机房安全隐患

动环监控系统又称机房动环、机房动力环境监控系统、动环监控等, 是指对各机房的动力、环境、安防进行集中监测。可对监控系统、设备、安全运行状态进行实时监测、通过统计和处理相关数据,及早发现故障,及时通知运维人员处理;实现机…

员工工作服穿戴AI识别算法 yolov5

员工工作服穿戴AI识别算法是基于yolov5python网络模型人工智能技术,员工工作服穿戴AI识别算法对现场人员的工作服穿戴情况进行实时监控,并对违规情况将自动发出警报。我们选择当下YOLO卷积神经网络YOLOv5来进行火焰识别检测。现版本的YOLOv5每个图像的推…

高并发下缓存失效问题(穿透、雪崩、击穿),以及本地锁、Redis分布锁、Redisson锁、SpringCache使用

高并发下缓存失效问题-穿透、雪崩、击穿 1.缓存穿透2.缓存雪崩3.缓存穿透4.加锁4.1 本地锁4.2 Redis分布锁4.3 RedLock 分布式锁-Redisson**4.3.1 整合Redisson实现分布式锁**4.3.2 分布式锁 1)分布式锁 - - 可重入锁 2)分布式锁 - - 公平锁 3&#xff0…

Spring面试题(基础篇)

目录 一、Spring框架概述 1、什么是Spring? 2、spring优点有哪些? 二、IOC与DI 3、你知道getBean方法的有几种重载方式吗? 4、Spring有几种依赖注入方式? 三、Spring创建对象 5、Spring创建对象有几种方式? 6…

SciencePub学术 | 可再生能源类重点SCIEI征稿中

SciencePub学术刊源推荐: 可再生能源类重点SCI&EI征稿中!2区闭源正刊,进展顺利,稳定检索40年以上。信息如下,录满为止: 一、期刊概况: 可再生能源类重点SCI&EI 【期刊简介】IF:4.0-4.…

Win安装kafka

Win安装kafka 安装zookeeper修改zookeeper 配置文件 安装kafka启动kafka创建topic查看topic命令 用命令发布消息消费命令 安装zookeeper https://zookeeper.apache.org/releases.html 解压到文件夹 同时在解压目录中拆创建 data和 log文件夹 修改zookeeper 配置文件 - 复制 …

小程序多选框问题

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 例如&#xff1a;前端小程序记录错误bug 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 例如&#xff1a;前端循环数组时页面数据无法显示 <checkbox-group bindchange"…

【greenplum 性能优化】greenplum 数据库集群 如何释放占用内存

无意中发现了一个巨牛的人工智能教程&#xff0c;忍不住分享一下给大家。教程不仅是零基础&#xff0c;通俗易懂&#xff0c;而且非常风趣幽默&#xff0c;像看小说一样&#xff01;觉得太牛了&#xff0c;所以分享给大家。点这里可以跳转到教程。人工智能教程 在Greenplum数据…