1数据的特征抽取
特征抽取对文本等数据进行特征值化。
API:
sklearn.feature_extraction
字典特征抽取
sklearn.feature_extraction.DictVectorizer
DictVectorizer语法
DictVectorizer(sparse=True,…):sparse=Teur意思是产生稀疏矩阵
DictVectorizer.fit_transform(X):X:字典或者包括字典的迭代器;返回值:返回sparse矩阵
DictVectorizer.inverse_transform(X):X:array数组或者sparse矩阵;返回值:转换之前数据格式
DictVectorizer.get_feature_names():返回类别名称
DictVectorizer.transform(X):按照原先的标准转换
流程:
实例化类DictVectorizer
调用fit_transform方法输入数据并转换 注意返回格式
方法:
fit_transform(X,y)
应用并转化映射列表X,y为目标类型
inverse_transform(X[, dict_type])
将Numpy数组或scipy.sparse矩阵转换为映射列表
from sklearn.feature_extraction import DictVectorizer
onehot = DictVectorizer() # 如果结果不用toarray,请开启sparse=False
instances = [{'city': '北京','temperature':100},{'city': '上海','temperature':60}, {'city': '深圳','temperature':30}]
X = onehot.fit_transform(instances).toarray()
print(onehot.inverse_transform(X))
文本特征提取(只限于英文)
文本的特征提取应用于很多方面,比如说文档分类、垃圾邮件分类和新闻分类。那么文本分类是通过词是否存在、以及词的概率(重要性)来表示。
(1)文档的中词的出现
数值为1表示词表中的这个词出现,为0表示未出现
sklearn.feature_extraction.text.CountVectorizer()
将文本文档的集合转换为计数矩阵(scipy.sparse matrices)
方法
fit_transform(raw_documents,y)
学习词汇词典并返回词汇文档矩阵
from sklearn.feature_extraction.text import CountVectorizer
content = ["life is short,i like python","life is too long,i dislike python"]
vectorizer = CountVectorizer()
print(vectorizer.fit_transform(content).toarray())
需要toarray()方法转变为numpy的数组形式
温馨提示:每个文档中的词,只是整个语料库中所有词,的很小的一部分,这样造成特征向量的稀疏性(很多值为0)为了解决存储和运算速度的问题,使用Python的scipy.sparse矩阵结构
(2)TF-IDF表示词的重要性
TfidfVectorizer会根据指定的公式将文档中的词转换为概率表示。(朴素贝叶斯介绍详细的用法)
class sklearn.feature_extraction.text.TfidfVectorizer()
方法
fit_transform(raw_documents,y)
学习词汇和idf,返回术语文档矩阵。
from sklearn.feature_extraction.text import TfidfVectorizer
content = ["life is short,i like python","life is too long,i dislike python"]
vectorizer = TfidfVectorizer(stop_words='english')
print(vectorizer.fit_transform(content).toarray())
print(vectorizer.vocabulary_)
数据的特征预处理
单个特征
归一化
归一化首先在特征(维度)非常多的时候,可以防止某一维或某几维对数据影响过大,也是为了把不同来源的数据统一到一个参考区间下,这样比较起来才有意义,其次可以程序可以运行更快。 例如:一个人的身高和体重两个特征,假如体重50kg,身高175cm,由于两个单位不一样,数值大小不一样。如果比较两个人的体型差距时,那么身高的影响结果会比较大,k-临近算法会有这个距离公式。
min-max方法
这里我们使用相亲约会对象数据在MatchData.txt,这个样本时男士的数据,三个特征,玩游戏所消耗时间的百分比、每年获得的飞行常客里程数、每周消费的冰淇淋公升数。然后有一个 所属类别,被女士评价的三个类别,不喜欢、魅力一般、极具魅力。 首先导入数据进行矩阵转换处理
import numpy as np
def data_matrix(file_name):
"""
将文本转化为matrix
:param file_name: 文件名
:return: 数据矩阵
"""
fr = open(file_name)
array_lines = fr.readlines()
number_lines = len(array_lines)
return_mat = zeros((number_lines, 3))
# classLabelVector = []
index = 0
for line in array_lines:
line = line.strip()
list_line = line.split('\t')
return_mat[index,:] = list_line[0:3]
# if(listFromLine[-1].isdigit()):
# classLabelVector.append(int(listFromLine[-1]))
# else:
# classLabelVector.append(love_dictionary.get(listFromLine[-1]))
# index += 1
return return_mat
输出结果
[[ 4.09200000e+04 8.32697600e+00 9.53952000e-01]
[ 1.44880000e+04 7.15346900e+00 1.67390400e+00]
[ 2.60520000e+04 1.44187100e+00 8.05124000e-01]
...,
[ 2.65750000e+04 1.06501020e+01 8.66627000e-01]
[ 4.81110000e+04 9.13452800e+00 7.28045000e-01]
[ 4.37570000e+04 7.88260100e+00 1.33244600e+00]]
我们查看数据集会发现,有的数值大到几万,有的才个位数,同样如果计算两个样本之间的距离时,其中一个影响会特别大。也就是说飞行里程数对于结算结果或者说相亲结果影响较大,但是统计的人觉得这三个特征同等重要,所以需要将数据进行这样的处理。
这样每个特征任意的范围将变成[0,1]的区间内的值,或者也可以根据需求处理到[-1,1]之间,我们再定义一个函数,进行这样的转换。
def feature_normal(data_set):
"""
特征归一化
:param data_set:
:return:
"""
# 每列最小值
min_vals = data_set.min(0)
# 每列最大值
max_vals = data_set.max(0)
ranges = max_vals - min_vals
norm_data = np.zeros(np.shape(data_set))
# 得出行数
m = data_set.shape[0]
# 矩阵相减
norm_data = data_set - np.tile(min_vals, (m,1))
# 矩阵相除
norm_data = norm_data/np.tile(ranges, (m, 1)))
return norm_data
输出结果为
[[ 0.44832535 0.39805139 0.56233353]
[ 0.15873259 0.34195467 0.98724416]
[ 0.28542943 0.06892523 0.47449629]
...,
[ 0.29115949 0.50910294 0.51079493]
[ 0.52711097 0.43665451 0.4290048 ]
[ 0.47940793 0.3768091 0.78571804]]
scikit-learn.preprocessing中的类MinMaxScaler,将数据矩阵缩放到[0,1]之间
>>> X_train = np.array([[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]])
...
>>> min_max_scaler = preprocessing.MinMaxScaler()
>>> X_train_minmax = min_max_scaler.fit_transform(X_train)
>>> X_train_minmax
array([[ 0.5 , 0. , 1. ],
[ 1. , 0.5 , 0.33333333],
[ 0. , 1. , 0. ]])
注意在特定场景下最大值最小值是变化的,另外,最大值与最小值非常容易受异常点影响,所以这种方法鲁棒性较差,只适合传统精确小数据场景
标准化
常用的方法是z-score标准化,经过处理后的数据均值为0,标准差为1
它们可以通过现有的样本进行估计,在已有的样本足够多的情况下比较稳定,适合嘈杂的数据场景
sklearn中提供了StandardScalar类实现列标准化:
In [2]: import numpy as np
In [3]: X_train = np.array([[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]])
In [4]: from sklearn.preprocessing import StandardScaler
In [5]: std = StandardScaler()
In [6]: X_train_std = std.fit_transform(X_train)
In [7]: X_train_std
Out[7]:
array([[ 0. , -1.22474487, 1.33630621],
[ 1.22474487, 0. , -0.26726124],
[-1.22474487, 1.22474487, -1.06904497]])
缺失值
由于各种原因,许多现实世界的数据集包含缺少的值,通常编码为空白,NaN或其他占位符。然而,这样的数据集与scikit的分类器不兼容,它们假设数组中的所有值都是数字,并且都具有和保持含义。使用不完整数据集的基本策略是丢弃包含缺失值的整个行和/或列。然而,这是以丢失可能是有价值的数据(即使不完整)的代价。更好的策略是估算缺失值,即从已知部分的数据中推断它们。
(1)填充缺失值 使用sklearn.preprocessing中的Imputer类进行数据的填充
class Imputer(sklearn.base.BaseEstimator, sklearn.base.TransformerMixin)
"""
用于完成缺失值的补充
:param param missing_values: integer or "NaN", optional (default="NaN")
丢失值的占位符,对于编码为np.nan的缺失值,使用字符串值“NaN”
:param strategy: string, optional (default="mean")
插补策略
如果是“平均值”,则使用沿轴的平均值替换缺失值
如果为“中位数”,则使用沿轴的中位数替换缺失值
如果“most_frequent”,则使用沿轴最频繁的值替换缺失
:param axis: integer, optional (default=0)
插补的轴
如果axis = 0,则沿列排列
如果axis = 1,则沿行排列
"""
多个特征
降维
PCA(Principal component analysis),主成分分析。特点是保存数据集中对方差影响最大的那些特征,PCA极其容易受到数据中特征范围影响,所以在运用PCA前一定要做特征标准化,这样才能保证每维度特征的重要性等同
sklearn.decomposition.PCA
1
class PCA(sklearn.decomposition.base)
"""
主成成分分析
:param n_components: int, float, None or string
这个参数可以帮我们指定希望PCA降维后的特征维度数目。最常用的做法是直接指定降维到的维度数目,此时n_components是一个大于1的整数。
我们也可以用默认值,即不输入n_components,此时n_components=min(样本数,特征数)
:param whiten: bool, optional (default False)
判断是否进行白化。所谓白化,就是对降维后的数据的每个特征进行归一化。对于PCA降维本身来说一般不需要白化,如果你PCA降维后有后续的数据处理动作,可以考虑白化,默认值是False,即不进行白化
:param svd_solver:
选择一个合适的SVD算法来降维,一般来说,使用默认值就够了。
"""
例子
>>> import numpy as np
>>> from sklearn.decomposition import PCA
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
>>> pca = PCA(n_components=2)
>>> pca.fit(X)
PCA(copy=True, iterated_power='auto', n_components=2, random_state=None,
svd_solver='auto', tol=0.0, whiten=False)
>>> print(pca.explained_variance_ratio_)
[ 0.99244... 0.00755...]
数据的特征选择
降维本质上是从一个维度空间映射到另一个维度空间,特征的多少别没有减少,当然在映射的过程中特征值也会相应的变化。举个例子,现在的特征是1000维,我们想要把它降到500维。降维的过程就是找个一个从1000维映射到500维的映射关系。原始数据中的1000个特征,每一个都对应着降维后的500维空间中的一个值。假设原始特征中有个特征的值是9,那么降维后对应的值可能是3。而对于特征选择来说,有很多方法:
Filter(过滤式):VarianceThreshold
Embedded(嵌入式):正则化、决策树
Wrapper(包裹式)
sklearn.feature_selection
去掉取值变化小的特征(删除低方差特征)
VarianceThreshold 是特征选择中的一项基本方法。它会移除所有方差不满足阈值的特征。默认设置下,它将移除所有方差为0的特征,即那些在所有样本中数值完全相同的特征。
假设我们要移除那些超过80%的数据都为1或0的特征
from sklearn.feature_selection import VarianceThreshold
X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
sel.fit_transform(X)
array([[0, 1],
[1, 0],
[0, 0],
[1, 1],
[1, 0],
[1, 1]])
降维
PCA
本质:PCA是一种分析、简化数据集的技术
目的:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息。
作用:可以削减回归分析或者聚类分析中特征的数量
PCA流程
1、初始化PCA,指定减少后的维度
2、调用fit_transform
机器学习组成:模型、策略、优化
《统计机器学习》中指出:机器学习=模型+策略+算法。其实机器学习可以表示为:Learning= Representation+Evalution+Optimization。我们就可以将这样的表示和李航老师的说法对应起来。机器学习主要是由三部分组成,即:表示(模型)、评价(策略)和优化(算法)。
表示(或者称为:模型):Representation
表示主要做的就是建模,故可以称为模型。
模型要完成的主要工作是转换:将实际问题转化成为计算机可以理解的问题,就是我们平时说的建模。类似于传统的计算机学科中的算法,数据结构,如何将实际的问题转换成计算机可以表示的方式。这部分可以见“简单易学的机器学习算法”。给定数据,我们怎么去选择对应的问题去解决,选择正确的已有的模型是重要的一步。
评价(或者称为:策略):Evalution
评价的目标是判断已建好的模型的优劣。对于第一步中建好的模型,评价是一个指标,用于表示模型的优劣。这里就会是一些评价的指标以及一些评价函数的设计。
优化:Optimization
优化的目标是评价的函数,我们是希望能够找到最好的模型,也就是说评价最高的模型。
开发机器学习应用程序的步骤
(1)收集数据
我们可以使用很多方法收集样本护具,如:制作网络爬虫从网站上抽取数据、从RSS反馈或者API中得到信息、设备发送过来的实测数据。
(2)准备输入数据
得到数据之后,还必须确保数据格式符合要求。
(3)分析输入数据
这一步的主要作用是确保数据集中没有垃圾数据。如果是使用信任的数据来源,那么可以直接跳过这个步骤
(4)训练算法
机器学习算法从这一步才真正开始学习。如果使用无监督学习算法,由于不存在目标变量值,故而也不需要训练算法,所有与算法相关的内容在第(5)步
(5)测试算法
这一步将实际使用第(4)步机器学习得到的知识信息。当然在这也需要评估结果的准确率,然后根据需要重新训练你的算法
(6)使用算法
转化为应用程序,执行实际任务。以检验上述步骤是否可以在实际环境中正常工作。如果碰到新的数据问题,同样需要重复执行上述的步骤