使用sklearn中的Iris植物分类数据集进行特征检验与预测分析

import numpy as np
from sklearn.datasets import load_iris
from collections import defaultdict
from operator import itemgetter
from sklearn.cross_validation import train_test_split
dataset=load_iris()
#X代表数据集的样子,每个sample中有四个值分别代表萼的长度和花瓣的长度
X=dataset.data
#Y中数据个数等于X中数据的sample数量,代表X中sample数量所属于0/1/2/3中的哪一种品种
Y=dataset.target
#print(Y)
#print(X)
n_samples,n_features=X.shape#返回的是数据集的总数量
# print(X)


#计算平均值,用于分类
attribute_means=X.mean(axis=0)#计算的是每一列的平均值
#print(attribute_means)
#将数据集中大于平均数的置为1.小于的置为0
c_X=np.array(X>attribute_means,dtype='int')
# print(c_X)


#分类问题,根据上面的数据集Y,我们知道150种植物被分成了三组,即三个种类。我们遍历这三类植物的特征,在某一个特征(比如花瓣长度)的特征值为0的情况下,
#如果A类有20个,B类有60个,C类有20个,那么上面花瓣长度特征值为0的个体最可能属于B类植物,但是这个特征值的计算,错误率是40%,
#首先根据需要创建出一个计算特征值错误率的函数
def train_feature_value(X,Y,feature,value):#四个参数分别是数据集,类别数组,特征索引(每种植物的第几个特征)和特征值
    class_counts=defaultdict(int)
    for sample,y in zip(X,Y):
        #如果当前种类植物的当前个体的特征的特征值等于给定的特征值,那么认为此类植物符合规则,数量加一
        if sample[feature]==value:
            class_counts[y]+=1
    
    #计算完成后,统计该特征下,哪种植物的计数最多
    sorted_class_counts=sorted(class_counts.items(),key=itemgetter(1),reverse=True)

    #找出最多的种类
    most_frequent_class=sorted_class_counts[0][0]
    #X现在是只包含0,1类型的矩阵,X.shape=(150,4),是150个数量每一种有四种特征
    n_samples=X.shape[1]
    #统计出错的数量
    error=sum([class_count for class_value,class_count in class_counts.items() if class_value!=most_frequent_class])
    
    #然后返回该特征主要指向哪一个品种,与错误率
#     return ('最多的品种是{0}类植物,错误数是{1}'.format(most_frequent_class,error))
    return most_frequent_class, error


#定义一个遍历某特征的特征值的函数
def train(X,Y,feature):#参数分别是数据集,类别集,特征索引
    n_samples,n_features=X.shape#数据集的行和列
    assert 0 <=feature <n_features
    #通过一个set集合,来获取不重复的特征值
    values=set(X[:,feature])
    #定义一个预测字典,用来保存每一个特征值出现的次数
    predictors=dict()
    #定义一个错误列表,用来保存每一个特征值的错误率
    errors=[]
    for value in values:
        most_frequent_class,error=train_feature_value(X,Y,feature,value)
        predictors[value]=most_frequent_class
        errors.append(error)
        
    #然后计算总错误率和预测器
    total_error=sum(errors)
    return (predictors,total_error)
    

#过拟合:当我们用训练集用做测试集的时候,通常会发生过拟合,即它在训练集中的表现特别好,但是碰到新的数据集时表现会很差。
#为了防止过拟合,我们将一整个数据集分成训练集和测试集,sklearn给我们提供了一个分割数据集和训练集的函数,我们就会取得两个数据集

X_train,X_test,Y_train,Y_test=train_test_split(c_X,Y,random_state=14)#如果random_state变成None时,就是真正的随机

# print('训练集X:',X_test)
# print('测试集X:',X_test)
# print('训练集Y:',Y_train)
# print('测试集Y:',Y_test)
#然后遍历物种的每一样特征
all_predicts={}
errors={}

for feature_index in range(X_train.shape[1]):#四种特征
    predictors,total_error=train(X_train, Y_train, feature_index)
    all_predicts[feature_index]=predictors
    errors[feature_index]=total_error
#找出错误无虑最低的特征
best_feature,best_error=sorted(errors.items(),key=itemgetter(1),reverse=True)[0]


#创建model,作为测试的标准
model={
    'feature':best_feature,
    'predictor':all_predicts[best_feature]
}
print('******',model)
#定义测试函数开始测试
def Test(X_test,model):
    feature=model['feature']
    predictor=model['predictor']
    Y_predictor=np.array([predictor[int(sample[feature])] for sample in X_test])
    return Y_predictor

Y_predictor=Test(X_test,model)
accuracy=np.mean(Y_predictor==Y_test)*100
print(accuracy)


猜你喜欢

转载自blog.csdn.net/just_so_so_fnc/article/details/78240444