<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Class 10
ML Techniques
Step1:  There are a number of different features here. We'll focus on the first two
Step2:  Standarization scaling
As we noted above, the goal is to turn these features into unitless parameters. That means we have to divide the feature by a quantity with the same units. There are two typical ways of doing this
Step3:  We've accomplished what we set out to do
Step4:  It looks like we've re-scaled the data without changing the basic shape or the relationships between the points. That's good. The standardized data can now be used as inputs for the machine learning algorithms.
Min-Max Scaling
One of the things we didn't mention before was that the standardization scaling only really works if we have enough data to get a good standard deviation and if the data are normally distributed (i.e. they look like a bell-shaped curve). IF these things don't apply, then standardization may not be the best thing to do.
There is another way we could scale the data
Step5:  As you can see, we've really shifted things around. The means are not very pretty (because the dataset has been shrunk to fit between 0 and 1). Additionally the standard deviation has changed and isn't very pretty, either. Let's plot it to see if the shape has changed.
<ASSISTANT_TASK:>
Python Code:
import pandas as pd
df = pd.read_csv('Class10_wine_data.csv')
df.head()
Explanation: Class 10
ML Techniques: Feature scaling
Another aspect of optimizing machine learning algorithms is to think about feature scaling. When we use multiple numeric features as inputs to a regression or classification algorithm, the computer just sees those values as numbers without context or units. What if we have the data that has one column corresponding to a driver's age and another column that corresponds to the vehicle gross weight. Those are very different sets of numbers. Without doing any other scaling or pre-processing, the machine learning algorithm may emphasize the vehicle weights more than the ages because they are larger numbers. We don't want that to happen.
The process of changing the data scale is called feature scaling and we'll look at two different types of feature scaling. If you want a good in-depth tutorial on how this works, I recommend this tutorial.
Working with Different Data Types
We'll use a sample dataset from the UCI archives. This dataset is looking at various characteristics of different wine samples and has classified the samples into one of three different classes (1,2, and 3). Let's import the data and take a look at it.
End of explanation
# Plot the first two feature columns
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('white')
#plt.figure(figsize=(8,6))
plt.scatter(df['Alcohol'], df['Malic acid'])
plt.xlabel('Alcohol (%/L)')
plt.ylabel('Malic Acid (g/L)')
plt.xlim(0,16)
plt.ylim(0,16)
plt.axes().set_aspect('equal')
Explanation: There are a number of different features here. We'll focus on the first two: Alcohol which has units (percent/volumne) and Malic acid with units (g/l). Any machine learning algorithm that uses these features is going to treat them as if they were on the same scale. However, they aren't. So we need to re-scale them to unitless values in order to work with them.
Let's first look at the distribution of points in those columns.
End of explanation
from sklearn.preprocessing import StandardScaler
std_scaler = StandardScaler().fit(df[['Alcohol', 'Malic acid']])
df_std = std_scaler.transform(df[['Alcohol', 'Malic acid']])
print('Mean before standardization:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df['Alcohol'].mean(), df['Malic acid'].mean()))
print('\nMean after standardization:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_std[:,0].mean(), df_std[:,1].mean()))
print('\nStandard deviation before standardization:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df['Alcohol'].std(), df['Malic acid'].std()))
print('\nStandard deviation after standardization:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_std[:,0].std(), df_std[:,1].std()))
Explanation: Standarization scaling
As we noted above, the goal is to turn these features into unitless parameters. That means we have to divide the feature by a quantity with the same units. There are two typical ways of doing this: we'll start with standardization or Z-scale normalization. We need to calculate the standard deviation of the feature, then divide the entire column by the standard deviation. Because the standard deviation has the same units as the feature itself, this takes care of the normalization.
We'll also do one more thing: we'll subtract the mean value of the distribution from each data point first. That way we end up with a distribution that is centered at zero. Of course there is a library that will do this for us. We need to fit the library on the data we want to scale, then use the transform() function to transform the input data based on the scaler. We can do both features at the same time: the scaler keeps track of them individually.
End of explanation
fig, ax = plt.subplots(1,2)
for a,d,l in zip(range(len(ax)),
               (df[['Alcohol', 'Malic acid']].values, df_std),
               ('Input scale',
                'Standardized [$N  (\mu=0, \; \sigma=1)$]')
                ):
    for i,c in zip(range(1,4), ('red', 'blue', 'green')):
        ax[a].scatter(d[df['Wine Class'].values == i, 0],
                  d[df['Wine Class'].values == i, 1],
                  alpha=0.5,
                  color=c,
                  label='Class %s' %i
                  )
        ax[a].set_aspect('equal')
    ax[a].set_title(l)
    ax[a].set_xlabel('Alcohol')
    ax[a].set_ylabel('Malic Acid')
    ax[a].legend(loc='upper left')
    ax[a].grid()
plt.tight_layout()
Explanation: We've accomplished what we set out to do: the new means are close to zero and the standard deviations are 1. Let's see how it changed the shape of the distributions.
End of explanation
from sklearn.preprocessing import MinMaxScaler
minmax_scaler = MinMaxScaler().fit(df[['Alcohol', 'Malic acid']])
df_minmax = minmax_scaler.transform(df[['Alcohol', 'Malic acid']])
print('Mean before min-max scaling:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df['Alcohol'].mean(), df['Malic acid'].mean()))
print('\nMean after min-max scaling:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_minmax[:,0].mean(), df_minmax[:,1].mean()))
print('\nStandard deviation before min-max scaling:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df['Alcohol'].std(), df['Malic acid'].std()))
print('\nStandard deviation after min-max scaling:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_minmax[:,0].std(), df_minmax[:,1].std()))
from sklearn.model_selection import train_test_split
train, test = train_test_split(df, test_size=0.2, random_state=23)
minmax_scaler = MinMaxScaler().fit(train[['Alcohol', 'Malic acid']])
train_features = minmax_scaler.transform(train[['Alcohol', 'Malic acid']])
train_features[0:2]
test[['Alcohol' ,'Malic acid']].head(2)
test_features = minmax_scaler.transform(test[['Alcohol', 'Malic acid']])
test_features[0:2]
Explanation: It looks like we've re-scaled the data without changing the basic shape or the relationships between the points. That's good. The standardized data can now be used as inputs for the machine learning algorithms.
Min-Max Scaling
One of the things we didn't mention before was that the standardization scaling only really works if we have enough data to get a good standard deviation and if the data are normally distributed (i.e. they look like a bell-shaped curve). IF these things don't apply, then standardization may not be the best thing to do.
There is another way we could scale the data: we could figure out the "distance" between the maximum and the minimum and then scale the data based on this "distance". Of course we should also subtract off the minimum point. The net result is that now the entire dataset lies between 0 and 1. Let's do this and see how it looks.
End of explanation
fig, ax = plt.subplots(1,2)
for a,d,l in zip(range(len(ax)),
               (df[['Alcohol', 'Malic acid']].values, df_minmax),
               ('Input scale',
                'Min-max scale')
                ):
    for i,c in zip(range(1,4), ('red', 'blue', 'green')):
        ax[a].scatter(d[df['Wine Class'].values == i, 0],
                  d[df['Wine Class'].values == i, 1],
                  alpha=0.5,
                  color=c,
                  label='Class %s' %i
                  )
        ax[a].set_aspect('equal')
    ax[a].set_title(l)
    ax[a].set_xlabel('Alcohol')
    ax[a].set_ylabel('Malic Acid')
    ax[a].legend(loc='upper left')
    ax[a].grid()
plt.tight_layout()
Explanation: As you can see, we've really shifted things around. The means are not very pretty (because the dataset has been shrunk to fit between 0 and 1). Additionally the standard deviation has changed and isn't very pretty, either. Let's plot it to see if the shape has changed.
End of explanation
<END_TASK>