您的位置:首页 > 编程语言 > Python开发

《Python数据挖掘入门与实践》—— 学习笔记(二)

2019-02-11 19:35 686 查看

scikit-learn库,实现了一系列数据挖掘算法,提供通用编程接口标准化的测试调参工具,便于用户尝试不同算法对其进行充分测试查找最优参数值

 

本节目标:讲解数据挖掘通用框架的搭建方法。

本节核心概念:

估计器(Estimator):用于分类、聚类和回归分析

转换器(Transformer):用于数据预处理数据转换

流水线(Pipeline):组合数据挖掘流程,便于再次使用。

 

scikit-learn估计器:为实现分类算法,把相关功能封装估计器。

估计器包括以下两个函数:

1、fit():训练算法,设置内部参数。接受训练集及其类别两个参数。

2、predict():参数为测试集。预测测试集类别。

scikit-learn估计器的接受和输出的数据格式均为numpy数组或类似格式。

 

scikit-learn提供大量估计器,包括支持向量机、随机森林、神经网络等。

近邻算法:为了对新个体进行分类,查找训练集,找到与新个体最相似的那些个体,看看这些个体大多属于哪个类别,就把新个体分到哪个类别。

优缺点:几乎可对任何数据集进行分类。但要计算数据集中每个个体之间的距离,计算量很大。

欧式距离:是真实距离。但某些特征其他特征取值大很多,精确度就会比较差。如果很多特征值为0,也就是稀疏矩阵,结果也不准确。

曼哈顿距离:两个特征在标准坐标系中绝对轴距之和。该距离在某些情况下具有更高的稳定性,但如果数据集中某些特征值很大,这些特征会掩盖其他特征间的邻近关系。

余弦距离:更适合解决异常值和数据稀疏问题。余弦距离指的是特征向量夹角的余弦值。适用于特征向量很多的情况,但它丢弃了向量长度所包含的在某些场景下可能有用的一些信息。

 

电离层数据集(Ionosphere):这些数据是由高频天线收集的。这些天线的目的是侦测在电离层和高层大气中,存不存在由自由电子组成的特殊结构。如果一条数据能给出特殊结构存在的证据,就属于好的一类(g),否则为坏的一类(b)。

下载:

http://archive.ics.uci.edu/ml/datasets/Ionosphere

点击Data Folder,下载ionosphere.data和iono.names文件

保存至用户主目录的Data文件夹下

 

[code]import os

home_folder = os.path.expanduser("~")
print(home_folder)

data_folder = os.path.join(home_folder, "Data", "Ionosphere")
data_filename = os.path.join(data_folder, "ionosphere.data")
print(data_filename)

import numpy as np
import csv

# 数据集大小已知,共有351行34列
X = np.zeros((351, 34), dtype='float')
y = np.zeros((351,), dtype='bool')

with open(data_filename, 'r') as input_file:
reader = csv.reader(input_file)  # 创建csv阅读器对象
for i, row in enumerate(reader):  # 用枚举函数来获得每行的索引号
# 获取每个个体的前34个值,将其强制转化为浮点型,保存到X中
data = [float(datum) for datum in row[:-1]]
X[i] = data
# 获取每个个体最后一个表示类别的值,把字母转化为数字
y[i] = row[-1] == 'g'

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14)
print("There are {} samples in the training dataset".format(X_train.shape[0]))
print("There are {} samples in the testing dataset".format(X_test.shape[0]))
print("Each sample has {} features".format(X_train.shape[1]))

from sklearn.neighbors import KNeighborsClassifier

# 默认选择5个近邻作为分类依据
estimator = KNeighborsClassifier()
# 分析训练集中的数据,比较待分类的新数据点和训练集中的数据,找到新数据点的近邻
estimator.fit(X_train, y_train)

# 用测试集测试算法,评估它在测试集上的表现
y_predicted = estimator.predict(X_test)
accuracy = np.mean(y_test == y_predicted) * 100
print("The accuracy is {0:.1f}%".format(accuracy))

# 交叉检验能够解决一次性测试所带来的问题。
# 算法描述:
# (1)将整个大数据集分为几个部分(fold)
# (2)对于每一部分执行如下操作:
# a.将其中一部分作为当前测试集
# b.用剩余部分训练算法
# c.在当前测试集上测试算法
# (3)记录每次得分及平均得分。
# (4)上述过程,每条数据只能在测试集中出现一次。
from sklearn.model_selection import cross_val_score

# 默认使用Stratified K Fold方法切分数据集
# 它大体上保证切分后得到的数据集中类别分布相同
scores = cross_val_score(estimator, X, y, scoring='accuracy')
average_accuracy = np.mean(scores) * 100
print("The average accuracy is {0:.1f}%".format(average_accuracy))

# 允许用户设置参数的好处是,增强算法的泛化能力
avg_scores = []
all_scores = []
# 测试一系列n_neighbors的值
parameter_values = list(range(1, 21))  # Including 20
for n_neighbors in parameter_values:
estimator = KNeighborsClassifier(n_neighbors=n_neighbors)
scores = cross_val_score(estimator, X, y, scoring='accuracy')
avg_scores.append(np.mean(scores))
all_scores.append(scores)

# %matplotlib inline 告诉IPython notebook,要作图
from matplotlib import pyplot as plt

plt.figure(figsize=(32, 20))
# 参数为近邻数和平均正确率
plt.plot(parameter_values, avg_scores, '-o', linewidth=5, markersize=24)

流水线在预处理中的应用:

[code]1、特征值大小实际上与该特征的分类效果没有任何关系。
2、解决方法是,对不同的特征进行规范化,使特征值落在相同的值域或从属于某几个确定的类别。
3、选择最具区分度的特征、创建新特征等都属于预处理范畴。scikit-learn的预处理工具叫作转换器

标准预处理:

[code]from sklearn.preprocessing import MinMaxScaler
#对训练集X进行预处理,最小值用0代替,最大值用1代替,其余值介于两者之间
X_transformed = MinMaxScaler().fit_transform(X)

常用规范化方法:

[code]sklearn.preprocessing.Normalizer:使每条数据各特征值的和为1
sklearn.preprocessing.StandardScaler:使各特征值的均值为0,方差为1
sklearn.preprocessing.Binarizer:将数值型特征二值化,即大于阈值的为1,反之为0

简单总结:异常值会影响近邻算法,不同算法对值域大小的敏感度不同。

 

流水线:

解决了跟踪记录操作不容易、代码具有先后顺序等问题。流水线把一些步骤保存到数据挖掘的工作流中,之后就可以用它们读入数据,做各种必要的预处理,然后给出预测结果。

创建流水线:输入为一连串的数据挖掘步骤,其中最后一步必须使估计器。

[code]from sklearn.preprocessing import MinMaxScaler
from sklearn.pipeline import Pipeline

X_broken = np.array(X)
X_broken[:, ::2] /= 10
scaling_pipeline = Pipeline([('scale', MinMaxScaler()), ('predict', KNeighborsClassifier())])
scores = cross_val_score(scaling_pipeline, X_broken, y, scoring='accuracy')
print("The pipeline scored an average accuracy for is {0:.1f}%".format(np.mean(scores) * 100))

 

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: