Scikit-learn库,实现了一系列数据挖掘算法,提供通用编程接口、标准化的测试和调参工具,便于用户尝试不同算法对其进行充分测试和查找优参数值。
一、Scikit-learn库概念
估计器(Estimator):用于分类、聚类和回归分析。
转换器(Transformer):用于数据预处理和数据转换。
流水线(Pipeline):组合数据挖掘流程,便于再次使用。
二、scikit-learn估计器
为帮助用户实现大量分类算法,scikit-learn把相关功能封装成所谓的估计器。估计器用于分类任务,它主要包括以下两个函数。
fit():训练算法,设置内部参数。该函数接收训练集及其类别两个参数。
predict():参数为测试集。预测测试集类别,并返回一个包含测试集各条数据类别的数组
三、近邻算法
近邻算法是标准数据挖掘算法中为直观的一种。为了对新个体进行分类,它查找训练集,找到与新个体相似的那些个体,看看这些个体大多属于哪个类别,就把新个体分到哪个类别。
四、距离度量方法
距离是数据挖掘的核心概念之一。主要包括欧氏距离、曼哈顿距离、余弦距离,其中最常用的是欧氏距离。
欧氏距离,即两个点之间的距离(两个特征向量长度平方和的平方根),得到的结果就是欧氏距离。欧氏距离很直观,但如果异常值偏差比较大或很多特征值为0,精确度就会比较差。
曼哈顿距离为两个特征在标准坐标系中绝对轴距之和。虽然异常值也会影响分类结果,但是其所受的影响要比欧氏距离小得多。
余弦距离更适合解决异常值和数据稀疏问题。直观上讲,余弦距离指的是特征向量夹角的余弦值。
五、数据集理解
即将用到的数据集叫作电离层(Ionosphere),这些数据是由高频天线收集的。
这些天线的目的是侦测在电离层和高层大气中存不存在由自由电子组成的特殊结构。
如果一条数据能给出特殊结构存在的证据,这条数据就属于好的那一类(在数据集中用“g”表示),否则就是坏的(用“b”表示)。
ionosphere.data从http://archive.ics.uci.edu/ml/datasets/Ionosphere,Data Folder下,下载ionosphere.data和ionosphere.names
该数据集每行有35个值,前34个为17座天线采集的数据(每座天线采集两个数据)。
后一个值不是“g”就是“b”,表示数据的好坏,即是否提供了有价值的信息。
六、数据挖掘步骤
一般说来包括理解数据集,数据清洗,创建训练集集和测试集,评估器实例化,训练样本,预测测试结果,优化参数,找到最佳参数。
七、代码
代码示例
代码语言:javascript复制import numpy as np
import csv
import os
from sklearn.cross_validation import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from matplotlib import pyplot as plt
from sklearn.cross_validation import cross_val_score
# 即将用到的数据集叫作电离层(Ionosphere),这些数据是由高频天线收集的。
# 这些天线的目 的是侦测在电离层和高层大气中存不存在由自由电子组成的特殊结构。
# 如果一条数据能给出特殊 结构存在的证据,这条数据就属于好的那一类(在数据集中用“g”表示),否则就是坏的(用“b” 表示)。
# ionosphere.data从http://archive.ics.uci.edu/ml/datasets/Ionosphere,Data Folder下,下载ionosphere.data和ionosphere.names
# 该数据集每行有35个值,前34个为17座天线采集的数据(每座天线采集两个数据)。
# 后一 个值不是“g”就是“b”,表示数据的好坏,即是否提供了有价值的信息。
data_filename=os.path.join('','','ionosphere.data')
# 创建Numpy数组X和y存放数据集。数据集大小已知,共有351行34列。
X=np.zeros((351,34),dtype='float') #float类型的零np数组,默认都是0
y=np.zeros((351,),dtype='bool') #bool类型的np数组,默认都是false
# 用csv模块来导入数据集文件,并创建csv阅读器对象
with open(data_filename,'r') as input_file:
reader=csv.reader(input_file)
# 遍历文件中的每一行数据。每行数据代表一组测量结果,我们可以将其称作数据集中 的一个个体。
# 用枚举函数来获得每行的索引号,在下面更新数据集X中的某一个体时会用到行号
for i,row in enumerate(reader):
# 获取每一个个体的前34个值,将其强制转化为浮点型,保存到X中。
data=[float(datum) for datum in row[:-1]]
X[i]=data
# 获取每个个体后一个表示类别的值,把字母转化为数字,如果类别为“g”,值为1, 否则值为0。
y[i]=row[-1]=='g'
# 导入并运行train_test_split函数,创建训练集和测试集,默认为75%的训练集。
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14)
# 导入K近邻分类器这个类,并为其初始化一个实例。
# 现阶段,参数用默认的即可,后面再讲参数调优。该算法默认选择5个近邻作为分类依据。
estimator = KNeighborsClassifier()
# 用训练数据进行训练。
# K近邻估计器分析训练集中的数据,比较待分类的新数据点和训练集中的数据,找到新数据点的近邻。
estimator.fit(X_train, y_train)
# 用测试集测试算法,评估它在测试集上的表
y_predicted = estimator.predict(X_test)
# 正常情况下,mean是取平均值,此处是返回条件成立的占比
accuracy = np.mean(y_test == y_predicted) * 100
print("The accuracy is {0:.1f}%".format(accuracy))
# -------------版本2,打印测试集、实际结果、预测结果-------------
# 将一维数组a转化为二维数组
#a = np.array([1,2,3]);
#b = np.array([[1],[2],[3]]);
#a = a[:,np.newaxis];
#c = np.concatenate((b,a),axis=1)
# 此处主要是为了将预测值和实际值打印出来,有个直观的对比
print(np.concatenate((X_test,y_test[:,np.newaxis],y_predicted[:,np.newaxis]),axis=1))
# ---------------------------------------------------------------
# -------------版本3,交叉验证解决一次性测试问题-----------------
#交叉检验能解决一次性测试所带来的问题
#cross_val_score默认使用Stratified K Fold方法切分数据集,它大体上保 证切分后得到的子数据集中类别分布相同,以避免某些子数据集出现类别分布失 衡的情况。
scores = cross_val_score(estimator, X, y, scoring='accuracy')
#score为得到几次验证的正确率
print(scores)
average_accuracy = np.mean(scores) * 100
print("The average accuracy is {0:.1f}%".format(average_accuracy))
# ---------------------------------------------------------------
# -------------版本4,调整近邻值以观察不同结果-------------------
avg_scores = []
max_scores = []
min_scores = []
all_scores = []
parameter_values = list(range(1, 21))
# 列n_neighbors的值,比如从1到20,可以重复进行多次实验
for n_neighbors in parameter_values:
estimator = KNeighborsClassifier(n_neighbors=n_neighbors)
scores = cross_val_score(estimator, X, y, scoring='accuracy')
# 把不同n_neighbors值的得分和平均分保存起来,留作分析用。
avg_scores.append(np.mean(scores))
max_scores.append(np.max(scores))
min_scores.append(np.min(scores))
all_scores.append(scores)
# matplotlib打印趋势情况
# 整体趋势是随着近邻数的增加,正确率不断下降
plt.plot(parameter_values, avg_scores, '-o')
plt.plot(parameter_values, max_scores, '- ')
plt.plot(parameter_values, min_scores, '--')
plt.show()
# ---------------------------------------------------------------
运行结果: