-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInvestigate_Wine_Dataset.py
More file actions
514 lines (260 loc) · 9.4 KB
/
Copy pathInvestigate_Wine_Dataset.py
File metadata and controls
514 lines (260 loc) · 9.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
#!/usr/bin/env python
# coding: utf-8
#
#
# # Project: Wine Quality Investigation
#
#
# ## Table of Contents
# <ul>
# <li><a href="#intro">Introduction</a></li>
# <li><a href="#wrangling">Data Wrangling</a></li>
# <li><a href="#eda">Exploratory Data Analysis</a></li>
# <li><a href="#conclusions">Conclusions</a></li>
# </ul>
# <a id='intro'></a>
# ## Introduction
#
# > This is a wine dataset containing 1599 rows and 12 columns displaying the wine's fixed acidity, residual sugar, citric acid and free sulphur dioxide which would be used to determine the quality of wine.
# ### Question(s) for Analysis
# <li>What chemical attribute are relevant in predicting the quality of wine.</li>
# <li>Do wines with higher alcoholic content receive better ratings?.</li>
# <li>What amount or level of acidity is associated with the highest quality.</li>
# <li>Do sweeter wines receive better ratings</li>
# <li>Is a certain type of wine associated with higher quality?</li>
# <a id='wrangling'></a>
# ## Data Wrangling
# ### Gathering Data
# In[117]:
#import statements
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
import seaborn as sns
sns.set_style('darkgrid')
# load red and white wine datasets
red_df = pd.read_csv('winequality-red.csv', sep = ';')
white_df =pd.read_csv('winequality-white.csv', sep = ';')
# In[118]:
red_df
# In[119]:
white_df
# In[120]:
red_df.info()
# In[121]:
white_df.info()
# In[122]:
sum(white_df.duplicated())
# In[123]:
white_df.duplicated()
# In[124]:
white_df.nunique()
# In[125]:
red_df['density'].mean()
# In[126]:
# create color array for red dataframe
color_red = np.repeat('red', red_df.shape[0])
# create color array for white dataframe
color_white = np.repeat('white', white_df.shape[0])
# In[127]:
red_df['color'] = color_red
red_df.head()
# In[128]:
white_df['color']= color_white
white_df.head()
# In[129]:
# append dataframes
wine_df = red_df.append(white_df, sort = False)
# view dataframe to check for success
wine_df.head()
# In[130]:
wine_df.to_csv('winequality_edited.csv', index=False)
# In[131]:
wine_df.info()
#
# ##### Data Cleaning
# In[132]:
red_df.rename(columns={'total_sulfur-dioxide':'total_sulfur_dioxide'}, inplace=True)
# <a id='eda'></a>
# ## Exploratory Data Analysis
# In[133]:
df_wine = pd.read_csv('winequality_edited.csv')
df_wine
# ## Scatterplot
# In[134]:
df_wine.plot(x ='quality', y = 'pH', kind = 'scatter' );
# In[135]:
df_wine.plot(x ='quality', y = 'residual_sugar', kind = 'scatter' );
# In[136]:
df_wine.plot(x ='quality', y = 'alcohol', kind = 'scatter' );
# In[137]:
df_wine.plot(x ='quality', y = 'volatile_acidity', kind = 'scatter' );
# ## Histogram
# In[138]:
df_wine.hist(figsize = (15, 15))
# In[139]:
df_wine['alcohol'].plot(kind = 'hist', figsize = (8, 8))
# In[140]:
df_wine['fixed_acidity'].plot(kind = 'hist', figsize = (8, 8), color = 'purple')
# In[141]:
df_wine['pH'].plot(kind = 'hist', figsize = (8, 8))
# In[142]:
df_wine['total_sulfur_dioxide'].plot(kind = 'hist', figsize = (8, 8))
# ### Drawing Conclusions Using Groupby
# ##### Is a certain type of wine associated with higher quality?
# In[143]:
# Find the mean quality of each wine type (red and white) with groupby
df_wine.groupby('color').mean().quality
# ##### What amount or level of acidity is associated with the highest quality?
# In[144]:
# View the min, 25%, 50%, 75%, max pH values with Pandas describe
df_wine['pH'].describe()
# In[145]:
# Bin edges that will be used to "cut" the data into groups
bin_edges = [2.72, 3.11, 3.21, 3.32, 4.01] # Fill in this list with five values you just found
# In[146]:
# Labels for the four acidity level groups
bin_names = bin_names = ['high', 'mod_high', 'medium', 'low'] # Name each acidity level category
# In[147]:
# Creates acidity_levels column
df_wine['acidity_levels'] = pd.cut(df_wine['pH'], bin_edges, labels=bin_names)
# Checks for successful creation of this column
df_wine.head()
# In[148]:
# Find the mean quality of each acidity level with groupby
acidity_level_quality_means = df_wine.groupby('acidity_levels').mean().quality
# In[149]:
locations = [2, 3, 4, 1] # reorder values above to go from low to high
heights = acidity_level_quality_means
labels = ['Low', 'Medium', 'Moderately High', 'High']
#labels = acidity_level_quality_means.index.str.replace('_', ' ').str.title() # alternative to commented out line above
plt.bar(locations, heights, tick_label=labels)
plt.title('Average Quality Ratings by Acidity Level')
plt.xlabel('Acidity Level')
plt.ylabel('Average Quality Rating');
# In[150]:
# Save changes for the next section
df_wine.to_csv('winequality_edited.csv', index=False)
# ### Drawing Conclusions Using Groupby
# #### Que 3: Do wines with a higher alcoholic content receive better ratings?
# In[151]:
# get the median amount of alcohol content
df_wine['alcohol'].median()
# In[152]:
# select samples with alcohol content less than the median
low_alcohol = df_wine.query('alcohol < 10.300000000000001')
# select samples with alcohol content greater than or equal to the median
high_alcohol = df_wine.query('alcohol >= 10.300000000000001')
# ensure these queries included each sample exactly once
num_samples = df_wine.shape[0]
num_samples == low_alcohol['quality'].count() + high_alcohol['quality'].count() # should be True
# In[153]:
# get mean quality rating for the low alcohol and high alcohol groups
mean_quality_low = low_alcohol['quality'].mean()
mean_quality_low
# In[154]:
mean_quality_high = high_alcohol['quality'].mean()
mean_quality_high
# In[155]:
# Create a bar chart with proper labels
locations = [1, 2]
heights = [mean_quality_low, mean_quality_high]
labels = ['Low', 'High']
plt.bar(locations, heights, tick_label=labels)
plt.title('Average Quality Ratings by Alcohol Content')
plt.xlabel('Alcohol Content')
plt.ylabel('Average Quality Rating');
# #### Que 4: Do sweeter wines receive better ratings?
# In[156]:
# get the median amount of residual sugar
df_wine['residual_sugar'].median()
# In[157]:
# select samples with residual sugar less than the median
low_sugar = df_wine.query('residual_sugar < 3.0')
# select samples with residual sugar greater than or equal to the median
high_sugar =df_wine.query('residual_sugar >= 3.0')
# ensure these queries included each sample exactly once
num_samples == low_sugar['quality'].count() + high_sugar['quality'].count() # should be True
# In[158]:
# get mean quality rating for the low sugar and high sugar groups
low_sugar['residual_sugar'].mean()
# In[159]:
high_sugar['residual_sugar'].mean()
# In[160]:
mean= df_wine['residual_sugar'].mean()
low_sugar = df_wine.query('residual_sugar < {}'.format(mean))
high_sugar = df_wine.query('residual_sugar > {}'.format(mean))
mean_quality_low = low_sugar['quality'].mean()
mean_quality_low
# In[161]:
mean_quality_high = high_sugar['quality'].mean()
mean_quality_high
# In[162]:
# Create a bar chart
location = [1, 2]
height = [mean_quality_low, mean_quality_high]
label = ['low', 'high']
plt.bar(location, height, tick_label = label);
plt.title('Average Quality Ratings by Residual Sugar')
plt.xlabel('Residual quality')
plt.ylabel('Average Quality Rating')
# ### Plotting Wine Type and Quality with Matplotlib
# #### Arrays for red bar heights white bar heights
# 1. Red bar proportions = counts for each quality rating / total # of red samples
# 2. White bar proportions = counts for each quality rating / total # of white samples
# In[163]:
# get counts for each rating and color
color_counts = wine_df.groupby(['color', 'quality']).count()['pH']
color_counts
# In[164]:
# get total counts for each color
color_totals = wine_df.groupby('color').count()['pH']
color_totals
# In[165]:
# get proportions by dividing red rating counts by total # of red samples
red_proportions = color_counts['red'] / color_totals['red']
red_proportions
# In[166]:
# get proportions by dividing white rating counts by total # of white samples
white_proportions = color_counts['white'] / color_totals['white']
white_proportions
# In[167]:
red_proportions['9'] = 0
red_proportions
# ### Plot proportions on a bar chart
# x axis = ratings
# y axis = width of each bar
# In[168]:
ind = np.arange(len(red_proportions)) #for x
width = 0.35 #for y
# In[169]:
# plot bars
red_bars = plt.bar(ind, red_proportions, width, color='r', alpha=.7, label='Red Wine')
white_bars = plt.bar(ind + width, white_proportions, width, color='w', alpha=.7, label='White Wine')
# title and labels
plt.ylabel('Proportion')
plt.xlabel('Quality')
plt.title('Proportion by Wine Color and Quality')
locations = ind + width / 2 # xtick locations
labels = ['3', '4', '5', '6', '7', '8', '9'] # xtick labels
plt.xticks(locations, labels)
# legend
plt.legend()
#
# <a id='conclusions'></a>
# ## Conclusions
#
# In this analysis, i discovered the following:
# <li>A low level of acidity receives the highest mean quality rating.</li>
# <li>Wines with higher alcohol content receives better ratings</li>
# <li>The mean quality of red wine is less than that of white wine.</li>
# <li>Sweeter wines receive better ratings.</li>
# <li>The chemical attribute relevant in predicting a wines quality are mainly residual sugar, color, alcohol .</li>
#
#
#
# In[171]:
from subprocess import call
call(['python', '-m', 'nbconvert', 'Investigate_Wine_Dataset.ipynb'])
# In[ ]: