机器学习入门级实例——针对葡萄酒质量进行建模

数据背景

本文数据取至于UCI——欧文大学机器学习数据库,是一个免费且十分好用的数据库,在学习机器学习时会接触一个基础的数据集——鸢尾花,就是欧文大学提供的,本文就是在一个名叫葡萄酒品质的数据集的基础上进行建模
附上数据链接:数据集
该数据集一个优点就是可以适用于分类和回归两种算法进行不同的建模,但是目的都为了预测葡萄酒的品质
本文利用KNN、决策树、随机森林对数据进行建模

数据处理

库与工具

import pandas as pd
#方差选择
from sklearn.feature_selection import VarianceThreshold
#皮尔逊相关系数
from scipy.stats import pearsonr
#标准化
from sklearn.preprocessing import StandardScaler
#数据划分
from sklearn.model_selection import train_test_split
#决策树
from sklearn.tree import DecisionTreeClassifier,export_graphviz
#KNN
from sklearn.neighbors import KNeighborsClassifier
#网格搜索和交叉验证
from sklearn.model_selection import GridSearchCV
#随机森林
from sklearn.ensemble import RandomForestClassifier

工具jupyter notebook

导入数据

在利用read_csv读取该文件时,需要注意sep参数的设置应该为‘;’
在这里插入图片描述该数据集一共有11个特征值和一个目标值
分为别:
1-固定酸度 2-挥发性酸度 3-柠檬酸 4-残留糖 5-氯化物 6-游离二氧化硫
7-总二氧化硫 8-密度 9-pH 10-硫酸盐 11-醇 12-质量
特征值不算很多,所以在数据处理的过程中就没有必要进行特征降维
并且该数据集没有缺失值,省去了缺失值处理

特征工程

数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已,而特征工程就是最大程度从原始数据中提取主要特征供建模使用

#检查是否方差有为0的情况
transfer = VarianceThreshold()
new_data = transfer.fit_transform(data1)
print('new_data:\n',new_data,new_data.shape)

在特征值比较多的大数据集中,可能会存在两个特征之间的方差为0或者方差特别小的情况,也就是这两个特征对于目标值的影响相同或相似,即特征冗余情况,就需要对特征进行选择
在这里插入图片描述
在这11个特征中没有方差为0的情况,VarianceThreshold()中也可以设置一个阈值,删去方差小于该阈值的特征,但是这个数据集比较小,不太适合这种方法
这里选择用皮尔逊相关系数进行特征选择

#特征名字索引
data_title = data1.columns.values.tolist()
r = []
for i in range(len(data_title)):
    for j in range(i+1,len(data_title)):
        print('%s和%s之间的皮尔逊相关系数为%f'%(data_title[i],data_title[j],pearsonr(data1[data_title[i]],data1[data_title[j]])[0]))
        r.append(pearsonr(data[data_title[i]],data[data_title[j]])[0])

可以算出两两特征之间的相关系数,如下图:
在这里插入图片描述
相关系数大致可以理解成三种情况:
当相关系数为0时,X和Y两变量无关系。
当X的值增大(减小),Y值增大(减小),两个变量为正相关,相关系数在[0,1]之间。
当X的值增大(减小),Y值减小(增大),两个变量为负相关,相关系数在[-1,0]之间。
通俗讲就是相关系数越接近于1或-1,两变量相关性越强

for i in range(len(r)):
    if r[i]>0.6:
        print(r[i])
        print(i)
    else:
        continue

索引出相关系数大于0.6,即相关性比较强的特征

0.8389664549045829 30
0.6155009650098364 40

即上图两个红框里的特征:残留糖和密度、游离二氧化硫和总二氧化硫
残留糖和密度的相关性达到了0.83,已经是强相关,所以这里选择删去密度这一特征
在游离二氧化硫和总二氧化硫之间可以尝试进行特征选择

def Quality(e):
    if e>0 and e<=4:
        return 'inferior'
    elif e>4 and e<=7:
        return 'ordinary'
    else:
        return 'superior'
data['Quality'] = data['quality'].map(Quality)
data.drop(['quality'],axis=1,inplace=True)

从数据简介中了解到葡萄酒的质量等级分为0-10,分布太广,并且过于细致,为了建模后利于分类,所以将质量分为三个等级:劣质(inferior)、普通(ordinary)、优质(superior)

利用算法建模

在进行建模之间需要对数据集进行划分,即将数据集分为训练集和目标集

#划分数据集
x_train,x_test,y_train,y_test = train_test_split(data2,data3,test_size =0.2,random_state = 6)

data2为所有的特征,data3为目标值,test_size控制划分程度,即数据中**80%**为训练集,**20%**为测试集
因为有三种方法进行建模,所以控制随机种子相同,便于观察对于该数据集哪一种算法的准确率更高一些

KNN(K最邻近)

所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。

#标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
#KNN预估器
estimator1 = KNeighborsClassifier()
#网格搜索和交叉验证
param_dict = {'n_neighbors':[i for i in range(1,16)]}
estimator1 = GridSearchCV(estimator1,param_grid=param_dict,cv = 10)
estimator1.fit(x_train,y_train)
#模型评估
#1)比对真实值与预测值
y_predict1 = estimator1.predict(x_test)
print('布尔比对:\n',y_predict1==y_test)
#2)查看准确率
score1 = estimator1.score(x_test,y_test)
print('模型准确率:\n',score1)
#得出最优模型
print('最佳结果:\n',estimator1.best_estimator_)

在许多方法的预估器中有超参数,即需要训练者人工输入并作出调整的变量,网格搜索就是选择训练者设置的可选参数值并预估出最优的结果,是算法调优的一种常用方法
KNN建模结果如下图:
在这里插入图片描述

决策树

决策树是一种典型的分类方法,首先对数据进行处理,利用归纳算法生成可读的规则和决策树,然后使用决策对新数据进行分析。本质上决策树是通过一系列规则对数据进行分类的过程。

#决策树预估器
estimator = DecisionTreeClassifier(criterion='entropy')#信息熵
estimator.fit(x_train,y_train)
#模型评估
y_predict = estimator.predict(x_test)
#1)比对真实值与预测值
print('布尔比对:\n',y_predict==y_test)
#2)查看准确率
score = estimator.score(x_test,y_test)
print('模型准确率:\n',score)

export_graphviz(estimator,out_file = 'wine.dot',feature_names=data_title2)

决策树的划分依据之一是信息增益,也算是决策树的一种调优,可以自行了解
决策树建模结果如下图:
在这里插入图片描述

随机森林

随机森林是一个包含多个决策树的分类器, 并且其输出的类别是由个别树输出的类别的众数而定

#随机森林评估器
estimator2 = RandomForestClassifier()
#网格搜索和交叉验证
param_dict = {'n_estimators':[i for i in range(1,100,5)],'max_depth':[i for i in range(10,30,5)]}
estimator2 = GridSearchCV(estimator2,param_grid=param_dict,cv = 3)
estimator2.fit(x_train,y_train)
#模型评估
y_predict2 = estimator.predict(x_test)
#1)比对真实值与预测值
print('布尔比对:\n',y_predict2==y_test)
#1)比对真实值与预测值
#2)查看准确率
score = estimator2.score(x_test,y_test)
print('模型准确率:\n',score)
#得出最优模型
print('最佳结果:\n',estimator2.best_estimator_)

随机森林超参数较多,所以运行时间比较长,也可以利用网格搜索设置不同的参数值进行调优
随机森林建模结果如下图:
在这里插入图片描述

总结

KNN模型准确率:0.9316326530612244
决策树模型准确率:0.9122448979591836
随机森林准确率:0.9510204081632653
三个模型的准确率都还可以,其中随机森林的准确率达到了95%,比较客观
如果想要提高模型的准确率:异常值处理、更佳细致的特征工程、超参数的调节
没有免费的午餐:
虽然随机森林的准确率比较高,但是不能说随机森林算法就优于其他算法甚至代替其他算法,每一种算法都有适合自己的数据,每一种算法的应用场景也是不同的

发布了13 篇原创文章 · 获赞 140 · 访问量 6438

猜你喜欢

转载自blog.csdn.net/weixin_43434202/article/details/102922379