TensorFlowTensorFlow教程汇总--Keras 机器学习基础④电影评论文本分类

117 阅读4分钟

官方网站

  • 回归:预测出如价格\概率这样连续值的输出。

  • 分类:从一系列的分类中选车出一个分类.

终端命令conda install seaborn用于做图

import pathlib
import matplotlib.pyplot as plt
import pandas as pd 
import seaborn as sns
import tensorflow as tf 
from tensorflow import keras
from tensorflow.keras import layers
tf.__version__

1. auto MPG 数据集

1.1 获取数据

dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")
dataset_path

column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
                'Acceleration', 'Model Year', 'Origin']
raw_dataset = pd.read_csv(dataset_path,names = column_names,na_values = "?",comment='\t',sep = " ",skipinitialspace=True)
dataset = raw_dataset.copy()
dataset.tail()

结果如下图:

image.png

1.2 清洗数据

dataset.isna().sum()

dataset = dataset.dropna()

# origin 列实际是分类,不仅仅是一个数字,所以将其转换为 one-hot 码
origin = dataset.pop('Origin')

dataset['USA'] = (origin == 1 )*1.0
dataset['Europe'] = (origin == 2)*1.0
dataset['Janpan'] = (origin == 3)*1.0
dataset.tail()

1.3拆分训练数据集和测试数据集

train_dataset = dataset.sample(frac = 0.8,random_state= 0)
test_dataset = dataset.drop(train_dataset.index)

1.4 数据检查

sns.pairplot(train_dataset[['MPG','Cylinders','Displacement','Weight']],diag_kind='kde')

image.png

train_stats = train_dataset.describe()
train_stats.pop('MPG')
train_stats = train_stats.transpose() #转置
train_stats

image.png

1.5 从标签中分体特征

将特征值从目标值或者’标签‘中分类,这个表示是使用训练模型时进行预测的值。

train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')

源数据的“MPG”删除,返回一个新的结果就是标签

1.6 数据规范化

归一化 再次审视下上面的 train_stats 部分,并注意每个特征的范围有什么不同。

使用不同的尺度和范围对特征归一化是好的实践。尽管模型可能 在没有特征归一化的情况下收敛,它会使得模型训练更加复杂,并会造成生成的模型依赖输入所使用的单位选择。

注意:尽管我们仅仅从训练集中有意生成这些统计数据,但是这些统计信息也会用于归一化的测试数据集。我们需要这样做,将测试数据集放入到与已经训练过的模型相同的分布中。

def norm(x):
 return (x - train_stats['mean']) / train_stats['std']
normed_train_data = norm(train_dataset)
normed_test_data = norm(test_dataset)

警告: 用于归一化输入的数据统计(均值和标准差)需要反馈给模型从而应用于任何其他数据,以及我们之前所获得独热码。这些数据包含测试数据集以及生产环境中所使用的实时数据。

2. 模型

2.1 构建模型

def build_model():
  model = keras.Sequential([
    layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
    layers.Dense(64, activation='relu'),
    layers.Dense(1)
  ])

  optimizer = tf.keras.optimizers.RMSprop(0.001)

  model.compile(loss='mse',
                optimizer=optimizer,
                metrics=['mae', 'mse'])
  return model

2.2 检查模型

  • 使用.summary方法
model.summary()

image.png

  • 方法 2
example_batch = normed_train_data[:10]
example_result = model.predict(example_batch)
example_result

2.3 训练模型

class PrintDot(keras.callbacks.Callback):
    def on_epoch_end(self,epoch,logs):
        if epoch %100 == 0: print('')
        print('.',end = '')
        
EPOCH = 1000
history = model.fit(
normed_train_data,train_labels,
epochs=EPOCH,validation_split = 0.2,verbose=0,
callbacks=[PrintDot()])

使用history对象中存储的统计信息可视化模型的训练进度

hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
hist.tail()

image.png

def plot_history(history):
  hist = pd.DataFrame(history.history)
  hist['epoch'] = history.epoch

  plt.figure()
  plt.xlabel('Epoch')
  plt.ylabel('Mean Abs Error [MPG]')
  plt.plot(hist['epoch'], hist['mae'],
           label='Train Error')
  plt.plot(hist['epoch'], hist['val_mae'],
           label = 'Val Error')
  plt.ylim([0,5])
  plt.legend()

  plt.figure()
  plt.xlabel('Epoch')
  plt.ylabel('Mean Square Error [$MPG^2$]')
  plt.plot(hist['epoch'], hist['mse'],
           label='Train Error')
  plt.plot(hist['epoch'], hist['val_mse'],
           label = 'Val Error')
  plt.ylim([0,20])
  plt.legend()
  plt.show()


plot_history(history)

image.png 该图表显示在约100个 epochs 之后误差非但没有改进,反而出现恶化。 让我们更新 model.fit 调用,当验证值没有提高上是自动停止训练。 我们将使用一个 EarlyStopping callback 来测试每个 epoch 的训练条件。如果经过一定数量的 epochs 后没有改进,则自动停止训练。

你可以从这里学习到更多的回调。

model = build_model()

patience 值用来检查改进 epochs 的数量

early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)

history = model.fit(normed_train_data, train_labels, epochs=EPOCH,
                    validation_split = 0.2, verbose=0, callbacks=[early_stop, PrintDot()])

plot_history(history)

image.png 如图所示,验证集中的平均的误差通常在 +/- 2 MPG左右。 这个结果好么? 我们将决定权留给你。

让我们看看通过使用 测试集 来泛化模型的效果如何,我们在训练模型时没有使用测试集。这告诉我们,当我们在现实世界中使用这个模型时,我们可以期望它预测得有多好。

loss,mae,mse = model.evaluate(normed_test_data,test_labels,verbose =2)
print('testing set mean abs error:{:5.2f} MPG'.format(mae))

2.4 做预测

loss,mae,mse = model.evaluate(normed_test_data,test_labels,verbose =2)
print('testing set mean abs error:{:5.2f} MPG'.format(mae))

image.png

查看误差分布

error = test_predictions - test_labels
plt.hist(error, bins = 25)
plt.xlabel("Prediction Error [MPG]")
_ = plt.ylabel("Count")

image.png

它不是完全的高斯分布,但我们可以推断出,这是因为样本的数量很小所导致的。

结论

本笔记本 (notebook) 介绍了一些处理回归问题的技术。

  • 均方误差(MSE)是用于回归问题的常见损失函数(分类问题中使用不同的损失函数)。
  • 类似的,用于回归的评估指标与分类不同。 常见的回归指标是平均绝对误差(MAE)。
  • 当数字输入数据特征的值存在不同范围时,每个特征应独立缩放到相同范围。
  • 如果训练数据不多,一种方法是选择隐藏层较少的小网络,以避免过度拟合。
  • 早期停止是一种防止过度拟合的有效技术。