python数据挖掘与入门实践(2.1)用sciket-learn估计器分类

来源:互联网 发布:网络盒子怎样双清 编辑:程序博客网 时间:2024/06/10 06:38
书中主要是用sciket-learn的近邻算法进行估计器分类。

准备工作:

         目标  ; -建立分类器,自动判别数据的好坏;

         数据集 :来自http://archive.ics.uci.edu/ml/machine-learning-databases/ionosphere/的数据ionosphere.data和ionosphere.names。将其保存到用户主目录下的Data文件夹中;

          g/b  ; 这条数据属于好/ 坏的一类


一、.加载数据集


%matplotlib  inline#将matplotlib的图表直接镶嵌在notebook中import oshome_folder=os.path.expanduser("~")#当不知道Data文件夹具体所在的主目录的时候,用os模块的这条代码输出主目录所在位置print(home_folder)

代码结果为   C:\Users\Administrator

接着用Data文件夹路径、数据集所在的文件夹名称和数据集名称组合成数据集文件的完整路径:data_folder:是Data文件夹中Ionosphere文件夹的路径;ionosphere.data是数据集名称。

data_folder = os.path.join(home_folder, "Data", "Ionosphere")data_filename = os.path.join(data_folder, "ionosphere.data")print(data_filename)#data_filename就是数据集文件ionosphere.data的完整路径

代码结果为:
C:\Users\Administrator\Data\Ionosphere\ionosphere.data


创建Numpy数组X和y存放数据集。由于数据集大小已知,共有351行35列,我们创建的数组X存放所有的数值数据,而判定的结果数据则放在数组y中。故X共有351行,34列数据,而y有351行,1列数据。


import csv#导入csv模块import numpy as npX = np.zeros((351, 34), dtype='float')#创建一个shape属性为(351,34),元素都为0的二维数组,存放351条数值数据,每条数值数据共有34个,数据类型为浮点型y = np.zeros((351,), dtype='bool')#创建一个shape属性为(351,)的一维数组,其形式为[0. 0. ....0.],其中每个数据对应X中的每条数据的判定结果,原始数据集中用‘g'或者’b'来表示,这里换成布尔值类型with open(data_filename, 'r') as input_file:      reader = csv.reader(input_file)#用csv模块来导入数据及文件,并创建csv阅读器对象      for i, row in enumerate(reader):#遍历文件中的每一行数据           data = [float(datum) for datum in row[:-1]]#将每一条数据中最后一个数据前面的34个值强制转换成float类型 # Set the appropriate row in our dataset           X[i] = data#将每个索引i对应的转换后的data数据赋值给数组X中相应的每一行 # 1 if the class is 'g', 0 otherwise           y[i] = row[-1] == 'g'#将每一行最后的数据复制给数组y,当row[-1]=='g'时,y[i]为'g',否则为False


我的代码在with open() as这一步总是出错,所以我临时换成用open来打开文件


datafile=open('/Users/Administrator/Desktop/ionosphere.data','r')#剩下的步骤都一样reader = csv.reader(datafile)for i, row in enumerate(reader):     data = [float(datum) for datum in row[:-1]]     X[i] = data     y[i] = row[-1] == 'g'


这次没有报错


相关知识点:
1.with open()和open
http://ludaming.com/posts/Python/python-open-file.html 这个博客讲得很清楚
2.
for i,row in enumerate(reader)

enumerate函数用于遍历序列中的元素及其下标:

eg1.

seq = ['one', 'two', 'three']for i, element in enumerate(seq):    print (i, seq[i])

0 one
1 two
2 three

eg2.

seq = ['one', 'two', 'three']for i, element in enumerate(seq,start=1):    print (i,seq[i])
1 two
2 three

eg3.

for i,j in enumerate('abc'):    print((i,j))

(0, 'a')
(1, 'b')
(2, 'c')

eg4.

import numpy as npa=np.array( [ (1,2,3,4), (5,6,7,8),(9,10,11,12) ] )for i, element in enumerate(a):    print (i,element)
0 [1 2 3 4]
1 [5 6 7 8]
2 [ 9 10 11 12]

二、努力实现流程标准化


sciket-learn估计器由两大函数组成:fit()和 predict()
用fit方法在训练集上完成模型的创建,用predict方法在测试集上评估效果
首先,创建训练集和测试集,平时常用from sklearn.cross_validation import train_test_split导入并运行train_test_split函数:
train_test_split是交叉验证中常用的函数,功能是从样本中随机地按比例选取train data数据和test data测试数据,构成训练集和测试集,其形式为X_train, X_test, y_train, y_test = train_test_split(train_data, train_target, test_size=0.4,random_state=0)
参数解释:train_data : 所要划分的样本特征集;
          train_target : 所要划分的样本结果;
          test_size:样本占比,如果是整数,就是测试样本的数量,即X_test里的样本数量;test_size值不同的情况下,得到的训练集和测试集的样本数量也不同,test_size为小于1的小数时,值越小,X_train的样本数越多,X_test的样本数越少;
          random_state :随机数的种子;
          随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数,比如每次都填1,在其他参数一样的情况下得到的随机数组是一样的;但是填0或者不填,每次都会不一样。随机数的产生取决于种子,随机数和种子之间得分关系遵从以下规则:种子不同,随机数不同;种子相同,即使实例不同,随机数也相同。

from sklearn.cross_validation import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14)#所要划分的样本特征集为X,所要划分的样本结果为y,由于没有test_size参数,样本全部进行划分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]))


There are 263 samples in the training dataset
There are 88 samples in the testing dataset
Each sample has 34 features

最后用三个打印语句打印出训练集的样本数、测试集的样本数和每个样本的特征值个数。导入K近邻分类器(KNN)这个类,并为其初始化一个实例。该算法默认选择5个近邻作为分类依据;估计器创建好后,用训练数据进行训练。K近邻分类器分析训练集中的数据,比较待分类的新数据点和训练集中的数据,找到新数据点的近邻。


from sklearn.neighbors import KNeighborsClassifier#导入KNN分类树的类KNeighborsClassifier;在scikit-learn 中,与近邻法这一大类相关的类库都在sklearn.neighbors包之中。estimator = KNeighborsClassifier() #创建估计器estimator.fit(X_train, y_train)#用训练数据进行训练KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',           metric_params=None, n_jobs=1, n_neighbors=5, p=2,           weights='uniform')

接着,用测试集测试算法,评估它在测试集上的表现。

y_predicted = estimator.predict(X_test)#对测试集X_test测试,88个测试样本的评估结果True或者Falseaccuracy = np.mean(y_test == y_predicted) * 100#accuracy为精确度,比较测试集的测试结果和估计结果,print("The accuracy is {0:.1f}%".format(accuracy))

The accuracy is 86.4%


相关知识:
np.mean():求矩阵的均值
在sklearn中,np.mean(answer == y[test])的说明

eg1.

answer=[1, 0, 1, 1, 1, 1]  y=[0, 0, 0, 0, 0, 1]  print(answer==y)  
结果:  False  

eg2.

answer=np.array([1, 0, 1, 1, 1, 1])   y=np.array([0, 0, 0, 0, 0, 1])   print(answer==y)  
 结果:  
 [False  True False False False  True] 

eg3.

answer=np.array([1, 0, 1, 1, 1, 1])   y=np.array([0, 0, 0, 0, 0, 1])   print(np.mean(answer == y[test])) 
结果:  0.333333333333 

说明:
       1、 answer == y表示两个数组中的值相同时,输出True;否则输出False
       2、 eg3 对 eg2 中结果取平均值,其中True=1,False=0;

三、运行算法


在前面的算法中,我们把数据集分为训练集和测试集,用训练集训练算法,在测试集上评估效果。如果只进行一次性测试,极有可能出现以下问题:若是碰巧走运,测试集很简单,我们就会觉得算法表现不错;反之,则会怀疑算法很糟糕,此时极有可能把一个其实很不错的算法给抛弃了。
交叉检验(Cross-Validation): 有时亦称循环估计, 是一种统计学上将数据样本切割成较小子集的实用方法。于是可以先在一个子集上做分析, 而其它子集则用来做后续对此分析的确认及验证。 一开始的子集被称为训练集。而其它的子集则被称为验证集或测试集。WIKI
交叉验证对于人工智能,机器学习,模式识别,分类器等研究都具有很强的指导与验证意义。
基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train set),另一部分做为验证集(validation set or test set),首先用训练集对分类器进行训练,在利用验证集来测试训练得到的模型(model),以此来做为评价分类器的性能指标.


.

阅读全文
0 0
原创粉丝点击