从UCI上获取到了一份winequality的数据来作为小练习的数据源 https://archive.ics.uci.edu/ml/datasets/Wine ,想通过红酒的特征来预测红酒的质量。最后通过随机森林和集成学习的方法,将预测的正确率提升到了90%。
这些数据是对意大利同一地区种植的葡萄酒进行化学分析的结果,这些葡萄酒来自三个不同的品种。该分析确定了三种葡萄酒中每种葡萄酒中含有的13种成分的数量。 数据集中主要采用11种特征变量,一哥目标变量如下:
数据集中属性列表:
attributes | 属性 |
---|---|
fixed acidity | 非挥发性酸; |
volatile acidity | 挥发性酸度 |
citric acid | 柠檬酸 |
residual sugar | 残余糖分 |
chlorides | 氯化物 |
free sulfur dioxide | 游离二氧化硫 |
total sulfur dioxide | 总二氧化硫 |
density | 密度 |
pH | pH值 |
sulphates | 硫酸盐 |
alcohol | 乙醇 |
quality | 品质 |
所有属性都是连续的
1、首先先进行数据的导入,探索与预处理:
import pandas as pd
import numpy as np
data = pd.read_csv('./winequality-red.csv',sep=';',encoding='ISO-8859-1')
观察到表有问题,实际上这个csv文件通过分号分割,所以导入时需要添加:sep=’;’,即可正常读取数据。
2、处理数据是否分布平衡
data['quality'].value_counts()
显然quality为5的数据样本有太多,而quality为3的数据样本又太少,这时候可以考虑过采样,imbalanced-learn可以进行处理。
from imblearn.over_sampling import RandomOverSampler
x = data.iloc[:,:-1].values #icloc方法根据位置悬着,即选择所有行,所有列去掉右数第一列
y= data['quality'].values
ros = RandomOverSampler()#构造采样方法
x,y = ros.fit_sample(x,y)
print(pd.DataFrame(y)[0].value_counts().sort_index())
先用LR回归尝试一下,这里也权当复习,先可以尝试把所有特征都用上,利用交叉检验,看看预测结果如何:
import sklearn
from sklearn import linear_model
lm = linear_model.LogisticRegression()
features = data.columns.values.tolist()[:-1]
x = data[features]
y = data['quality']
from sklearn.model_selection import cross_val_score
#logistic 中的scroing参数指定为accuracy
scores = cross_val_score(lm,x,y,cv=5,scoring='accuracy')
print(np.mean(scores))
输出结果为0.57可以看到如果直接在原始不平衡数据上把所有特征都用上,使用LR回归几乎对预测这个多分类的quality没有什么帮助,后来再过采样后的数据上也用了LR回归同样准确率很不理想。
以为可能是由于特征的多重共线性导致的,所以有差看一下所有使用的特征的相关性,这个可以利用seaborn快速可视化的实现这一效果,代码如下:
import matplotlib.pyplot as plt
import seaborn as sns
data = data.corr()
sns.heatmap(data)
plt.show()
显示如上:可以看到多数变量之间实际上相关系数都在0.4以下,不存在高度相关。
随机森林就是通过集成学习的思想将多棵树集成的一种算法,它的基本单元是决策树,而它的本质属于机器学习的一大分支——集成学习(Ensemble Learning)方法。
from sklearn import ensemble
#设置随机深林分类模型
rf = ensemble.RandomForestClassifier(100) #设置100个决策树
from sklearn.model_selection import cross_val_score
score = cross_val_score(rf,x,y,cv=5,scoring='accuracy')
print(np.mean(score)
得到结果是86%,大大超过了Logistics回归的准确率,这种交叉检验的方法是训练集是所有样本都使用了。
使用predict()函数得到上一节训练的随机森林模型在测试集合上的预测结果,然后使用 sklearn.metrics中的相关函数对模型的性能进行评估。
得到的结果如下:
precision recall f1-score support
3 0.99 1.00 0.99 142
4 1.00 1.00 1.00 129
5 0.80 0.81 0.80 150
6 0.77 0.66 0.71 146
7 0.87 0.98 0.92 125
8 0.99 1.00 1.00 126
avg / total 0.90 0.90 0.90 818
[[142 0 0 0 0 0]
[ 0 129 0 0 0 0]
[ 2 0 121 26 1 0]
[ 0 0 31 96 18 1]
[ 0 0 0 2 123 0]
[ 0 0 0 0 0 126]]
Accuracy: 0.90097799511
准确度在90%左右,由于前面在抽取训练集和测试集时random_state设置为0,我们可以测试多次,会选取到不同的训练集和测试集,测算多个准确度求平均值进行比较,经过测试仍然维持在90%左右。