如何从数字数据转到字符串数据 (NN)?

数据挖掘 机器学习 Python 神经网络 分类 反向传播
2022-02-20 05:19:54

我对在神经网络中使用数字数据很有信心,但我想使用字符串数据。我的问题是我从哪里开始?显然你不能将权重和字符串一起计算(x * w),因为它们属于不同的数据类型,那么我应该如何处理字符串数据将其转换为数字呢?如果你有兴趣,这里是我的数据集。这绝不是最终版本,但这里只是给你一个例子。它基于拼写:

  1. 巨大的........| 难度:2
  2. 节奏........| 难度:3
  3. 仓鼠......| 难度:2
  4. 走…………| 难度:1
  5. 容纳...| 难度:3
  6. 蓝色........| 难度:1
  7. 投影仪…………| 难度:1
  8. 回归…………| 难度:2
  9. 去.............| 难度:1
  10. 剧作家........| 难度:3
  11. 奇怪..................| 难度:3
  12. 良心.......| 难度:2

...所以在训练之后,当我输入一个单词时,网络应该返回 1、2 或 3,这取决于网络认为单词拼写的难度。综上所述,我的问题是:我习惯于在我的项目中使用数字数据而不是字符串,那么在第一次创建基于字符串的网络时应该采取哪些步骤?我只使用 numpy

2个回答

有多种方法可以处理神经网络的字符串输入,但由于您试图预测拼写难度,我建议将您的单词表示为字符序列。这将保留有关单词特定拼写的信息,包括字母顺序。

要表示一个字符序列,您可以对每个字符进行一次热编码,因此每个单词将表示为一个长度为 26 的一次热向量序列。

为了处理这种输入,我建议使用一维卷积神经网络或某种形式的循环神经网络。

如果您选择 1D CNN,则必须为其提供固定大小的输入。为此,请选择最大字长k,然后将每个输入字截去或用零填充以适合k*26输入矩阵。

以下是您可能在 Keras 中使用的 CNN 架构示例:

model = Sequential()
model.add(Convolution1D(nb_filter=32, filter_length=5, activation='relu', input_shape=(k, 26))
model.add(MaxPooling1D())
model.add(Convolution1D(nb_filter=32, filter_length=5, activation='relu')
model.add(MaxPooling1D())
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

那么第一次创建基于字符串的网络时应该采取哪些步骤?

神经网络处理数值数据。它们也适用于相对较小的浮点数,以零为中心。您可以对该部分不那么严格,但是您经常会在神经网络中看到计算每个特征的训练数据的均值和标准差的方法,然后通过执行转换所有特征x = (x - means) / stds(您想存储这些缩放因子与网络数据一起使用,因为稍后在使用网络进行预测时,您将希望重新使用相同的值)。

那么如果输入的数据还不是这种形式,你会怎么做呢?在使用它进行训练或预测之前,您可以在代码中对其进行准备。这是机器学习脚本中非常常见的结构:

raw_features, raw_labels = load_from_disk( some_data_source )
all_features = convert_features( raw_features )
all_labels = convert_labels( raw_labels )
train_X, test_X, train_y, test_y = split_data( all_features, all_labels )
model = build_model( .... various model params ....)
model.fit( train_X, train_y )
test_predictions = model.predict( test_X )
report_accuracy( test_predictions, test_Y )

以上是粗略的伪代码,因此通常上述所有函数都有不同的名称,或者是多行执行相同的操作,如果您正在编写快速脚本,您可能不会费心将其封装到可重用的方法中。我展示的分割特征的部分可能会内置到训练函数中,而且训练过程可以使用测试数据来帮助监控进度也是很常见的。

如果加载和转换需要很长时间,您可以在单独的脚本中执行此操作,并将生成的 NumPy 数组保存在单独的文件中,以便下次更快加载。

因此,您关心的部分是如何convert_features从起始字符串构建一段代码。答案是使用可以从字符串中提取的任何相关值。字符串长度可能是一个简单的开始,即len( text )- 但您也可以查看任何其他可以计算的度量(例如元音的数量,单词中不常见的二元组)。决定尝试哪些功能并在它们之间进行测试是特征工程,这通常需要一些创造力。重要的是特征必须都是数字的。对于神经网络,您还应该尝试使它们相对较小和/或在进入下一阶段之前将它们转换为均值 0、标准差 1。

当你稍后使用网络进行预测时,你必须重复大部分管道:

model = load_model( model_file_or_identifier )
raw_features, raw_labels = fetch_data( some_data_source )
X = convert_features( raw_features )
y = convert_labels( raw_labels )
predictions = model.predict( X )
report_predictions( X, y )