作者: fchollet
创建日期 2020/06/09
上次修改日期 2020/06/09
描述: 对包含数值和类别特征的结构化数据进行二元分类。
此示例演示了如何从原始 CSV 文件开始进行结构化数据分类。我们的数据包含数值特征和类别特征。我们将使用 Keras 预处理层对数值特征进行归一化,并对类别特征进行向量化。
请注意,此示例应使用 TensorFlow 2.5 或更高版本运行。
我们的数据集由克里夫兰诊所心脏病基金会提供。它是一个包含 303 行的 CSV 文件。每一行包含一位患者的信息(一个样本),每一列描述患者的一个属性(一个特征)。我们使用这些特征来预测患者是否患有心脏病(二元分类)。
以下是每个特征的描述
列 | 描述 | 特征类型 |
---|---|---|
Age | 年龄(岁) | 数值型 |
Sex | (1 = 男性;0 = 女性) | 类别型 |
CP | 胸痛类型 (0, 1, 2, 3, 4) | 类别型 |
Trestbpd | 入院时静息血压(单位:毫米汞柱) | 数值型 |
Chol | 血清胆固醇(单位:毫克/分升) | 数值型 |
FBS | 空腹血糖超过 120 毫克/分升(1 = 是;0 = 否) | 类别型 |
RestECG | 静息心电图结果 (0, 1, 2) | 类别型 |
Thalach | 达到的最大心率 | 数值型 |
Exang | 运动诱发心绞痛(1 = 是;0 = 否) | 类别型 |
Oldpeak | 运动引起的相对于静息的 ST 段压低 | 数值型 |
Slope | 运动峰值 ST 段的斜率 | 数值型 |
CA | 通过荧光透视着色的主要血管数量 (0-3) | 数值型和类别型 |
Thal | 3 = 正常;6 = 固定缺陷;7 = 可逆缺陷 | 类别型 |
Target | 心脏病诊断(1 = 是;0 = 否) | Target |
import os
os.environ["KERAS_BACKEND"] = "torch" # or torch, or tensorflow
import pandas as pd
import keras
from keras import layers
让我们下载数据并将其加载到 Pandas 数据框中
file_url = "http://storage.googleapis.com/download.tensorflow.org/data/heart.csv"
dataframe = pd.read_csv(file_url)
数据集包含 303 个样本,每个样本有 14 列(13 个特征加上目标标签)
dataframe.shape
(303, 14)
以下是部分样本的预览
dataframe.head()
age | sex | cp | trestbps | chol | fbs | restecg | thalach | exang | oldpeak | slope | ca | thal | target | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 63 | 1 | 1 | 145 | 233 | 1 | 2 | 150 | 0 | 2.3 | 3 | 0 | 固定缺陷 | 0 |
1 | 67 | 1 | 4 | 160 | 286 | 0 | 2 | 108 | 1 | 1.5 | 2 | 3 | 正常 | 1 |
2 | 67 | 1 | 4 | 120 | 229 | 0 | 2 | 129 | 1 | 2.6 | 2 | 2 | 可逆缺陷 | 0 |
3 | 37 | 1 | 3 | 130 | 250 | 0 | 0 | 187 | 0 | 3.5 | 3 | 0 | 正常 | 0 |
4 | 41 | 0 | 2 | 130 | 204 | 0 | 2 | 172 | 0 | 1.4 | 1 | 0 | 正常 | 0 |
最后一列“target”表示患者是否患有心脏病(1)或没有(0)。
让我们将数据分割成训练集和验证集
val_dataframe = dataframe.sample(frac=0.2, random_state=1337)
train_dataframe = dataframe.drop(val_dataframe.index)
print(
f"Using {len(train_dataframe)} samples for training "
f"and {len(val_dataframe)} for validation"
)
Using 242 samples for training and 61 for validation
在这里,我们定义了数据集的元数据,这对于读取数据、将其解析为输入特征以及根据特征类型对其进行编码非常有用。
COLUMN_NAMES = [
"age",
"sex",
"cp",
"trestbps",
"chol",
"fbs",
"restecg",
"thalach",
"exang",
"oldpeak",
"slope",
"ca",
"thal",
"target",
]
# Target feature name.
TARGET_FEATURE_NAME = "target"
# Numeric feature names.
NUMERIC_FEATURE_NAMES = ["age", "trestbps", "thalach", "oldpeak", "slope", "chol"]
# Categorical features and their vocabulary lists.
# Note that we add 'v=' as a prefix to all categorical feature values to make
# sure that they are treated as strings.
CATEGORICAL_FEATURES_WITH_VOCABULARY = {
feature_name: sorted(
[
# Integer categorcal must be int and string must be str
value if dataframe[feature_name].dtype == "int64" else str(value)
for value in list(dataframe[feature_name].unique())
]
)
for feature_name in COLUMN_NAMES
if feature_name not in list(NUMERIC_FEATURE_NAMES + [TARGET_FEATURE_NAME])
}
# All features names.
FEATURE_NAMES = NUMERIC_FEATURE_NAMES + list(
CATEGORICAL_FEATURES_WITH_VOCABULARY.keys()
)
以下特征是编码为整数的类别特征
sex
cp
fbs
restecg
exang
ca
我们将使用独热编码对这些特征进行编码。我们有两种选择
CategoryEncoding()
,这需要知道输入值的范围,并且在输入超出范围时会出错。IntegerLookup()
,它将为输入构建一个查找表,并为未知输入值保留一个输出索引。对于此示例,我们需要一个简单的解决方案,可以在推理时处理超出范围的输入,因此我们将使用 IntegerLookup()
。
我们还有一个编码为字符串的类别特征:thal
。我们将创建所有可能特征的索引,并使用 StringLookup()
层对输出进行编码。
最后,以下特征是连续的数值特征
age
trestbps
chol
thalach
oldpeak
slope
对于每个这些特征,我们将使用 Normalization()
层来确保每个特征的均值为 0,标准差为 1。
下面,我们定义了 2 个实用函数来执行这些操作
encode_numerical_feature
用于对数值特征应用逐特征归一化。process
用于对字符串或整数类别特征进行独热编码。# Tensorflow required for tf.data.Dataset
import tensorflow as tf
# We process our datasets elements here (categorical) and convert them to indices to avoid this step
# during model training since only tensorflow support strings.
def encode_categorical(features, target):
for feature_name in features:
if feature_name in CATEGORICAL_FEATURES_WITH_VOCABULARY:
lookup_class = (
layers.StringLookup
if features[feature_name].dtype == "string"
else layers.IntegerLookup
)
vocabulary = CATEGORICAL_FEATURES_WITH_VOCABULARY[feature_name]
# Create a lookup to convert a string values to an integer indices.
# Since we are not using a mask token nor expecting any out of vocabulary
# (oov) token, we set mask_token to None and num_oov_indices to 0.
index = lookup_class(
vocabulary=vocabulary,
mask_token=None,
num_oov_indices=0,
output_mode="binary",
)
# Convert the string input values into integer indices.
value_index = index(features[feature_name])
features[feature_name] = value_index
else:
pass
# Change features from OrderedDict to Dict to match Inputs as they are Dict.
return dict(features), target
def encode_numerical_feature(feature, name, dataset):
# Create a Normalization layer for our feature
normalizer = layers.Normalization()
# Prepare a Dataset that only yields our feature
feature_ds = dataset.map(lambda x, y: x[name])
feature_ds = feature_ds.map(lambda x: tf.expand_dims(x, -1))
# Learn the statistics of the data
normalizer.adapt(feature_ds)
# Normalize the input feature
encoded_feature = normalizer(feature)
return encoded_feature
让我们为每个数据框生成 tf.data.Dataset
对象
def dataframe_to_dataset(dataframe):
dataframe = dataframe.copy()
labels = dataframe.pop("target")
ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels)).map(
encode_categorical
)
ds = ds.shuffle(buffer_size=len(dataframe))
return ds
train_ds = dataframe_to_dataset(train_dataframe)
val_ds = dataframe_to_dataset(val_dataframe)
每个 Dataset
生成一个元组 (input, target)
,其中 input
是一个特征字典,target
是值 0
或 1
for x, y in train_ds.take(1):
print("Input:", x)
print("Target:", y)
Input: {'age': <tf.Tensor: shape=(), dtype=int64, numpy=45>, 'sex': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([0, 1])>, 'cp': <tf.Tensor: shape=(5,), dtype=int64, numpy=array([0, 0, 0, 0, 1])>, 'trestbps': <tf.Tensor: shape=(), dtype=int64, numpy=142>, 'chol': <tf.Tensor: shape=(), dtype=int64, numpy=309>, 'fbs': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([1, 0])>, 'restecg': <tf.Tensor: shape=(3,), dtype=int64, numpy=array([0, 0, 1])>, 'thalach': <tf.Tensor: shape=(), dtype=int64, numpy=147>, 'exang': <tf.Tensor: shape=(2,), dtype=int64, numpy=array([0, 1])>, 'oldpeak': <tf.Tensor: shape=(), dtype=float64, numpy=0.0>, 'slope': <tf.Tensor: shape=(), dtype=int64, numpy=2>, 'ca': <tf.Tensor: shape=(4,), dtype=int64, numpy=array([0, 0, 0, 1])>, 'thal': <tf.Tensor: shape=(5,), dtype=int64, numpy=array([0, 0, 0, 0, 1])>}
Target: tf.Tensor(1, shape=(), dtype=int64)
让我们对数据集进行批处理
train_ds = train_ds.batch(32)
val_ds = val_ds.batch(32)
完成此步骤后,我们可以创建我们的端到端模型
# Categorical features have different shapes after the encoding, dependent on the
# vocabulary or unique values of each feature. We create them accordinly to match the
# input data elements generated by tf.data.Dataset after pre-processing them
def create_model_inputs():
inputs = {}
# This a helper function for creating categorical features
def create_input_helper(feature_name):
num_categories = len(CATEGORICAL_FEATURES_WITH_VOCABULARY[feature_name])
inputs[feature_name] = layers.Input(
name=feature_name, shape=(num_categories,), dtype="int64"
)
return inputs
for feature_name in FEATURE_NAMES:
if feature_name in CATEGORICAL_FEATURES_WITH_VOCABULARY:
# Categorical features
create_input_helper(feature_name)
else:
# Make them float32, they are Real numbers
feature_input = layers.Input(name=feature_name, shape=(1,), dtype="float32")
# Process the Inputs here
inputs[feature_name] = encode_numerical_feature(
feature_input, feature_name, train_ds
)
return inputs
# This Layer defines the logic of the Model to perform the classification
class Classifier(keras.layers.Layer):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.dense_1 = layers.Dense(32, activation="relu")
self.dropout = layers.Dropout(0.5)
self.dense_2 = layers.Dense(1, activation="sigmoid")
def call(self, inputs):
all_features = layers.concatenate(list(inputs.values()))
x = self.dense_1(all_features)
x = self.dropout(x)
output = self.dense_2(x)
return output
# Surpress build warnings
def build(self, input_shape):
self.built = True
# Create the Classifier model
def create_model():
all_inputs = create_model_inputs()
output = Classifier()(all_inputs)
model = keras.Model(all_inputs, output)
return model
model = create_model()
model.compile("adam", "binary_crossentropy", metrics=["accuracy"])
/home/humbulani/tensorflow-env/env/lib/python3.11/site-packages/keras/src/models/functional.py:106: UserWarning: When providing `inputs` as a dict, all keys in the dict must match the names of the corresponding tensors. Received key 'age' mapping to value <KerasTensor shape=(None, 1), dtype=float32, sparse=False, name=keras_tensor> which has name 'keras_tensor'. Change the tensor name to 'age' (via `Input(..., name='age')`)
warnings.warn(
/home/humbulani/tensorflow-env/env/lib/python3.11/site-packages/keras/src/models/functional.py:106: UserWarning: When providing `inputs` as a dict, all keys in the dict must match the names of the corresponding tensors. Received key 'trestbps' mapping to value <KerasTensor shape=(None, 1), dtype=float32, sparse=False, name=keras_tensor_1> which has name 'keras_tensor_1'. Change the tensor name to 'trestbps' (via `Input(..., name='trestbps')`)
warnings.warn(
/home/humbulani/tensorflow-env/env/lib/python3.11/site-packages/keras/src/models/functional.py:106: UserWarning: When providing `inputs` as a dict, all keys in the dict must match the names of the corresponding tensors. Received key 'thalach' mapping to value <KerasTensor shape=(None, 1), dtype=float32, sparse=False, name=keras_tensor_2> which has name 'keras_tensor_2'. Change the tensor name to 'thalach' (via `Input(..., name='thalach')`)
warnings.warn(
/home/humbulani/tensorflow-env/env/lib/python3.11/site-packages/keras/src/models/functional.py:106: UserWarning: When providing `inputs` as a dict, all keys in the dict must match the names of the corresponding tensors. Received key 'oldpeak' mapping to value <KerasTensor shape=(None, 1), dtype=float32, sparse=False, name=keras_tensor_3> which has name 'keras_tensor_3'. Change the tensor name to 'oldpeak' (via `Input(..., name='oldpeak')`)
warnings.warn(
/home/humbulani/tensorflow-env/env/lib/python3.11/site-packages/keras/src/models/functional.py:106: UserWarning: When providing `inputs` as a dict, all keys in the dict must match the names of the corresponding tensors. Received key 'slope' mapping to value <KerasTensor shape=(None, 1), dtype=float32, sparse=False, name=keras_tensor_4> which has name 'keras_tensor_4'. Change the tensor name to 'slope' (via `Input(..., name='slope')`)
warnings.warn(
/home/humbulani/tensorflow-env/env/lib/python3.11/site-packages/keras/src/models/functional.py:106: UserWarning: When providing `inputs` as a dict, all keys in the dict must match the names of the corresponding tensors. Received key 'chol' mapping to value <KerasTensor shape=(None, 1), dtype=float32, sparse=False, name=keras_tensor_5> which has name 'keras_tensor_5'. Change the tensor name to 'chol' (via `Input(..., name='chol')`)
warnings.warn(
让我们可视化连接图
# `rankdir='LR'` is to make the graph horizontal.
keras.utils.plot_model(model, show_shapes=True, rankdir="LR")
model.fit(train_ds, epochs=50, validation_data=val_ds)
Epoch 1/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 102ms/step - accuracy: 0.4688 - loss: 8.0563
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - accuracy: 0.4732 - loss: 7.9796
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.4725 - loss: 7.9848 - val_accuracy: 0.2295 - val_loss: 12.0816
Epoch 2/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 105ms/step - accuracy: 0.5000 - loss: 6.6368
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - accuracy: 0.4532 - loss: 7.8320
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 18ms/step - accuracy: 0.4547 - loss: 7.8310 - val_accuracy: 0.2459 - val_loss: 6.2543
Epoch 3/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 91ms/step - accuracy: 0.5000 - loss: 7.6558
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.5041 - loss: 7.3378
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step - accuracy: 0.5087 - loss: 7.2802 - val_accuracy: 0.6885 - val_loss: 2.1633
Epoch 4/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 93ms/step - accuracy: 0.4375 - loss: 8.9030
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - accuracy: 0.4815 - loss: 8.0109
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 19ms/step - accuracy: 0.4858 - loss: 7.9351 - val_accuracy: 0.7705 - val_loss: 3.3916
Epoch 5/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 88ms/step - accuracy: 0.4688 - loss: 8.1279
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.5049 - loss: 7.4815
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.5117 - loss: 7.4054 - val_accuracy: 0.7705 - val_loss: 3.6911
Epoch 6/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 107ms/step - accuracy: 0.4688 - loss: 7.8832
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.4940 - loss: 7.4615
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.5121 - loss: 7.1851 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 7/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 101ms/step - accuracy: 0.5312 - loss: 6.9446
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 12ms/step - accuracy: 0.5357 - loss: 6.5511
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.5497 - loss: 6.3711 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 8/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 110ms/step - accuracy: 0.5938 - loss: 6.3905
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.6192 - loss: 5.9601
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6101 - loss: 6.0728 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 9/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 108ms/step - accuracy: 0.5938 - loss: 6.5442
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.6006 - loss: 6.3309
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step - accuracy: 0.5949 - loss: 6.3647 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 10/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 113ms/step - accuracy: 0.5625 - loss: 6.8250
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 10ms/step - accuracy: 0.5675 - loss: 6.5020
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.5764 - loss: 6.3308 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 11/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 116ms/step - accuracy: 0.6250 - loss: 4.3582
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.6053 - loss: 5.4824
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6076 - loss: 5.4500 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 12/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 118ms/step - accuracy: 0.5625 - loss: 7.0064
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.5740 - loss: 6.4431
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step - accuracy: 0.5787 - loss: 6.3510 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 13/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 115ms/step - accuracy: 0.7500 - loss: 3.7382
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 10ms/step - accuracy: 0.6812 - loss: 4.7893
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step - accuracy: 0.6712 - loss: 4.9453 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 14/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 114ms/step - accuracy: 0.6562 - loss: 5.5498
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.6580 - loss: 5.4636
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step - accuracy: 0.6578 - loss: 5.4379 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 15/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 113ms/step - accuracy: 0.5938 - loss: 5.8118
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.5978 - loss: 5.9295
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step - accuracy: 0.6045 - loss: 5.8426 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 16/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 115ms/step - accuracy: 0.6562 - loss: 4.4893
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.5763 - loss: 5.9135
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.5814 - loss: 5.8590 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 17/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 127ms/step - accuracy: 0.5625 - loss: 7.0281
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.6071 - loss: 6.0424
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6179 - loss: 5.8262 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 18/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 130ms/step - accuracy: 0.6562 - loss: 5.3547
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.6701 - loss: 5.0648
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.6713 - loss: 5.0607 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 19/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 121ms/step - accuracy: 0.7500 - loss: 4.0295
5/8 ━━━━━━━━━━━━ [37m━━━━━━━━ 0s 13ms/step - accuracy: 0.7157 - loss: 4.3995
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.7077 - loss: 4.4886 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 20/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 129ms/step - accuracy: 0.6250 - loss: 6.0278
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.6479 - loss: 5.4982
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6461 - loss: 5.4898 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 21/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 134ms/step - accuracy: 0.5938 - loss: 5.8592
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.6782 - loss: 4.7529
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.6627 - loss: 5.0219 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 22/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 127ms/step - accuracy: 0.6875 - loss: 5.0149
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.6342 - loss: 5.5898
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.6290 - loss: 5.6701 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 23/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 121ms/step - accuracy: 0.5938 - loss: 6.0783
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.6259 - loss: 5.6908
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6352 - loss: 5.5719 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 24/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 112ms/step - accuracy: 0.7812 - loss: 3.1021
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 12ms/step - accuracy: 0.7353 - loss: 3.8725
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.7163 - loss: 4.1637 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 25/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 112ms/step - accuracy: 0.5625 - loss: 6.9224
5/8 ━━━━━━━━━━━━ [37m━━━━━━━━ 0s 13ms/step - accuracy: 0.6331 - loss: 5.5663
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.6416 - loss: 5.4024 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 26/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 117ms/step - accuracy: 0.6875 - loss: 4.4043
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.6668 - loss: 5.0742
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6743 - loss: 4.9986 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 27/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 104ms/step - accuracy: 0.6562 - loss: 5.3405
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 8ms/step - accuracy: 0.6868 - loss: 4.7990
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step - accuracy: 0.6838 - loss: 4.8458 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 28/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 116ms/step - accuracy: 0.6562 - loss: 4.8092
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.7061 - loss: 4.3996
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step - accuracy: 0.7053 - loss: 4.4297 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 29/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 114ms/step - accuracy: 0.6250 - loss: 5.6655
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 10ms/step - accuracy: 0.6536 - loss: 5.3912
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step - accuracy: 0.6589 - loss: 5.3014 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 30/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 116ms/step - accuracy: 0.7812 - loss: 3.5258
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.6900 - loss: 4.7711
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 20ms/step - accuracy: 0.6882 - loss: 4.8074 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 31/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 123ms/step - accuracy: 0.5938 - loss: 6.5425
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 10ms/step - accuracy: 0.6346 - loss: 5.6779
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6423 - loss: 5.5672 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 32/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 120ms/step - accuracy: 0.6250 - loss: 5.6215
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.6451 - loss: 5.2140
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.6556 - loss: 5.0993 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 33/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 115ms/step - accuracy: 0.7188 - loss: 4.2096
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.7218 - loss: 4.3075
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.7143 - loss: 4.4143 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 34/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 114ms/step - accuracy: 0.5625 - loss: 7.0242
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.6608 - loss: 5.3428
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6675 - loss: 5.2031 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 35/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 105ms/step - accuracy: 0.6875 - loss: 5.0369
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.6601 - loss: 5.2386
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6675 - loss: 5.0972 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 36/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 114ms/step - accuracy: 0.6562 - loss: 4.8957
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.7086 - loss: 4.4144
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.6980 - loss: 4.5912 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 37/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 115ms/step - accuracy: 0.6250 - loss: 6.0333
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.6438 - loss: 5.6852
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 23ms/step - accuracy: 0.6551 - loss: 5.4504 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 38/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 119ms/step - accuracy: 0.5938 - loss: 6.4043
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.6659 - loss: 5.2220
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6751 - loss: 5.0637 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 39/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 122ms/step - accuracy: 0.5625 - loss: 7.0517
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 10ms/step - accuracy: 0.6782 - loss: 5.0396
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6854 - loss: 4.9129 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 40/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 121ms/step - accuracy: 0.6562 - loss: 5.4278
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.6575 - loss: 5.2183
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6676 - loss: 5.0430 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 41/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 120ms/step - accuracy: 0.7500 - loss: 3.9611
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 10ms/step - accuracy: 0.7322 - loss: 4.2233
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.7325 - loss: 4.2274 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 42/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 127ms/step - accuracy: 0.8438 - loss: 2.5075
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.7483 - loss: 3.8605
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step - accuracy: 0.7305 - loss: 4.1423 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 43/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 132ms/step - accuracy: 0.7188 - loss: 4.5277
5/8 ━━━━━━━━━━━━ [37m━━━━━━━━ 0s 15ms/step - accuracy: 0.6698 - loss: 5.2541
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step - accuracy: 0.6831 - loss: 4.9995 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 44/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 1s 149ms/step - accuracy: 0.7188 - loss: 4.3368
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 12ms/step - accuracy: 0.6884 - loss: 4.8941
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step - accuracy: 0.6877 - loss: 4.9237 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 45/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 113ms/step - accuracy: 0.7188 - loss: 3.6048
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.6953 - loss: 4.5189
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step - accuracy: 0.6914 - loss: 4.6078 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 46/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 120ms/step - accuracy: 0.7188 - loss: 4.5277
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.7298 - loss: 4.2710
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 25ms/step - accuracy: 0.7214 - loss: 4.4175 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 47/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 117ms/step - accuracy: 0.7500 - loss: 4.0295
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.6962 - loss: 4.8892
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step - accuracy: 0.6981 - loss: 4.8478 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 48/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 122ms/step - accuracy: 0.7812 - loss: 3.4540
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 9ms/step - accuracy: 0.7095 - loss: 4.5553
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 21ms/step - accuracy: 0.7080 - loss: 4.5585 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 49/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 117ms/step - accuracy: 0.6875 - loss: 4.5707
7/8 ━━━━━━━━━━━━━━━━━ [37m━━━ 0s 10ms/step - accuracy: 0.6914 - loss: 4.7756
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6939 - loss: 4.7445 - val_accuracy: 0.7705 - val_loss: 3.6992
Epoch 50/50
1/8 ━━ [37m━━━━━━━━━━━━━━━━━━ 0s 124ms/step - accuracy: 0.7188 - loss: 4.0735
6/8 ━━━━━━━━━━━━━━━ [37m━━━━━ 0s 11ms/step - accuracy: 0.7049 - loss: 4.3802
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 22ms/step - accuracy: 0.6987 - loss: 4.5132 - val_accuracy: 0.7705 - val_loss: 3.6992
<keras.src.callbacks.history.History at 0x747bef08e590>
我们很快达到了 80% 的验证准确率。
要获得新样本的预测结果,只需调用 model.predict()
。您只需做两件事
convert_to_tensor
sample = {
"age": 60,
"sex": 1,
"cp": 1,
"trestbps": 145,
"chol": 233,
"fbs": 1,
"restecg": 2,
"thalach": 150,
"exang": 0,
"oldpeak": 2.3,
"slope": 3,
"ca": 0,
"thal": "fixed",
}
# Given the category (in the sample above - key) and the category value (in the sample above - value),
# we return its one-hot encoding
def get_cat_encoding(cat, cat_value):
# Create a list of zeros with the same length as categories
encoding = [0] * len(cat)
# Find the index of category_value in categories and set the corresponding position to 1
if cat_value in cat:
encoding[cat.index(cat_value)] = 1
return encoding
for name, value in sample.items():
if name in CATEGORICAL_FEATURES_WITH_VOCABULARY:
sample.update(
{
name: get_cat_encoding(
CATEGORICAL_FEATURES_WITH_VOCABULARY[name], sample[name]
)
}
)
# Convert inputs to tensors
input_dict = {name: tf.convert_to_tensor([value]) for name, value in sample.items()}
predictions = model.predict(input_dict)
print(
f"This particular patient had a {100 * predictions[0][0]:.1f} "
"percent probability of having a heart disease, "
"as evaluated by our model."
)
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 77ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 79ms/step
This particular patient had a 0.0 percent probability of having a heart disease, as evaluated by our model.