[scikit-learn 机器学习] 4. 特征提取


本文为 scikit-learn机器学习(第2版)学习笔记

许多机器学习问题需要从 类别变量、文本、图片中学习,需要从中提取出数字特征

1. 从类别变量中提取特征

通常使用 one-hot 编码,产生2进制的编码,会扩展数据,当数据值种类多时,不宜使用

from sklearn.feature_extraction import DictVectorizer
onehot_encoder = DictVectorizer()
X=[{'city':'Beijing'},{'city':'Guangzhou'},{'city':'Shanghai'}
]
print(onehot_encoder.fit_transform(X).toarray())
[[1. 0. 0.][0. 1. 0.][0. 0. 1.]]

one-hot 编码,没有顺序或大小之分,相比于用 0, 1, 2 来表示上述 3 个city,one-hot编码更好

  • DictVectorizer 只针对 string 变量,如果分类变量是数字类型,请使用 sklearn.preprocessing.OneHotEncoder

this transformer will only do a binary one-hot encoding when feature values are of type string.

If categorical features are represented as numeric values such as int, the DictVectorizer can be followed by sklearn.preprocessing.OneHotEncoder to complete binary one-hot encoding.

  • DictVectorizer 对数字特征 失效案列:
X=[{'city':1},{'city':4},{'city':5}
]
onehot_encoder = DictVectorizer()
print(onehot_encoder.fit_transform(X).toarray())
[[1.][4.][5.]]
  • OneHotEncoder 既可针对 string 类型,也可以对数字类型,进行编码
# string 类型
from sklearn.preprocessing import OneHotEncoder
import pandas as pd
onehot_encoder = OneHotEncoder()
X=[{'city':'Beijing'},{'city':'Guangzhou'},{'city':'Shanghai'}
]
X = pd.DataFrame(X)
print(onehot_encoder.fit_transform(X).toarray())
[[1. 0. 0.][0. 1. 0.][0. 0. 1.]]
# 数字类型
onehot_encoder = OneHotEncoder()
X=[{'city':1},{'city':4},{'city':5}
]
X = pd.DataFrame(X)
print(onehot_encoder.fit_transform(X).toarray())
[[1. 0. 0.][0. 1. 0.][0. 0. 1.]]

2. 特征标准化

  • 防止特征淹没,某些特征无法发挥作用
  • 加快算法收敛
from sklearn import preprocessing
import numpy as np
X = np.array([[0., 0., 5., 13., 9., 1.],[0., 0., 13., 15., 10., 15.],[0., 3., 15., 2., 0., 11.]
])
s = preprocessing.StandardScaler()
print(s.fit_transform(X))

StandardScaler 均值为0,方差为1

[[ 0.         -0.70710678 -1.38873015  0.52489066  0.59299945 -1.35873244][ 0.         -0.70710678  0.46291005  0.87481777  0.81537425  1.01904933][ 0.          1.41421356  0.9258201  -1.39970842 -1.4083737   0.33968311]]

RobustScaler 对异常值有更好的鲁棒性,减轻异常值的影响

This Scaler removes the median and scales the data according to the quantile range (defaults to IQR: Interquartile Range).

The IQR is the range between the 1st quartile (25th quantile) and the 3rd quartile (75th quantile).

from sklearn.preprocessing import RobustScaler
s = RobustScaler()
print(s.fit_transform(X))
[[ 0.          0.         -1.6         0.          0.         -1.42857143][ 0.          0.          0.          0.30769231  0.2         0.57142857][ 0.          2.          0.4        -1.69230769 -1.8         0.        ]]

3. 从文本中提取特征

文本通常为自然语言

3.1 词袋模型

  • 不会编码任何文本句法,忽略单词顺序,忽略语法,忽略词频
  • 可看做 one-hot 的一种扩展,会对文本中关注的每一个单词创建一个特征
  • 可用于文档分类和检索
corpus = ["UNC played Duke in basketball","Duke lost the basketball game"
]
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer()
print(vectorizer.fit_transform(corpus).todense())
# [[1 1 0 1 0 1 0 1]
# [1 1 1 0 1 0 1 0]]
print(vectorizer.vocabulary_)
# {'unc': 7, 'played': 5, 'duke': 1, 'in': 3, 
#  'basketball': 0, 'lost': 4, 'the': 6, 'game': 2}
  • 注意:只会提取长度 >= 2 的单词,添加一个句子,该句子的单词 I,a 没有向量化
corpus.append("I ate a sandwich and an apple")
print(vectorizer.fit_transform(corpus).todense())
# [[0 0 0 0 1 1 0 1 0 1 0 0 1]
#  [0 0 0 0 1 1 1 0 1 0 0 1 0]
#  [1 1 1 1 0 0 0 0 0 0 1 0 0]]
print(vectorizer.vocabulary_)
# {'unc': 12, 'played': 9, 'duke': 5, 'in': 7, 
#  'basketball': 4, 'lost': 8, 'the': 11, 'game': 6, 
#  'ate': 3, 'sandwich': 10, 'and': 1, 'an': 0, 'apple': 2}
  • 进行文本相似度计算,计算文本向量之间的欧氏距离(L2范数)
from sklearn.metrics.pairwise import euclidean_distances
X = vectorizer.fit_transform(corpus).todense()
print("distance between doc1 and doc2 ", euclidean_distances(X[0],X[1]))
print("distance between doc1 and doc3 ", euclidean_distances(X[0],X[2]))
print("distance between doc2 and doc3 ", euclidean_distances(X[1],X[2]))
# distance between doc1 and doc2  [[2.44948974]]
# distance between doc1 and doc3  [[3.16227766]]
# distance between doc2 and doc3  [[3.16227766]]

可以看出,文档1跟文档2更相似
真实环境中,词汇数量相当大,需要的内存很大,为了缓和这个矛盾,采用稀疏向量
后序还有降维方法,来降低向量的维度

3.2 停用词过滤

降维策略:

  • 所有单词转成小写,对单词的意思没有影响
  • 忽略语料库中大部分文档中经常出现的单词,如the\a\an\do \be\will\on\around等,称之 stop_words
  • CountVectorizer 可以通过 stop_words 关键词参数,过滤停用词,它本身也有一个基本的英语停用词列表
vectorizer = CountVectorizer(stop_words='english')
print(vectorizer.fit_transform(corpus).todense())
# [[0 0 1 1 0 0 1 0 1]
#  [0 0 1 1 1 1 0 0 0]
#  [1 1 0 0 0 0 0 1 0]]
print(vectorizer.vocabulary_)
# {'unc': 8, 'played': 6, 'duke': 3, 'basketball': 2, 
# 'lost': 5, 'game': 4, 'ate': 1, 'sandwich': 7, 'apple': 0}

我们发现 in\the\and\an不见了

3.3 词干提取和词形还原

停用词列表包含的词很少,过滤后依然包含很多单词怎么办?

  • 词干提取、词形还原,进一步降维

例如,jumping\jumps\jump,一篇报道跳远比赛的文章中,这几个词时分别编码的,我们可以对他们进行统一处理,压缩成单个特征

corpus = ['He ate the sandwiches','Every sandwich was eaten by him'
]
vectorizer = CountVectorizer(binary=True, stop_words='english')
print(vectorizer.fit_transform(corpus).todense())
# [[1 0 1 0]
# [0 1 0 1]]
print(vectorizer.vocabulary_)
# {'ate': 0, 'sandwiches': 2, 'sandwishes': 3, 'eaten': 1}

我们看到这两个句子表达的一个意思,特征向量却没有一个共同元素

  • Lemmatizer 词性还原
    注:NLTK WordNet 安装 参考,解压、添加路径、重新打开python即可
corpus = ['I am gathering ingredients for the sandwich.','There were many peoples at the gathering.'
]
from nltk.stem.wordnet import WordNetLemmatizer
# help(WordNetLemmatizer)
lemmatizer = WordNetLemmatizer()
print(lemmatizer.lemmatize('gathering','v')) # gather,动词
print(lemmatizer.lemmatize('gathering','n')) # gathering,名词
  • PorterStemmer 词干提取
from nltk.stem import PorterStemmer
# help(PorterStemmer)
stemmer = PorterStemmer()
print(stemmer.stem('gathering')) # gather

小例子:

from nltk import word_tokenize # 取词
from nltk.stem import PorterStemmer # 词干提取
from nltk.stem.wordnet import WordNetLemmatizer # 词性还原
from nltk import pos_tag # 词性标注wordnet_tags = ['n','v']
corpus = ['He ate the sandwiches','Every sandwich was eaten by him'
]
stemmer = PorterStemmer()
print("词干:", [[stemmer.stem(word) for word in word_tokenize(doc)] for doc in corpus])# 词干: [['He', 'ate', 'the', 'sandwich'], 
#		['everi', 'sandwich', 'wa', 'eaten', 'by', 'him']]
def lemmatize(word, tag):if tag[0].lower() in ['n','v']:return lemmatizer.lemmatize(word, tag[0].lower())return word
lemmatizer = WordNetLemmatizer()
tagged_corpus = [pos_tag(word_tokenize(doc)) for doc in corpus]print(tagged_corpus)
# [[('He', 'PRP'), ('ate', 'VBD'), ('the', 'DT'), ('sandwiches', 'NNS')], 
#  [('Every', 'DT'), ('sandwich', 'NN'), ('was', 'VBD'), 
#   ('eaten', 'VBN'), ('by', 'IN'), ('him', 'PRP')]]print('词性还原:',[[lemmatize(word,tag) for word, tag in doc] for doc in tagged_corpus])
# 词性还原: [['He', 'eat', 'the', 'sandwich'], 
#            ['Every', 'sandwich', 'be', 'eat', 'by', 'him']]对 n,v 开头的词性的单词进行了词性还原

3.4 TF-IDF 权重扩展词包

词频是很重要的,创建编码单词频数的特征向量

import numpy as np
from sklearn.feature_extraction.text import CountVectorizercorpus = ["The dog ate a sandwich, the people manufactured many sandwiches,\and I ate a sandwich"]vectorizer = CountVectorizer(stop_words='english')
freq = np.array(vectorizer.fit_transform(corpus).todense())
freq # array([[2, 1, 1, 3]], dtype=int64)
vectorizer.vocabulary_
#  {'dog': 1, 'ate': 0, 'sandwich': 3, 'people': 2}
for word, idx in vectorizer.vocabulary_.items():print(word, " 出现了 ", freq[0][idx]," 次")
dog  出现了  1  次
ate  出现了  2  次
sandwich  出现了  2  次
people  出现了  1  次
manufactured  出现了  1  次
sandwiches  出现了  1
  • sklearn 的TfidfVectorizer 可以统计单词的权值:单词频率-逆文本频率 TF-IDF
    在这里插入图片描述
from sklearn.feature_extraction.text import TfidfVectorizer
corpus = ["The dog ate a sandwich, and I ate a sandwich","the people manufactured a sandwich"]
vectorizer = TfidfVectorizer(stop_words='english')
print(vectorizer.fit_transform(corpus).todense())
print(vectorizer.vocabulary_)
[[0.75458397 0.37729199 0.         0.         0.53689271][0.         0.         0.6316672  0.6316672  0.44943642]]
{'dog': 1, 'ate': 0, 'sandwich': 4, 'people': 3, 'manufactured': 2}

3.5 空间有效特征向量化与哈希技巧

  • 书上大概意思是说可以省内存,可以用于在线流式任务创建特征向量
from sklearn.feature_extraction.text import HashingVectorizer
# help(HashingVectorizer)
corpus = ['This is the first document.','This document is the second document.']
vectorizer = HashingVectorizer(n_features=2**4)
X = vectorizer.fit_transform(corpus).todense()
print(X)
x = vectorizer.transform(['This is the first document.']).todense()
print(x)
x in X # True
[[-0.57735027  0.          0.          0.          0.          0.0.          0.         -0.57735027  0.          0.          0.0.          0.57735027  0.          0.        ][-0.81649658  0.          0.          0.          0.          0.0.          0.          0.          0.          0.          0.408248290.          0.40824829  0.          0.        ]]
[[-0.57735027  0.          0.          0.          0.          0.0.          0.         -0.57735027  0.          0.          0.0.          0.57735027  0.          0.        ]]

3.6 词向量

词向量模型相比于词袋模型更好些。

词向量模型在类似的词语上产生类似的词向量(如,small、tiny都表示小),反义词的向量则只在很少的几个维度类似

# google colab 运行以下代码
import gensim
from google.colab import drive
drive.mount('/gdrive')
# !git clone https://github.com/mmihaltz/word2vec-GoogleNews-vectors.git
! wget -c "https://s3.amazonaws.com/dl4j-distribution/GoogleNews-vectors-negative300.bin.gz"!cd /content
!gzip -d /content/GoogleNews-vectors-negative300.bin.gzmodel = gensim.models.KeyedVectors.load_word2vec_format('/content/GoogleNews-vectors-negative300.bin', binary=True)
embedding = model.word_vec('cat')
embedding.shape  # (300,)相似度
print(model.similarity('cat','dog'))  # 0.76094574
print(model.similarity('cat','sandwich'))  # 0.17211203最相似的n个单词
print(model.most_similar(positive=['good','ok'],negative=['bad'],topn=3))
# [('okay', 0.7390689849853516), 
#  ('alright', 0.7239435911178589), 
#  ('OK', 0.5975555777549744)]

4. 从图像中提取特征

4.1 从像素强度中提取特征

将图片的矩阵展平后作为特征向量

  • 有缺点,产出的模型对缩放、旋转、平移很敏感,对光照强度变化也很敏感
from sklearn import datasets
digits = datasets.load_digits()
print(digits.images[0].reshape(-1,64))
图片特征向量
[[ 0.  0.  5. 13.  9.  1.  0.  0.  0.  0. 13. 15. 10. 15.  5.  0.  0.  3.15.  2.  0. 11.  8.  0.  0.  4. 12.  0.  0.  8.  8.  0.  0.  5.  8.  0.0.  9.  8.  0.  0.  4. 11.  0.  1. 12.  7.  0.  0.  2. 14.  5. 10. 12.0.  0.  0.  0.  6. 13. 10.  0.  0.  0.]]

4.2 使用卷积神经网络激活项作为特征

不懂,暂时跳过。

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

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

相关文章

LeetCode 第 29 场双周赛(890/2259,前39.4%)

文章目录1. 比赛结果2. 题目1. LeetCode 5432. 去掉最低工资和最高工资后的工资平均值 easy2. LeetCode 5433. n 的第 k 个因子 medium3. LeetCode 5434. 删掉一个元素以后全为 1 的最长子数组 medium4. LeetCode 5435. 并行课程 II hard1. 比赛结果 做出来了3道题。第三题卡了…

【dll 返回字符串 】2

【vc <--> vc】返回void* 类型void* __stdcall torrent_hash( const char *TorrentFilePath){char szText[41]{0};if(strcmp(TorrentFilePath,"") 0 || TorrentFilePath NULL)return NULL;string strHashString "abcdefg"; sprintf(szText,&qu…

LeetCode 1496. 判断路径是否相交(set)

1. 题目 给你一个字符串 path&#xff0c;其中 path[i] 的值可以是 ‘N’、‘S’、‘E’ 或者 ‘W’&#xff0c;分别表示向北、向南、向东、向西移动一个单位。 机器人从二维平面上的原点 (0, 0) 处开始出发&#xff0c;按 path 所指示的路径行走。 如果路径在任何位置上出…

电压压力蕊片_一文让你知道什么是压力变送器

一般来说&#xff0c;压力变送器主要由测压元件传感器(也称作压力传感器)、测量电路和过程连接件三部分组成。它能将测压元件传感器感受到的气体、液体等物理压力参数转变成标准的电信号(如4~20mADC等)&#xff0c;以供给指示报警仪、记录仪、调节器等二次仪表进行测量、指示和…

C# 多线程编程 ThreadStart ParameterizedThreadStart

原文地址&#xff1a;http://club.topsage.com/thread-657023-1-1.html 在实例化Thread的实例&#xff0c;需要提供一个委托&#xff0c;在实例化这个委托时所用到的参数是线程将来启动时要运行的方法。在.net中提供了两种启动线程的方式&#xff0c;一种是不带参数的启动…

Matlab编程学习笔记【待续】

最近想用Matlab进行数据分析&#xff0c;算法性能测试&#xff0c;平时由于用的是C、C&#xff0c;因此很多习惯都一时改不了&#xff0c;这里自己列出来一些Matlab中明显不同的地方。 矩阵单元元素访问方式&#xff1a;A(1,2)---A[1][2]选取矩阵某个行或者列&#xff1a;A(:,1…

animation 先执行一次 在持续执行_这一次,彻底弄懂 JavaScript 执行机制

本文来源&#xff1a;ssssyokihttps://juejin.im/post/6844903512845860872不论你是javascript新手还是老鸟&#xff0c;不论是面试求职&#xff0c;还是日常开发工作&#xff0c;我们经常会遇到这样的情况&#xff1a;给定的几行代码&#xff0c;我们需要知道其输出内容和顺序…

[scikit-learn 机器学习] 5. 多元线性回归

文章目录1. 多元线性回归2. 多项式回归3. 正则化4. 线性回归应用举例&#xff08;酒质量预测&#xff09;4.1 数据预览4.2 模型验证5. 梯度下降法本文为 scikit-learn机器学习&#xff08;第2版&#xff09;学习笔记1. 多元线性回归 模型 yαβ1x1β2x2...βnxny \alpha\bet…

LeetCode 831. 隐藏个人信息

1. 题目 给你一条个人信息字符串 S&#xff0c;它可能是一个 邮箱地址 &#xff0c;也可能是一串 电话号码 。 我们将隐藏它的隐私信息&#xff0c;通过如下规则: 电子邮箱 定义名称 name 是长度大于等于 2 &#xff08;length ≥ 2&#xff09;&#xff0c;并且只包含小写…

bootstrap 树形表格渲染慢_layUI之树状表格异步加载组件treetableAsync.js(基于treetable.js)...

概述后台框架中使用树状表格是非常常用的操作&#xff0c;layUI本身并没有这种组件。 第三方的treetable.js做到了完美的实现&#xff0c;但是不能实现在双击时异步加载数据&#xff0c;本文就是站在了巨人的肩膀上实现的异步加载的树状表格~1. 使用说明本组件基于treetable.js…

[scikit-learn 机器学习] 6. 逻辑回归

文章目录1. 逻辑回归二分类2. 垃圾邮件过滤2.1 性能指标2.2 准确率2.3 精准率、召回率2.4 F1值2.5 ROC、AUC3. 网格搜索调参4. 多类别分类5. 多标签分类5.1 多标签分类性能指标本文为 scikit-learn机器学习&#xff08;第2版&#xff09;学习笔记逻辑回归常用于分类任务 1. 逻…

libsvm回归参数寻优cgp_【lightgbm/xgboost/nn代码整理二】xgboost做二分类,多分类以及回归任务...

1.简介该部分是代码整理的第二部分&#xff0c;为了方便一些初学者调试代码&#xff0c;作者已将该部分代码打包成一个工程文件&#xff0c;包含简单的数据处理、xgboost配置、五折交叉训练和模型特征重要性打印四个部分。数据处理部分参考&#xff1a;代码整理一&#xff0c;这…

[scikit-learn 机器学习] 7. 朴素贝叶斯

文章目录1. 朴素贝叶斯2. NB 与 逻辑回归对比本文为 scikit-learn机器学习&#xff08;第2版&#xff09;学习笔记相关知识参考&#xff1a;《统计学习方法》朴素贝叶斯法&#xff08;Naive Bayes&#xff0c;NB&#xff09; 1. 朴素贝叶斯 通过最大概率来预测类&#xff1a…

塔菲克蓝牙适配器驱动_小身材,大功能,biaze毕亚兹USB蓝牙适配器开箱体验

在日常生活中&#xff0c;我们平时使用的台式电脑或是笔记本电脑&#xff0c;想要传输数据或者音频的时候&#xff0c;都是需要借助数据传输线或是U盘等传输设备&#xff0c;使用过程可想而知&#xff0c;有点麻烦。我们都知道&#xff0c;手机是有蓝牙传输功能的&#xff0c;只…

HDU1003——MAX SUM

简单DP&#xff0c;状态转移公式&#xff1a;num[j].data max{num[j].data, num[j].datanum[j-1].data}&#xff0c;也就是保证加上前一个数不失自己的值减小。 View Code #include <stdio.h>#define N 100010#define inf 9999999struct _num{int data;int pre;int nex…

[scikit-learn 机器学习] 8. 非线性分类和决策树

文章目录1. 特征选择标准2. 网页广告预测2.1 数量处理2.2 网格搜索模型参数3. 决策树优缺点本文为 scikit-learn机器学习&#xff08;第2版&#xff09;学习笔记相关知识&#xff1a;《统计学习方法》决策树&#xff08;Decision Tree&#xff0c;DT&#xff09; 1. 特征选择…

智慧新泰时空大数据与云平台_智慧警务大数据云平台开发情报研判系统解决方案...

智慧公安作为公安信息化开展到高级阶段的一种警务形态&#xff0c;“智慧公安”主要采用物联网、云计算、无线通讯、智能动态感知分析等新一代信息技术,将公安工作IT根底设备与物理设备、人际环境等高度交融,以提供智能化公安决策与效劳。智慧警务大数据云平台开发情报研判系统…

RGB颜色查询对照表#FFFFFF

大致是下图这样的&#xff0c;有需要的可以点击下面的连接复制使用&#xff1a; https://www.114la.com/other/rgb.htm

ikbc机械键盘打字出现重复_超小无线机械键盘,绝佳移动打字体验

NuType筹资信息产品名称NuType上线平台Kickstarter发起团队NUPHY发起地区中国香港目标金额80,000HKD筹集金额1,301,212HKD完全进度1,627%支持人数1,612最低价格697HKD上线时间2019/11/13-2019/12/28创次方/制表时间&#xff1a;2019年12月28日文/大智笔电键盘的打字体验远不及桌…

MySQL - 定时任务(每天凌晨1点、每小时、每分钟、某一时间点)

常用的一定要写在前面 # 从2019-10-11开始&#xff0c;每天的00:30:00执行定时任务 ON SCHEDULE EVERY 1 DAY STARTS 2019-10-11 00:30:00 # 每天的凌晨1点执行定时任务 ON SCHEDULE EVERY 1 DAY STARTS DATE_ADD(DATE_ADD(CURDATE(), INTERVAL 1 DAY), INTERVAL 1 HOUR)# 特…