持續優化中~~~
研究背景:
中國制酒歷史源遠流長,品種繁多,名酒薈萃,享譽中外。其中,黃酒跟白酒是兩種主要的酒類。它們滲透於中華民族的源遠流長的文明史中,對文學創作、文化娛樂、飲食文化的影響更是起到一個重要作用。但是,隨着全球化的腳步,我們的生活中漸漸出現了紅葡萄酒、白葡萄酒。喝葡萄酒漸漸成為一種時尚。百度了一下葡萄酒的功能,有如下:
1)葡萄酒中含有抗氧化成分和豐富的酚類化合物,可防止動脈硬化和血小板凝結,保護並維持心腦血管系統的正常生理機能,起到保護心臟、防止中風的作用;
2) 飲用葡萄酒對女性有很好的美容養顏的功效,可養氣活血,使皮膚富有彈性。
好像還很不錯的樣子。在 UCI數據庫中,發現一個關於葡萄酒質量評分的數據集,於是決定來探討一下影響葡萄酒口感的因素是什么。
目的:
從UCI下載數據集:Wine Quality Data Set ,里面包含紅葡萄酒和白葡萄酒的2個樣本數據集。里面均包含葡萄酒的11個物理化學方面的因素,還有1個對葡萄酒質量的測評平均分數(0-10分)。現采用其白葡萄酒數據,對該數據集進行一定的數據分析:
(1)建立回歸模型,研究這些性質是怎樣影響白葡萄酒的質量評價
(2)找出影響較大的前三因素
(3)這些物理化學性質之間是否存在一定的關系
目錄:
一.數據探索分析&數據預處理
二.建模分析
三.總結與建議
一.數據探索分析&數據預處理
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams["font.sans-serif"]=["SimHei"] #正常顯示中文標簽
plt.rcParams["axes.unicode_minus"]=False #正常顯示負號
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
#導入數據
data = pd.read_csv(r"G:\data\UCI data\Wine Quality\winequality-white.csv", sep=";")
下面先觀察一下白葡萄酒數據:
data.head()
fixed acidity | volatile acidity | citric acid | residual sugar | chlorides | free sulfur dioxide | total sulfur dioxide | density | pH | sulphates | alcohol | quality | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 7.0 | 0.27 | 0.36 | 20.7 | 0.045 | 45.0 | 170.0 | 1.0010 | 3.00 | 0.45 | 8.8 | 6 |
1 | 6.3 | 0.30 | 0.34 | 1.6 | 0.049 | 14.0 | 132.0 | 0.9940 | 3.30 | 0.49 | 9.5 | 6 |
2 | 8.1 | 0.28 | 0.40 | 6.9 | 0.050 | 30.0 | 97.0 | 0.9951 | 3.26 | 0.44 | 10.1 | 6 |
3 | 7.2 | 0.23 | 0.32 | 8.5 | 0.058 | 47.0 | 186.0 | 0.9956 | 3.19 | 0.40 | 9.9 | 6 |
4 | 7.2 | 0.23 | 0.32 | 8.5 | 0.058 | 47.0 | 186.0 | 0.9956 | 3.19 | 0.40 | 9.9 | 6 |
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4898 entries, 0 to 4897
Data columns (total 12 columns):
fixed acidity 4898 non-null float64
volatile acidity 4898 non-null float64
citric acid 4898 non-null float64
residual sugar 4898 non-null float64
chlorides 4898 non-null float64
free sulfur dioxide 4898 non-null float64
total sulfur dioxide 4898 non-null float64
density 4898 non-null float64
pH 4898 non-null float64
sulphates 4898 non-null float64
alcohol 4898 non-null float64
quality 4898 non-null int64
dtypes: float64(11), int64(1)
memory usage: 459.3 KB
1.數據集基本情況探索:
(1)數據集中總共有4898個白葡萄酒的樣本數據。其中,包含11個物理化學的特征和1個葡萄酒質量評分。
分別為:
- fixed acidity 非揮發性酸
- volatile acidity 揮發性酸
- citric acid 檸檬酸
- residual sugar 剩余糖分
- chlorides 氯化物
- free sulfur dioxide 游離二氧化硫
- total sulfur dioxide 總二氧化硫
- density 密度
- pH 酸鹼性
- sulphates 硫酸鹽
- alcohol 酒精
- quality 質量
(2)數據完整,無缺失值。注意到,有些數值小於0.1,有些數值大於100。在做回歸模型時,我們常用MSE(均方誤差)來衡量模型的好壞,如果數據量綱不一樣,可能影響我們對模型的評估,所以后面我們將對數據進行歸一化處理,排除量綱帶來的影響。
(3)11個因素均為浮點型數據,最后的質量評分為整型數據。
下面通過計算均值、方差、最小最大值等,配合數據的分布直方圖來看數據的大致分布:
data.describe()
fixed acidity | volatile acidity | citric acid | residual sugar | chlorides | free sulfur dioxide | total sulfur dioxide | density | pH | sulphates | alcohol | quality | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 4898.000000 | 4898.000000 | 4898.000000 | 4898.000000 | 4898.000000 | 4898.000000 | 4898.000000 | 4898.000000 | 4898.000000 | 4898.000000 | 4898.000000 | 4898.000000 |
mean | 6.854788 | 0.278241 | 0.334192 | 6.391415 | 0.045772 | 35.308085 | 138.360657 | 0.994027 | 3.188267 | 0.489847 | 10.514267 | 5.877909 |
std | 0.843868 | 0.100795 | 0.121020 | 5.072058 | 0.021848 | 17.007137 | 42.498065 | 0.002991 | 0.151001 | 0.114126 | 1.230621 | 0.885639 |
min | 3.800000 | 0.080000 | 0.000000 | 0.600000 | 0.009000 | 2.000000 | 9.000000 | 0.987110 | 2.720000 | 0.220000 | 8.000000 | 3.000000 |
25% | 6.300000 | 0.210000 | 0.270000 | 1.700000 | 0.036000 | 23.000000 | 108.000000 | 0.991723 | 3.090000 | 0.410000 | 9.500000 | 5.000000 |
50% | 6.800000 | 0.260000 | 0.320000 | 5.200000 | 0.043000 | 34.000000 | 134.000000 | 0.993740 | 3.180000 | 0.470000 | 10.400000 | 6.000000 |
75% | 7.300000 | 0.320000 | 0.390000 | 9.900000 | 0.050000 | 46.000000 | 167.000000 | 0.996100 | 3.280000 | 0.550000 | 11.400000 | 6.000000 |
max | 14.200000 | 1.100000 | 1.660000 | 65.800000 | 0.346000 | 289.000000 | 440.000000 | 1.038980 | 3.820000 | 1.080000 | 14.200000 | 9.000000 |
plt.style.use("ggplot")
data.hist(figsize=(12,12), color="#476DD5", edgecolor="k")
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x000000F085C85668>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F085F13DD8>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F085F964A8>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x000000F086000BE0>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F086067080>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F0860670B8>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x000000F08612EF28>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F0863DA828>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F086431A58>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x000000F086469B00>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F0864F9E10>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F08650BF28>]], dtype=object)
data.boxplot(figsize=(18,9))
plt.yticks(fontsize=14,color="k")
plt.xticks(fontsize=12,color="#081073")
(array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
<a list of 12 Text xticklabel objects>)
sns.pairplot(data)
<seaborn.axisgrid.PairGrid at 0xf08682a588>
data.skew().sort_values(ascending=False)
chlorides 5.023331
volatile acidity 1.576980
free sulfur dioxide 1.406745
citric acid 1.281920
residual sugar 1.077094
density 0.977773
sulphates 0.977194
fixed acidity 0.647751
alcohol 0.487342
pH 0.457783
total sulfur dioxide 0.390710
quality 0.155796
dtype: float64
data.kurt().sort_values(ascending=False)
chlorides 37.564600
free sulfur dioxide 11.466342
density 9.793807
citric acid 6.174901
volatile acidity 5.091626
residual sugar 3.469820
fixed acidity 2.172178
sulphates 1.590930
total sulfur dioxide 0.571853
pH 0.530775
quality 0.216526
alcohol -0.698425
dtype: float64
(data.max()-data.min()).sort_values(ascending=False)
total sulfur dioxide 431.00000
free sulfur dioxide 287.00000
residual sugar 65.20000
fixed acidity 10.40000
alcohol 6.20000
quality 6.00000
citric acid 1.66000
pH 1.10000
volatile acidity 1.02000
sulphates 0.86000
chlorides 0.33700
density 0.05187
dtype: float64
2.從均值、標准差、四分位數等值,及直方圖看到:
(1)所有的特征都不是正態分布,均呈現右偏。chlorides(氯化物)的右偏程度最大,為5.02,接着是volatile acidity(揮發性酸):1.58 、free sulfur dioxide(游離二氧化硫):1.41;右偏最小的三個特征為:total sulfur dioxide(總二氧化硫0.39)< PH(酸鹼度0.46)< alcohol(酒精0.49)。
(2)每個特征的極差(最大值減去最小值的值)相差較大,最大的為total sulfur dioxide(總二氧化硫):431,最小的為density(密度),僅為0.05。后面將對數據進行歸一化處理,消除量綱影響。
(3)從四分位數來看,可能存在異常值。從箱線圖來看,存在較多的較大的值。為了便於觀察,下面進行歸一化,借用箱線圖更細致來看數據的集中分布情況、異常值的情況。
(4)質量評分最小值為3,最大值為9。50%的評分為5或6分,看出大多數白葡萄酒質量處於中等水平,不會太差,也不會太好。
(5)看到大多數變量之間的關系較小,下面通過具體的數值及熱力圖做更深入探討。
3.下面對數據進行標准化處理,讓數據減去其均值再除以其對應的標准差:
from sklearn.preprocessing import scale
data_scaled = scale(data)
data_scaled
array([[ 1.72096961e-01, -8.17699008e-02, 2.13280202e-01, ...,
-3.49184257e-01, -1.39315246e+00, 1.37870140e-01],
[ -6.57501128e-01, 2.15895632e-01, 4.80011213e-02, ...,
1.34184656e-03, -8.24275678e-01, 1.37870140e-01],
[ 1.47575110e+00, 1.74519434e-02, 5.43838363e-01, ...,
-4.36815783e-01, -3.36667007e-01, 1.37870140e-01],
...,
[ -4.20473102e-01, -3.79435433e-01, -1.19159198e+00, ...,
-2.61552731e-01, -9.05543789e-01, 1.37870140e-01],
[ -1.60561323e+00, 1.16673788e-01, -2.82557040e-01, ...,
-9.62604939e-01, 1.85757201e+00, 1.26711420e+00],
[ -1.01304317e+00, -6.77100966e-01, 3.78559282e-01, ...,
-1.48839409e+00, 1.04489089e+00, 1.37870140e-01]])
plt.figure(figsize=(17,8))
columns = ["非揮發性酸","揮發性酸","檸檬酸","剩余糖分","氯化物","游離二氧化硫","總二氧化硫",
"密度","酸鹼性","硫酸鹽","酒精","質量"]
plt.boxplot(data_scaled,
showmeans=True,meanprops={"marker":"D","markerfacecolor":"red"},#設置均值點的屬性,點的形狀、填充色
labels=columns
)
plt.title("歸一化后數據的箱線圖",color="#4013AF",size=18)
plt.yticks(fontsize=14,color="k")
plt.xticks(fontsize=14.5,color="#081073")
(array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
<a list of 12 Text xticklabel objects>)
data_scaled = pd.DataFrame(data_scaled)
data_scaled.hist(figsize=(15,8))
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x000000F08449F828>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F091CE97B8>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F091CFAF60>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x000000F091DB8898>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F091E1A160>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F091E1A198>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x000000F0920E1CF8>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F09215FA90>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F0921C54E0>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x000000F092203978>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F09228AFD0>,
<matplotlib.axes._subplots.AxesSubplot object at 0x000000F09229DB38>]], dtype=object)
data_scaled.skew().sort_values(ascending=False)
4 5.023331
1 1.576980
5 1.406745
2 1.281920
3 1.077094
7 0.977773
9 0.977194
0 0.647751
10 0.487342
8 0.457783
6 0.390710
11 0.155796
dtype: float64
data_scaled.kurt().sort_values(ascending=False)
4 37.564600
5 11.466342
7 9.793807
2 6.174901
1 5.091626
3 3.469820
0 2.172178
9 1.590930
6 0.571853
8 0.530775
11 0.216526
10 -0.698425
dtype: float64
(data_scaled.max()-data_scaled.min()).sort_values(ascending=False)
7 17.344336
5 16.876991
4 15.426350
2 13.718164
3 12.856056
0 12.325457
6 10.142674
1 10.120628
9 7.536311
8 7.285483
11 6.775464
10 5.038623
dtype: float64
4.對數據進行歸一化后:
繪制箱線圖后發現,除了酒精,其余的變量都存在異常值,且普遍存在較多較大的異常值。
(1)其中,氯化物的箱體最扁,說明50%的數據在均值附近波動,但是存在大量較大的異常值,偏離均值分布。
(2)而剩余糖分、總二氧化硫、密度、質量評分的異常值相對其他特征來說,比較少,且普遍遠大於平均值。
(3)非揮發性酸、檸檬酸、酸鹼性這三個特征都存在大量較大的異常值,但也同時存在部分較小的異常值。
(4)揮發性酸、氯化物、游離二氧化硫、硫酸鹽這四個特征的異常值普遍較大,只有氯化物存在少量較小的異常值。
(5)酒精特征不存在異常值,也與歸一前所做的直方圖對應得上。
(6)歸一化后數據的偏度、峰度均沒有改變,但是它將數據按照一定的規則縮小了,使得采用MSE來評價更有參考意義。
5.下面探究一下,各特征間、各特征與質量評分之間的關系:
data_df_scaled = pd.DataFrame(data_scaled)
data_df_scaled.columns = columns
data_df_scaled.sample(4) #隨機抽取5個歸一化后的樣本數據
非揮發性酸 | 揮發性酸 | 檸檬酸 | 剩余糖分 | 氯化物 | 游離二氧化硫 | 總二氧化硫 | 密度 | 酸鹼性 | 硫酸鹽 | 酒精 | 質量 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
819 | -0.301959 | 2.795664 | -0.943673 | 0.494640 | -0.538886 | -0.488556 | -0.126152 | 0.910393 | 0.077712 | 0.176605 | -1.149348 | -0.991374 |
905 | 1.831293 | -0.875545 | 0.709117 | -0.944765 | 0.056196 | -1.547043 | -0.879204 | -0.009154 | -0.849531 | 1.403446 | 0.476014 | -2.120618 |
4391 | 0.527639 | -0.577879 | 0.295920 | 1.796020 | 0.101972 | 2.040053 | 1.521150 | 1.659406 | 0.408870 | 2.455025 | -0.905544 | -0.991374 |
2314 | 0.172097 | -0.875545 | -0.034638 | -0.018025 | -0.630437 | 0.393517 | -0.267349 | -0.738104 | 0.806260 | -0.962605 | 1.369963 | 0.137870 |
corr_df = data_df_scaled.corr()
corr_df
非揮發性酸 | 揮發性酸 | 檸檬酸 | 剩余糖分 | 氯化物 | 游離二氧化硫 | 總二氧化硫 | 密度 | 酸鹼性 | 硫酸鹽 | 酒精 | 質量 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
非揮發性酸 | 1.000000 | -0.022697 | 0.289181 | 0.089021 | 0.023086 | -0.049396 | 0.091070 | 0.265331 | -0.425858 | -0.017143 | -0.120881 | -0.113663 |
揮發性酸 | -0.022697 | 1.000000 | -0.149472 | 0.064286 | 0.070512 | -0.097012 | 0.089261 | 0.027114 | -0.031915 | -0.035728 | 0.067718 | -0.194723 |
檸檬酸 | 0.289181 | -0.149472 | 1.000000 | 0.094212 | 0.114364 | 0.094077 | 0.121131 | 0.149503 | -0.163748 | 0.062331 | -0.075729 | -0.009209 |
剩余糖分 | 0.089021 | 0.064286 | 0.094212 | 1.000000 | 0.088685 | 0.299098 | 0.401439 | 0.838966 | -0.194133 | -0.026664 | -0.450631 | -0.097577 |
氯化物 | 0.023086 | 0.070512 | 0.114364 | 0.088685 | 1.000000 | 0.101392 | 0.198910 | 0.257211 | -0.090439 | 0.016763 | -0.360189 | -0.209934 |
游離二氧化硫 | -0.049396 | -0.097012 | 0.094077 | 0.299098 | 0.101392 | 1.000000 | 0.615501 | 0.294210 | -0.000618 | 0.059217 | -0.250104 | 0.008158 |
總二氧化硫 | 0.091070 | 0.089261 | 0.121131 | 0.401439 | 0.198910 | 0.615501 | 1.000000 | 0.529881 | 0.002321 | 0.134562 | -0.448892 | -0.174737 |
密度 | 0.265331 | 0.027114 | 0.149503 | 0.838966 | 0.257211 | 0.294210 | 0.529881 | 1.000000 | -0.093591 | 0.074493 | -0.780138 | -0.307123 |
酸鹼性 | -0.425858 | -0.031915 | -0.163748 | -0.194133 | -0.090439 | -0.000618 | 0.002321 | -0.093591 | 1.000000 | 0.155951 | 0.121432 | 0.099427 |
硫酸鹽 | -0.017143 | -0.035728 | 0.062331 | -0.026664 | 0.016763 | 0.059217 | 0.134562 | 0.074493 | 0.155951 | 1.000000 | -0.017433 | 0.053678 |
酒精 | -0.120881 | 0.067718 | -0.075729 | -0.450631 | -0.360189 | -0.250104 | -0.448892 | -0.780138 | 0.121432 | -0.017433 | 1.000000 | 0.435575 |
質量 | -0.113663 | -0.194723 | -0.009209 | -0.097577 | -0.209934 | 0.008158 | -0.174737 | -0.307123 | 0.099427 | 0.053678 | 0.435575 | 1.000000 |
corr_df["質量"].sort_values(ascending=False)
質量 1.000000
酒精 0.435575
酸鹼性 0.099427
硫酸鹽 0.053678
游離二氧化硫 0.008158
檸檬酸 -0.009209
剩余糖分 -0.097577
非揮發性酸 -0.113663
總二氧化硫 -0.174737
揮發性酸 -0.194723
氯化物 -0.209934
密度 -0.307123
Name: 質量, dtype: float64
plt.figure(figsize=(16,16))
sns.heatmap(corr_df,linewidths=0.1,square=True,linecolor="white",annot=True,cmap='YlGnBu',vmin=-1,vmax=1)
plt.title("各特征間的熱力圖")
<matplotlib.text.Text at 0xf095627f98>
6.可以看到:
(1)白葡萄酒的質量評分與酒精、酸鹼性、硫酸鹽、游離二氧化硫有正的線性相關關系,它們的含量越高,口感評分越高;而與其他特征都呈現負的線性相關關系,這些特征的含量越高,口感評分越低。關系強度最大為0.44,大部分關系強度的絕對值均小於0.2(線性關系強度在[0,1]之間)。
(2)白葡萄酒的質量評分跟酒精、密度、氯化物的線性關系較強。質量評分與酒精之間有正相關關系,關系強度為0.44,酒精含量越高,口感評分越高;而與密度、氯化物為負線性相關關系,分別為-0.31、-0.21,它們的含量越高,白葡萄酒的口感評分越低。
(3)從熱力圖看,顏色普遍較淺,說明各變量間的線性相關關系較弱。
(4)而密度跟剩余糖分、酒精線性相關關系比較強。密度與剩余糖分的線性關系為0.84,剩余糖分越多,白葡萄酒的密度越大;密度與酒精的線性關系為-0.78,酒精密度越大,白葡萄酒的密度越小。
二.建模分析
1.一般線性模型
from sklearn.model_selection import train_test_split
xx_train, xx_test, yy_train, yy_test = train_test_split(data_df_scaled.iloc[:,:11], data_df_scaled.iloc[:,-1], test_size=0.3,random_state=100)
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
LR = LinearRegression()
LR.fit(xx_train, yy_train)
print("1.線性回歸方程的截距:", LR.intercept_)
print("2.線性回歸方程的回歸系數:\n", LR.coef_)
yy0_pred = LR.predict(xx_test)
print("3.均方誤差: ", mean_squared_error(yy_test, yy0_pred))
1.線性回歸方程的截距: -0.00695101212555
2.線性回歸方程的回歸系數:
[ 7.63074915e-02 -1.93903082e-01 7.78570075e-03 4.68097575e-01
-4.05515219e-04 9.52752806e-02 -2.27524242e-02 -5.00567332e-01
1.27837888e-01 9.45724618e-02 2.90086677e-01]
3.均方誤差: 0.724247388354
Coef0_df = pd.DataFrame(LR.intercept_,index=columns[0:11],columns=["回歸系數"])
Coef0_df.sort_values(by="回歸系數",ascending=False)
回歸系數 | |
---|---|
非揮發性酸 | -0.006951 |
揮發性酸 | -0.006951 |
檸檬酸 | -0.006951 |
剩余糖分 | -0.006951 |
氯化物 | -0.006951 |
游離二氧化硫 | -0.006951 |
總二氧化硫 | -0.006951 |
密度 | -0.006951 |
酸鹼性 | -0.006951 |
硫酸鹽 | -0.006951 |
酒精 | -0.006951 |
從擬合出來的結果來看,每個自變量的回歸系數都很小,而且均為負值,與現實意義不符,該模型可能存在過擬合。下面用Lasso回歸和Ridge回歸來改善過擬合現象。
2.套索模型(LassoCV)
2.1 部分數據做交叉驗證
from sklearn.linear_model import LassoCV
L1_CV = LassoCV(cv=10).fit(xx_train, yy_train)
yy1_pred = L1_CV.predict(xx_test)
print("均方誤差:",mean_squared_error(yy_test, yy1_pred))
均方誤差: 0.723045110072
Coef1_df = pd.DataFrame(L1_CV.intercept_,index=columns[0:11],columns=["回歸系數"])
Coef1_df.sort_values(by="回歸系數",ascending=False)
回歸系數 | |
---|---|
非揮發性酸 | -0.007413 |
揮發性酸 | -0.007413 |
檸檬酸 | -0.007413 |
剩余糖分 | -0.007413 |
氯化物 | -0.007413 |
游離二氧化硫 | -0.007413 |
總二氧化硫 | -0.007413 |
密度 | -0.007413 |
酸鹼性 | -0.007413 |
硫酸鹽 | -0.007413 |
酒精 | -0.007413 |
回歸系數依然全部為負值且很小,說明做交叉驗證的效果不好。下面我們拿所有的數據來做交叉驗證,並用里面的屬性來評估效果。
2.2 所有數據做交叉驗證
x = data_df_scaled.iloc[:,:11]
y = data_df_scaled.iloc[:,-1]
print("特征集:",x.shape)
print("標簽集:",y.shape)
from sklearn.linear_model import LassoCV
Las_cv = LassoCV(cv=10).fit(x,y)
特征集: (4898, 11)
標簽集: (4898,)
print("線性模型的截距:",Las_cv.intercept_)
print("線性模型的回歸系數:\n",Las_cv.coef_)
線性模型的截距: 1.06646156739e-14
線性模型的回歸系數:
[ 0.0098704 -0.21381849 0. 0.33369253 -0.01166061 0.06691956
-0.009035 -0.31407498 0.07341963 0.06597724 0.352643 ]
Coef2_df = pd.DataFrame(Las_cv.coef_,index=columns[0:11],columns=["回歸系數"])
Coef2_df.sort_values(by="回歸系數",ascending=False)
回歸系數 | |
---|---|
酒精 | 0.352643 |
剩余糖分 | 0.333693 |
酸鹼性 | 0.073420 |
游離二氧化硫 | 0.066920 |
硫酸鹽 | 0.065977 |
非揮發性酸 | 0.009870 |
檸檬酸 | 0.000000 |
總二氧化硫 | -0.009035 |
氯化物 | -0.011661 |
揮發性酸 | -0.213818 |
密度 | -0.314075 |
A.可以看到,基於歸一化后的數據:
(1)我們構造的模型為:
y_scaled = 1.06646156739e-14 + 0.0098704 * x1_scaled - 0.21381849 * x2_scaled + 0.33369253 * x4_scaled -
0.01166061 * x5_scaled + 0.06691956 * x6_scaled - 0.009035 * x7_scaled - 0.31407498 * x8_scaled +
0.07341963 * x9_scaled + 0.06597724 * x10_scaled + 0.352643 * x11_scaled
(2)檸檬酸的回歸系數為0,在LasscoCV模型里,沒有對白葡萄酒的口感評價產生影響。酒精、剩余糖分、酸鹼性、游離二氧化硫、硫酸鹽、非揮發性酸這6個特征對提升口感評價有正向作用,其影響力依次遞減;在一定程度上,這些成分含量越多,口感越好。另一方面,密度、揮發性酸、氯化物、總二硫化物對提升口感有負作用,其影響力依次遞減;一定程度上,它們在白葡萄酒里的含量越高,口感越差。
(3)對提升白葡萄酒口感評價影響最大的三個特征為:酒精含量、剩余糖分、酸鹼性。酒精含量、剩余糖分含量的回歸系數分別為0.35、0.33,排名第三的酸鹼性的回歸系數為0.07,與前面個兩個特征相比,該值較小。在實際生產中,為提升白葡萄酒口感,生產商應更多地關注、研究白葡萄酒中的酒精含量和剩余糖分含量。
(4)降低白葡萄酒口感的前三特征為:密度、揮發性酸、氯化物。其中密度的影響最大,為-0.31;揮發性酸的影響第二,為-0.21;氯化物的影響第三,為-0.01。可看到,密度和揮發性酸對降低口感評分的影響較大,氯化物相對較小。在實際生產工藝中,需要更多關注、合理控制白葡萄酒的密度大小與揮發性酸的含量。
(5)在熱力圖及相關關系計算中,我們得出密度跟剩余糖分(0.84)、酒精(-0.78)的線性相關關系比較強。所以在實際生產中,為了提升口感而不斷地提升剩余糖分和酒精含量是不可行的。在提升糖分的同時,要注意密度也有所提升,這時候可適當加入酒精,提高酒精含量來降低密度對口感的影響。應多投入到調配這三個特征的比例,才能更有效地提升白葡萄酒口感,提升銷量。
B.下面來看在十折試驗中,MSE的一個變化情況:
plt.figure(figsize=(11,9))
plt.plot(Las_cv.alphas_,Las_cv.mse_path_,"-")
plt.plot(Las_cv.alphas_,Las_cv.mse_path_.mean(axis=-1),label="均方誤差均值:MSE_mean",linewidth=3,color="b")
plt.axvline(Las_cv.alpha_,linestyle="--",label="10折預測最佳表現對應的alpha值")
plt.xlabel("alpha值",size=16)
plt.xticks(size=16)
plt.ylabel("均方誤差(MSE)")
plt.legend(loc="best")
plt.semilogx()
ax = plt.gca()
ax.invert_xaxis()
均方誤差隨着alpha的減小,漸漸地趨於一定的值,處於基本穩定狀態。
print("10折交叉驗證中,最佳的懲罰系數:", Las_cv.alpha_)
print("10折交叉驗證中,最小的MSE(均值):", min(Las_cv.mse_path_.mean(axis=0))) #均值來的,注意
10折交叉驗證中,最佳的懲罰系數: 0.00467052490126
10折交叉驗證中,最小的MSE(均值): 0.547575587951
- 在眾多的擬合的懲罰系數里,表現最優的懲罰系數為0.0046705249012570426。在這個位置,均方誤差MSE基本穩定下來。
- 十折交叉驗證里,最小的MSE為0.548.十折的平均值見最粗的藍色線,在0.73—0.74之間,比對上面的兩種方法,效果較好。方程具備現實意義。
C.總的來說:
(1)各特征間存在一定的線性關系,但普遍關系強度不太大;最大的是密度與剩余糖分(0.84)、酒精濃度(-0.78)的線性關系。
(2)找出對白葡萄酒口感影響最大的前三因素:酒精、剩余糖分、密度;
(3)針對給出的11個特征,我們用LassoCV來建模,並給出了最終的模型:
y_scaled = 1.06646156739e-14 + 0.0098704 * x1_scaled - 0.21381849 * x2_scaled + 0.33369253 * x4_scaled -
0.01166061 * x5_scaled + 0.06691956 * x6_scaled - 0.009035 * x7_scaled - 0.31407498 * x8_scaled +
0.07341963 * x9_scaled + 0.06597724 * x10_scaled + 0.352643 * x11_scaled
(4)在實際生產中,廠家應多嘗試酒精、剩余糖分、密度的不同比例調配方式。酒精、剩余糖分的含量能提高葡萄酒的口感,而密度大小則會降低酒的口感。另外,要注意到密度跟剩余糖分(0.84)、酒精(-0.78)的相關關系。所以在實際生產中,根據二八定理,針對這三個特征多投入,會得到較大的收益。
3.嶺回歸:
3.1 部分數據做交叉驗證
from sklearn.linear_model import RidgeCV
R1_CV = RidgeCV(cv=10).fit(xx_train, yy_train)
yyR1_pred = R1_CV.predict(xx_test)
print("均方誤差:",mean_squared_error(yy_test, yyR1_pred))
Coef3_df = pd.DataFrame(R1_CV.coef_,index=columns[0:11],columns=["回歸系數"])
Coef3_df.sort_values(by="回歸系數",ascending=False)
均方誤差: 0.724085117608
回歸系數 | |
---|---|
剩余糖分 | 0.436080 |
酒精 | 0.309095 |
酸鹼性 | 0.118767 |
游離二氧化硫 | 0.096880 |
硫酸鹽 | 0.091681 |
非揮發性酸 | 0.065386 |
檸檬酸 | 0.007297 |
氯化物 | -0.003010 |
總二氧化硫 | -0.024704 |
揮發性酸 | -0.194503 |
密度 | -0.454458 |
看到主要影響因素為密度、剩余糖分、酒精、揮發性酸。密度的影響強度最大。下面用全部數據做交叉驗證,比對效果。
3.2 全部數據做交叉驗證
from sklearn.linear_model import RidgeCV
R2_cv = RidgeCV(alphas=np.arange(0, 100), scoring='neg_mean_squared_error', cv=10).fit(x,y)
print("線性模型的截距:", R2_cv.intercept_)
print("線性模型的回歸系數:\n", R2_cv.coef_)
print("最佳懲罰系數:", R2_cv.alpha_)
線性模型的截距: 1.26696321324e-14
線性模型的回歸系數:
[ 0.03197363 -0.21165971 0.00223188 0.3755903 -0.01303913 0.0767687
-0.02080385 -0.3747941 0.09182727 0.07351966 0.3229347 ]
最佳懲罰系數: 48
Coef4_df = pd.DataFrame(R2_cv.coef_, index=columns[0:11], columns=["回歸系數"])
Coef4_df.sort_values(by="回歸系數", ascending=False)
回歸系數 | |
---|---|
剩余糖分 | 0.375590 |
酒精 | 0.322935 |
酸鹼性 | 0.091827 |
游離二氧化硫 | 0.076769 |
硫酸鹽 | 0.073520 |
非揮發性酸 | 0.031974 |
檸檬酸 | 0.002232 |
氯化物 | -0.013039 |
總二氧化硫 | -0.020804 |
揮發性酸 | -0.211660 |
密度 | -0.374794 |
A.可以看到,基於歸一化后的數據:
(1)我們構造的模型為:
y_scaled = 1.26696321324e-14 + 0.03197363 x1_scaled - 0.21165971 x2_scaled + 0.00223188x3_scaled + 0.3755903 x4_scaled -
0.01303913 x5_scaled + 0.0767687 x6_scaled - 0.02080385 x7_scaled - 0.3747941 x8_scaled +
0.09182727 x9_scaled + 0.07351966 x10_scaled + 0.3229347 x11_scaled
(2)剩余糖分、酒精、酸鹼性、游離二氧化硫、硫酸鹽、非揮發性酸、檸檬酸這7個特征對提升口感評價有正向作用,其影響力依次遞減;在一定程度上,這些成分含量越多,口感越好。另一方面,密度、揮發性酸、總二硫化物、氯化物對提升口感有負作用,其影響力依次遞減;一定程度上,它們在白葡萄酒里的含量越高,口感越差。
(3)對提升白葡萄酒口感評價影響最大的三個特征為:剩余糖分、酒精含量、酸鹼性。剩余糖分、酒精含量含量的回歸系數分別為0.38、0.32,排名第三的酸鹼性的回歸系數為0.09,與前面個兩個特征相比,該值較小。在實際生產中,為提升白葡萄酒口感,生產商應更多地關注、研究白葡萄酒中的剩余糖分含量和酒精含量,跟上面LassoCV的結論一致。
(4)降低白葡萄酒口感的前三特征為:密度、揮發性酸、總二氧化硫。其中密度的影響最大,為-0.37;揮發性酸的影響第二,為-0.21;總二氧化硫的影響第三,為-0.02。可看到,密度和揮發性酸對降低口感評分的影響較大,總二氧化硫相對較小。在實際生產工藝中,需要更多關注、合理控制白葡萄酒的密度大小與揮發性酸的含量,與LasscoCV一致。
(5)最佳懲罰系數為48。
三.總結與建議
我們用了一般線性回歸、Lasso回歸和嶺回歸,來為白葡萄酒的口感評分建模。模型參見上面結論。
發現:
-
(1)跟質量評分線性相關程度較強的是:酒精、密度和氯化物,最弱的是檸檬酸。
-
(2)按正負影響划分因素:
提升質量的因素:酒精、剩余糖分、酸鹼性、游離二氧化硫、硫酸鹽、非揮發性酸、檸檬酸。
降低質量因素:密度、揮發性酸、氯化物、總二氧化硫。 -
(3)按影響強度划分因素:
關鍵影響因素:酒精、剩余糖分、密度、揮發性酸。
次級影響因素:酸鹼性、游離二氧化硫、硫酸鹽、非揮發性酸、氯化物、總二氧化硫。
最弱影響因素:檸檬酸 -
(4)為生產質量好的白葡萄酒,生產商應把主要的經歷、資金投入到酒精、剩余糖分、密度、揮發性酸這四個主要因素的比例中,提高投入產出比。注意剩余糖分越多,密度同時也增高;而酒精與密度呈負相關關系,可適度多加酒精
-
(5)在考慮推出新品時,可考慮推出少量極高端、質量一般般的產品,主要推出質量中等、甚至偏上的產品。中等價位的產品更受到消費者青睞。
如果在中等的基礎上,對品質提高一個段位,與其他銷售產品划開一個層次,可利用價格溢價來提高營收。 -
(6)做用戶分層:
在產品的消費群體中,可針對他們的購買行為(消費時間、消費次數量、消費總金額、消費頻次、最近一次消費時間、單次購買金額、單次購買品類等等)作用戶分層,分成高中低消費群體,然后針對他們購買的產品、消費的金額、消費的次數來找出這類人群最喜歡什么類型的產品。在后續生產中,可針對不同群體,推出對應的產品。