2. 用scikit-learn估计器分类

# -*- coding: utf-8 -*-
"""
Created on Sat Sep 22 09:43:28 2018

@author: asus
"""
#2 用scikit-learn估计器分类
#估计器(Estimator):用于分类、聚类和回归分析
#转换器(Transformer):用于数据预处理和数据转换
#流水线(Pipeline):组合数据挖掘流程,便于再次使用。

#2.1 scikit-learn估计器
#主要参数
#fit():训练算法,设置内部参数。该函数接收训练集及其类别两个参数。
#predict():参数为测试集。预测测试集类别,并返回一个包含测试集各条数据类别的数组。

#scikit-learn提供了大量估计器,其中有支持向量机(SVM)、随机森林、神经网络等。

#2.1.1 近邻算法
#计算量大,在特征取离散值的数据集上表现很差。

#常用的距离度量,欧氏距离,曼哈顿距离,余弦距离。

#即将用到的数据集叫作电离层,这些数据是由高频天线收集的。最后一列,'g'好,'b'坏,为数
#据的好坏,即是否提供了有价值的信息。

import numpy as np
import csv

data_filename = "E:/books/Python数据挖掘入门与实践/ionosphere.data"
#创建NumPy数组x和y存放数据集。数据大小已知,共有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)
    #遍历文件中的每一行数据。用枚举函数获得每行的索引号
    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'

#2.1.4 努力实现流程标准化

#创建训练集和测试集
from sklearn.cross_validation import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=14)
#x_train训练集,x_test测试集。y_train,y_test分别为以上两个数据集的类别信息。

#导入K近邻分类器这个类,并为其初始化一个实例。默认选择5个近邻作为分类依据。
from sklearn.neighbors import KNeighborsClassifier
estimator = KNeighborsClassifier()
#估计器创建好后,接下来就要用训练数据进行训练。K近邻估计器分析训练集中的数据,比较待分
#类的新数据点和训练集中的数据,找到新数据点的近邻。
estimator.fit(x_train, y_train)
#接着,用测试集测试算法,评估它在测试集上的表现
y_predicted = estimator.predict(x_test)
accuracy = np.mean(y_test == y_predicted) * 100
print("The test accuracy is {:.1f}%".format(accuracy))

#2.1.5 运行算法
#交叉检验
from sklearn.cross_validation import cross_val_score
scores = cross_val_score(estimator, x, y, scoring='accuracy')
average_accuracy = np.mean(scores) * 100
print("The test accuracy is {:.1f}%".format(average_accuracy))

#2.1.6 设置参数
#n_neighbors,选取多少个近邻作为预测依据。

#测试1到20的n_neighbors
avg_scores = []
all_scores = []
parameter_values = list(range(1, 21))
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))
    all_scores.append(scores)
%matplotlib inline
from matplotlib import pyplot as plt
plt.plot(parameter_values, avg_scores, '-o')

#2.2 流水线在预处理中的应用
#转换器(Transformer),它接受原始数据集,返回转换后的数据集。

#2.2.1 预处理案例
#讲解需要,先对数据集做些破坏
x_broken = np.array(x) #创建一个副本
x_broken[:,::2] /= 10  #每隔一行,就把第二行的特征除以10
#数值范围变了,再次计算正确率
estimator = KNeighborsClassifier()
#原始数据集的正确率
original_scores = cross_val_score(estimator, x, y, scoring='accuracy')
print("The test accuracy is {:.1f}%".format(np.mean(original_scores) * 100))
#副本的正确率
broken_scores = cross_val_score(estimator, x_broken, y, scoring='accuracy')
print("The test accuracy is {:.1f}%".format(np.mean(broken_scores) * 100))

#2.2.2 标准预处理
from sklearn.preprocessing import MinMaxScaler
#规范化,标准化,最小值用0代替,最大值用1代替,其余值介于两者之间
x_transformed = MinMaxScaler().fit_transform(x)

#其他规范化方法
#为使每条数据各特征值的和为1,使用sklearn.preprocessing.Normalizer
#为使各特征的均值为0,方差为1,使用sklearn.preprocessing.StandardScaler,常用作规范
#化的基准
#为将数值型特征的二值化,使用sklearn.preprocessing.Binarizer,大于阈值的为1,反之为0

#2.2.3 组装起来
x_transformed = MinMaxScaler().fit_transform(x_broken)
estimator = KNeighborsClassifier()
transformed_scores = cross_val_score(estimator, x_transformed, y,
                                     scoring='accuracy')
print("The test accuracy is {:.1f}%".format(np.mean(transformed_scores) * 100))
#正确率又再次升回来了
#异常值会影响近邻算法,不同算法对值域大小的敏感度不同

#2.3 流水线
#流水线把这些步骤保存到数据挖掘的工作流中。之后你就可以用它们读入数据,做各种必要的处
#理,然后给出预测结果。
from sklearn.pipeline import Pipeline
#流水线的输入为一连串的数据挖掘步骤,其中最后一步必须是估计器,前几步是转换器。
#每一部都用元组(‘名称’,步骤)表示。
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))


猜你喜欢

转载自blog.csdn.net/qq_39124646/article/details/82980858