一、选题背景:
我国餐桌酒文化盛行,白酒、红酒及啤酒的消费比较普及。随着国民经济的快速增长,居民收入及消费能力不断提高,消费结构逐渐升级,消费者的饮酒习惯随之改变,加上红酒文化知识在我国的渗透,消费者对低度酒精饮料-一红酒认知度不断提高,红酒不仅仅作为一种产品被消费,同时也作为一种时尚、高雅的文化和品位的象征慢慢渗透消费层次,中国红酒消费市场同时呈现出高速增长。而许多企业仍然缺乏产品质量及诚信意识,生产冒牌、假品和产区、假年份酒等伪劣产品,扰乱了正常的市场秩序。
二、数据说明:
kaggle的https://www.kaggle.com/hufe09/winequality 项目提供了红酒品质的具体的数据,该数据包括了红酒的挥发性酸度、氯化物、游离二氧化硫、总二氧化硫、ph值等数据
三、实施过程及代码
导入库
import numpy as np import scipy as sp import pandas as pd import matplotlib import seaborn as sn import pylab as pl import matplotlib.pyplot as plt from sklearn.linear_model import LogisticRegression from sklearn import linear_model from sklearn import tree from sklearn.ensemble import RandomForestClassifier import warnings#忽略warning提示
查看数据大小
hj = pd.read_csv('E:/excl/winequality-red(4).csv') print('红酒品质:',hj.shape,)
#查看数据情况 hj.head()
#计算红酒的总酸度 hj['total acid'] = hj['fixed acidity'] + hj['volatile acidity'] + hj['citric acid'] #移动hj总酸到列首 r = hj.columns.tolist() r.insert(0,r.pop()) hj = hj.reindex(columns=r) #移动hj总酸到列首 r =hj.columns.tolist() r.insert(0,r.pop()) hj = hj.reindex(columns=r)
hj.head()
hj.columns.tolist()
通过上述表格,我们可以看到红酒的品质的总酸度,酸度,残糖,二氧化硫,ph等具体值。
#查看数据总体信息 print('红酒品质:',hj.info(),)
二、数据清洗
#缺失值查询 #只显示存在缺失值的行列,清楚的确定缺失值的位置 #[hj.isnull().values==True]是条件表达式
hj[hj.isnull().values==True]
说明该数据没有缺失值
#删除无效列与行,可使用如下drop方法进行无效列的处理(axis =1)。 #若处理无效行,设置axis =0。 #axis=0表示index行,axis=1表示columns列,默认为0
#统计各列的空值情况 print('\n各列的空值情况如下:') hj.isnull().sum()
# 查找重复值,索引行返回值为“True”,表示该行是一个重复值行 hj.duplicated()
# 删除重复值 hj = hj.drop_duplicates() print(hj.shape)
# 查找重复值 hj.duplicated()#显示表示已经删除重复值
#使用describe查看统计信息 hj.describe()
三、 大数据分析过程及采用的算法
sns.set_style('ticks') sns.set_context("notebook", font_scale=1.4) plt.figure(figsize=(6,4))#画出双变量的散点图,然后以y~x拟合回归方程和预测值95%置信区间并将其画出。 sns.regplot(x='density',y='alcohol',data=hj, scatter_kws={'s':10}) plt.xlim(0.989,1.005) plt.ylim(7,16) print("密度 vs 酒精浓度")
密度和酒精浓度是相关的,物理上,两者并不是线性关系。上图展示了两者的关系。另外密度还与酒中其他物质的含量有关,但是关系很小
from sklearn import linear_model model = linear_model.LinearRegression() x=hj['density'].values y=hj['alcohol'].values x=x.reshape(-1,1) model.fit(x,y) print("回归方程系数{}".format(model.coef_)) print("回归方程截距:{}".format(model.intercept_))
x = np.random.uniform(hj['alcohol']) y = np.log(x) + np.random.normal(hj['density']) pl.scatter(x, y, s=1, label="log(x) with noise") pl.plot(np.arange(1, 100), np.log(np.arange(1, 100)), c="b", label="log(x) true function") pl.xlabel("x") pl.ylabel("f(x) = log(x)") pl.legend(loc="best") pl.title("A Basic Log Function") pl.show()
随机森林
warnings.filterwarnings("ignore") data= pd.read_csv('E:/excl/winequality-red(4).csv') data.replace([3,4,5,6,7,8],[0,0,0,1,1,1],inplace=True)#我们将质量为6以上评为高质量 X = data.iloc[:, :-1]#切片不包含最后一列 Y = data.iloc[:,-1]#结果 #kfold,将数据分成三部份 from sklearn.model_selection import KFold k = KFold(n_splits = 3) #class k=3 #定义函数,用于返回模型的平均accuarcy(正确率) def get_score(model, x_train, x_test, y_train, y_test): model.fit(x_train, y_train) return model.score(x_test, y_test) #函数score返回模型的平均 accuracy(正确率) #定义画图函数 def draw(fpr,tpr): plt.figure() lw = 2 plt.plot(fpr, tpr, color='darkorange', lw=lw, label='ROC curve (area = %0.2f)' % auc(fpr, tpr)) plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--') plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('Receiver operating characteristic example') plt.legend(loc="lower right") plt.show() from sklearn.metrics import roc_curve from sklearn.metrics import auc,accuracy_score RF = RandomForestClassifier(n_estimators = 100,max_samples=0.2) scoreRF = [] s=1 for train,test in k.split(data): #计算平均得分 scoreRF.append(get_score(RF,X.loc[train],X.loc[test],Y.loc[train],Y.loc[test])) #画图 roc曲线,auc得分 fpr, tpr, thresholds = roc_curve(Y.loc[test], RF.predict_proba(X.loc[test])[:, 1]) print("随机森林%s"%s) draw(fpr,tpr) s+=1 print("随机森林:",scoreRF)
输出结果的准确率大致在七点几
绘图
colnm = hj.columns.tolist() plt.figure(figsize=(15,12)) for i in range(12): plt.subplot(4,3,i+1) hj[colnm[i]].hist(bins = 50)#bins指每张图柱子的个数 plt.xlabel(colnm[i], fontsize=12)#xlabel:x轴标注 plt.ylabel('Frequency')#频率ylabel:y轴标注 plt.tight_layout()# 处理图与图之间的空隙 print('\n单变量直方图'
通过上图我们可以看到每一个红酒品质列名直方图
#游离二氧化硫与总二氧化硫比较 plt.rcParams['font.sans-serif']=['SimHei'] plt.rcParams['axes.unicode_minus'] = False data1 = np.array(hj['free sulfur dioxide'][:10]) data2 = np.array(hj['total sulfur dioxide'][:10]) width =0.3 plt.bar(np.arange(len(data1)), data1, width=width, label='free sulfur') plt.bar(np.arange(len(data2))+ width, data2, width=width, label='total sulfur') plt.title('游离二氧化硫与总二氧化硫比较') plt.legend() plt.show()
总二氧化硫远远高于游离的二氧化硫
plt.figure(figsize = (6,4)) plt.hist(hj['total acid'], bins = 50) plt.xlabel('total acid') plt.ylabel('Frequency') plt.tight_layout() print("总酸性直方图")
#红酒品质ph的直方图用Matplotlib和Seaborn画直方图 a = hj['pH'] s = pd.Series(a) plt.hist(s,bins=50 ) plt.show() sns.distplot(s, kde=True) plt.show()
从上面三幅图可以看出红酒的ph值平均在3.3,说明红酒的口感清脆鲜活。
#红酒品质质量的直方图用Matplotlib和Seaborn画直方图 a = hj['quality'] s = pd.Series(a) plt.hist(s,bins=20) plt.show() sns.distplot(s, kde=True) plt.show()
可以看出数据集的大多数红酒的品质在5和6之间,最差的是3,而最好的是8,但分布都比较少
hj['sweetness']=pd.cut(hj['residual sugar'], bins = [0,4,12,45],labels=["dry","medium dry","semi-sweet"]) plt.figure(figsize =(5,3)) hj['sweetness'].value_counts().plot(kind = 'bar') plt.xticks(rotation=0)#rotation代表lable显示的旋转角度。 plt.xlabel('sweetness',fontsize=12)#fontsize文字大小 plt.ylabel('',fontsize=12) plt.tight_layout() print("甜度")
残糖与酒的甜度相关,通常用来区别各种红酒,干红<=4, 半干4-12,半甜12-45,和甜>45这个数据中主要为干红,没有甜葡萄酒。
fig = plt.figure(figsize=(15,9)) for i in range(12): plt.subplot(3,4,i+1) # 三行四列 位置是i+1的子图 # orient:"v"|"h" 用于控制图像使水平还是竖直显示(这通常是从输入变量的dtype推断出来的,此参数一般当不传入x、y,只传入data的时候使用) sns.boxplot(hj[colnm[i]], orient="v", width = 0.3) plt.ylabel(colnm[i],fontsize = 13) # plt.xlabel('one_pic') # 图形调整 plt.subplots_adjust(left=0.2, wspace=0.8, top=0.9, hspace=0.1) # 子图的左侧 子图之间的宽度间隔 子图的高 子图之间的高度间隔 # tight_layout会自动调整子图参数,使之填充整个图像区域 plt.tight_layout() print('箱线图')
plt.figure(figsize=(10,8)) colnm = hj.columns.tolist()[:11]+['total acid','quality'] mcorr = hj[colnm].corr()#相关系数矩阵,即给出了任意两个变量之间的相关系数 mask = np.zeros_like(mcorr,dtype=np.bool) # 创建一个mcorr一样的全False矩阵 mask[np.triu_indices_from(mask)]=True # 上三角置位True cmap = sns.diverging_palette(220,10,as_cmap=True)# 建立一个发散调色板 g=sns.heatmap(mcorr,mask=mask, cmap=cmap, square=True,annot=True, fmt='0.1f') print("两两相关图")
根据上述两幅图可以看出品质好的酒有更高的柠檬酸,其中酒精度数和品质的相关性最高。 品质好的酒有较低的挥发性酸类,密度,和pH。 残留糖分,氯离子,二氧化硫似乎对酒的品质影响不大。
对于好酒(7,8)以及差酒(3,4),关系很明显。但是对于中等酒(5,6),酒精浓度的挥发性酸度有很大程度的交叉。
根据上图可以得到质量较好的酒含的酒精量较高, 质量不好的酒的挥发性酸较高。
sns.lmplot(x = 'alcohol', y = 'volatile acidity', col='quality', hue = 'quality', data = hj,fit_reg = False, size = 3, aspect= 0.9, col_wrap=3,scatter_kws={'s':20}) print("酒精挥发酸和质量的散点图") plt.show()
品质相关性最高的三个特征是酒精浓度,挥发性酸度,和柠檬酸。下面图中显示的酒精浓度,挥发性酸和品质的关系。 酒精浓度,挥发性酸和品质 对于好酒(7,8)以及差酒(3,4),关系很明显。但是对于中等酒(5,6),酒精浓度的挥发性酸度有很大程度的交叉。
sns.set_style('ticks') sns.set_context("notebook", font_scale= 1.4) plt.figure(figsize=(6,5)) cm = plt.cm.get_cmap('RdBu') sc = plt.scatter(hj['fixed acidity'], hj['citric acid'], c=hj['pH'], vmin=2.6, vmax=4, s=15, cmap=cm) bar = plt.colorbar(sc) bar.set_label('pH', rotation = 0) plt.xlabel('fixed acidity') plt.ylabel('citric acid') plt.xlim(4,18) plt.ylim(0,1) print('酸度何柠檬酸固定的ph值')
pH,非挥发性酸和柠檬酸 pH和非挥发性的酸以及柠檬酸有相关性。整体趋势也很合理,即浓度越高,pH越低。
总代码
1 import numpy as np 2 import scipy as sp 3 import pandas as pd 4 import matplotlib 5 import seaborn as sns 6 import pylab as pl 7 import matplotlib.pyplot as plt 8 from sklearn.linear_model import LogisticRegression 9 from sklearn import linear_model 10 from sklearn import tree 11 from sklearn.ensemble import RandomForestClassifier 12 import warnings#忽略warning提示 13 14 hj = pd.read_csv('E:/excl/winequality-red(4).csv') 15 print('红酒品质:',hj.shape,) 16 #查看数据情况 17 hj.head() 18 #计算红酒的总酸度 19 hj['total acid'] = hj['fixed acidity'] + hj['volatile acidity'] + hj['citric acid'] 20 #移动hj总酸到列首 21 r = hj.columns.tolist() 22 r.insert(0,r.pop()) 23 hj = hj.reindex(columns=r) 24 #移动hj总酸到列首 25 r =hj.columns.tolist() 26 r.insert(0,r.pop()) 27 hj = hj.reindex(columns=r) 28 #查看数据情况 29 hj.head() 30 hj.columns.tolist() 31 #查看数据总体信息 32 print('红酒品质:',hj.info(),) 33 #数据清洗 34 hj[hj.isnull().values==True] 35 #统计各列的空值情况 36 print('\n各列的空值情况如下:') 37 hj.isnull().sum() 38 # 查找重复值,索引行返回值为“True”,表示该行是一个重复值行 39 hj.duplicated() 40 # 删除重复值 41 hj = hj.drop_duplicates() 42 print(hj.shape) 43 # 将异常值替换为平均值 44 hj.replace([512.329200],hj['chlorides'].mean()).head() 45 hj.describe() 46 47 #三 大数据分析过程 48 sns.set_style('ticks') 49 sns.set_context("notebook", font_scale=1.4) 50 plt.figure(figsize=(6,4))#画出双变量的散点图,然后以y~x拟合回归方程和预测值95%置信区间并将其画出。 51 sns.regplot(x='density',y='alcohol',data=hj, scatter_kws={'s':10}) 52 plt.xlim(0.989,1.005) 53 plt.ylim(7,16) 54 print("密度 vs 含酒饮料") 55 56 #线性回归 57 from sklearn import linear_model 58 model = linear_model.LinearRegression() 59 x=hj['density'].values 60 y=hj['alcohol'].values 61 x=x.reshape(-1,1) 62 model.fit(x,y) 63 print("回归方程系数{}".format(model.coef_)) 64 print("回归方程截距:{}".format(model.intercept_)) 65 66 x = np.random.uniform(hj['alcohol']) 67 y = np.log(x) + np.random.normal(hj['density']) 68 pl.scatter(x, y, s=1, label="log(x) with noise") 69 pl.plot(np.arange(1, 100), np.log(np.arange(1, 100)), c="b", label="log(x) true function") 70 pl.xlabel("x") 71 pl.ylabel("f(x) = log(x)") 72 pl.legend(loc="best") 73 pl.title("A Basic Log Function") 74 pl.show() 75 76 #随机森林 77 warnings.filterwarnings("ignore") 78 data= pd.read_csv('E:/excl/winequality-red(4).csv') 79 80 data.replace([3,4,5,6,7,8],[0,0,0,1,1,1],inplace=True)#我们将质量为6以上评为高质量 81 X = data.iloc[:, :-1]#切片不包含最后一列 82 Y = data.iloc[:,-1]#结果 83 #kfold,将数据分成三部份 84 from sklearn.model_selection import KFold 85 k = KFold(n_splits = 3) #class k=3 86 #定义函数,用于返回模型的平均accuarcy(正确率) 87 def get_score(model, x_train, x_test, y_train, y_test): 88 model.fit(x_train, y_train) 89 return model.score(x_test, y_test) #函数score返回模型的平均 accuracy(正确率) 90 #定义画图函数 91 def draw(fpr,tpr): 92 plt.figure() 93 lw = 2 94 plt.plot(fpr, tpr, color='darkorange', 95 lw=lw, label='ROC curve (area = %0.2f)' % auc(fpr, tpr)) 96 plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--') 97 plt.xlim([0.0, 1.0]) 98 plt.ylim([0.0, 1.05]) 99 plt.xlabel('False Positive Rate') 100 plt.ylabel('True Positive Rate') 101 plt.title('Receiver operating characteristic example') 102 plt.legend(loc="lower right") 103 plt.show() 104 from sklearn.metrics import roc_curve 105 from sklearn.metrics import auc,accuracy_score 106 RF = RandomForestClassifier(n_estimators = 100,max_samples=0.2) 107 scoreRF = [] 108 s=1 109 for train,test in k.split(data): 110 #计算平均得分 111 scoreRF.append(get_score(RF,X.loc[train],X.loc[test],Y.loc[train],Y.loc[test])) 112 #画图 roc曲线,auc得分 113 fpr, tpr, thresholds = roc_curve(Y.loc[test], RF.predict_proba(X.loc[test])[:, 1]) 114 print("随机森林%s"%s) 115 draw(fpr,tpr) 116 s+=1 117 118 print("随机森林:",scoreRF) 119 #4画图 120 colnm = hj.columns.tolist() 121 plt.figure(figsize=(15,12)) 122 for i in range(12): 123 plt.subplot(4,3,i+1) 124 hj[colnm[i]].hist(bins = 50)#bins指每张图柱子的个数 125 plt.xlabel(colnm[i], fontsize=12)#xlabel:x轴标注 126 plt.ylabel('Frequency')#频率ylabel:y轴标注 127 plt.tight_layout()# 处理图与图之间的空隙 128 print('\n单变量直方图') 129 130 #游离二氧化硫与总二氧化硫比较 131 plt.rcParams['font.sans-serif']=['SimHei'] 132 plt.rcParams['axes.unicode_minus'] = False 133 data1 = np.array(hj['free sulfur dioxide'][:10]) 134 data2 = np.array(hj['total sulfur dioxide'][:10]) 135 width =0.3 136 plt.bar(np.arange(len(data1)), data1, width=width, label='free sulfur') 137 plt.bar(np.arange(len(data2))+ width, data2, width=width, label='total sulfur') 138 plt.title('游离二氧化硫与总二氧化硫比较') 139 plt.legend() 140 plt.show() 141 142 #2总酸度 143 plt.figure(figsize = (6,4)) 144 plt.hist(hj['total acid'], bins = 50) 145 plt.xlabel('total acid') 146 plt.ylabel('Frequency') 147 plt.tight_layout() 148 print("总酸性直方图") 149 150 #3ph和质量 151 #红酒品质ph的直方图用Matplotlib和Seaborn画直方图 152 a = hj['pH']#ph 153 s = pd.Series(a) 154 plt.hist(s,bins=20) 155 plt.show() 156 sns.distplot(s, kde=True) 157 plt.show() 158 159 #红酒品质质量的直方图用Matplotlib和Seaborn画直方图 160 a = hj['quality']#质量 161 s = pd.Series(a) 162 plt.hist(s,bins=20) 163 plt.show() 164 sns.distplot(s, kde=True) 165 plt.show() 166 167 #甜度 168 hj['sweetness']=pd.cut(hj['residual sugar'], bins = [0,4,12,45],labels=["dry","medium dry","semi-sweet"]) 169 plt.figure(figsize =(5,3)) 170 hj['sweetness'].value_counts().plot(kind = 'bar') 171 plt.xticks(rotation=0)#rotation代表lable显示的旋转角度。 172 plt.xlabel('sweetness',fontsize=12)#fontsize文字大小 173 plt.ylabel('',fontsize=12) 174 plt.tight_layout() 175 print("甜度") 176 177 #单变量箱图 178 fig = plt.figure(figsize=(15,9)) 179 for i in range(12): 180 plt.subplot(3,4,i+1) # 三行四列 位置是i+1的子图 181 # orient:"v"|"h" 用于控制图像使水平还是竖直显示(这通常是从输入变量的dtype推断出来的,此参数一般当不传入x、y,只传入data的时候使用) 182 sns.boxplot(hj[colnm[i]], orient="v", width = 0.3) 183 plt.ylabel(colnm[i],fontsize = 13) 184 # plt.xlabel('one_pic') 185 # 图形调整 186 plt.subplots_adjust(left=0.2, wspace=0.8, top=0.9, hspace=0.1) # 子图的左侧 子图之间的宽度间隔 子图的高 子图之间的高度间隔 187 # tight_layout会自动调整子图参数,使之填充整个图像区域 188 plt.tight_layout() 189 print('箱线图') 190 #两两相关图 191 192 plt.figure(figsize=(10,8)) 193 colnm = hj.columns.tolist()[:11]+['total acid','quality'] 194 mcorr = hj[colnm].corr()#相关系数矩阵,即给出了任意两个变量之间的相关系数 195 mask = np.zeros_like(mcorr,dtype=np.bool) # 创建一个mcorr一样的全False矩阵 196 mask[np.triu_indices_from(mask)]=True # 上三角置位True 197 cmap = sns.diverging_palette(220,10,as_cmap=True)# 建立一个发散调色板 198 g=sns.heatmap(mcorr,mask=mask, cmap=cmap, square=True,annot=True, fmt='0.1f') 199 print("两两相关图") 200 201 #酒精挥发酸和质量的散点图 202 sns.lmplot(x = 'alcohol', y = 'volatile acidity', col='quality', hue = 'quality', data = hj,fit_reg = False, size = 3, aspect= 0.9, col_wrap=3,scatter_kws={'s':20}) 203 print("酒精挥发酸和质量的散点图") 204 plt.show() 205 206 #酸度何柠檬酸固定的ph值 207 sns.set_style('ticks') 208 sns.set_context("notebook", font_scale= 1.4) 209 plt.figure(figsize=(6,5)) 210 cm = plt.cm.get_cmap('RdBu') 211 sc = plt.scatter(hj['fixed acidity'], hj['citric acid'], c=hj['pH'], vmin=2.6, vmax=4, s=15, cmap=cm) 212 bar = plt.colorbar(sc) 213 bar.set_label('pH', rotation = 0) 214 plt.xlabel('fixed acidity') 215 plt.ylabel('citric acid') 216 plt.xlim(4,18) 217 plt.ylim(0,1) 218 print('酸度何柠檬酸固定的ph值')
在红酒品质的分析过程中,pH值主要是与fixed acidity有关,品质好的酒有更高的柠檬酸,硫酸盐,和酒精度数。硫酸盐的加入通常是调整酒的酸度的。其中酒精度数和品质的相关性最高。品质好的酒有较低的挥发性酸类,密度,和pH。残留糖分,氯离子,二氧化硫似乎对酒的品质影响不大。另外密度还与酒中其他物质的含量有关,但是关系很小。pH和非挥发性酸性物质有-0.683的相关性。因为非挥发性酸性物质的含量远远高于其他酸性物质。整体而言,红酒的品质主要与酒精浓度,挥发性酸,和柠檬酸有关。对于品质优于7,或者劣于4的酒,直观上是线性可分的。但是品质为5,6的酒很难线性区分。
在此次的课程设计中我学到了很多,刚开始容易犯一些简单的错误什么标点,练习多了后面就很少犯了,但是还会犯一些语法错误,上网查了好多函数的用法,然后把相关函数的用法一个一个搞清楚并且标注上去,然后再用自己的数据集改并且一步一步让代码运行出来,在数据分析的第三问也就是大数据分析和采用算法哪一步,通过不断的上网学习将代码改出来,在绘图的过程中,上网找到https://matplotlib.org/ 绘图网站,里面有相应的代码,参照上面的绘图代码然后在改改,但是在改的过程中出现了n多次错误,有时候改的太难了,但是最终还是完成了这个课程设计,这个课程设计很有挑战性,通过此次课程设计,这门课程是一门不简单的课程,要通过自己的钻研才能学到东西,这让我更想学好python。