Python TensorFlow/Keras-如何正确转换文本?

Python TensorFlow/Keras-如何正确转换文本?,python,tensorflow,machine-learning,keras,Python,Tensorflow,Machine Learning,Keras,我正在尝试创建一个模型来确定句子的主语是否是布拉格市 句子用斯洛伐克语。即: “V Prahe bolo dobre”,“Praha je VČesku” 我的csv文件如下所示: Praha je v Česku,1 Chodím do Blavy,0 Neviem čo to je za vetu,0 Pražský hrad,1 正如你所看到的,布拉格这个词有很多形式,所以我不想把csv中的每个词都替换成一些数字。我的目标是在角色级别检测它 我试过这个: train = pandas

我正在尝试创建一个模型来确定句子的主语是否是布拉格市

句子用斯洛伐克语。即:

“V Prahe bolo dobre”,“Praha je VČesku”

我的
csv
文件如下所示:

Praha je v Česku,1 
Chodím do Blavy,0 
Neviem čo to je za vetu,0
Pražský hrad,1
正如你所看到的,布拉格这个词有很多形式,所以我不想把csv中的每个词都替换成一些数字。我的目标是在角色级别检测它

我试过这个:

train = pandas.read_csv("prague_train_set.csv",
                        usecols=[ "title"])

train['title'] = train['title'].fillna("None")
train['title'] = le.fit_transform(train['title'])

results = pandas.read_csv("prague_train_set.csv",
                        usecols=["result"])    

# create model
model = Sequential()
model.add(Dense(12, input_dim=1, init='uniform', activation='relu'))
model.add(Dense(10, init='uniform', activation='relu'))
model.add(Dense(1, init='uniform', activation='sigmoid'))
# Compile model
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
# Fit the model
model.fit(train, results, epochs=150, batch_size=10, verbose=2)
# calculate predictions
predictions = model.predict(train)
但输出就像是完全随机的:

编辑大约有1/4的书名是关于布拉格的

...
Epoch 145/150
 - 0s - loss: 0.1826 - acc: 0.7589
Epoch 146/150
 - 0s - loss: 0.1827 - acc: 0.7589
Epoch 147/150
 - 0s - loss: 0.1826 - acc: 0.7589
Epoch 148/150
 - 0s - loss: 0.1827 - acc: 0.7589
Epoch 149/150
 - 0s - loss: 0.1827 - acc: 0.7589
Epoch 150/150
 - 0s - loss: 0.1827 - acc: 0.7589

我认为这是因为
train['title']=le.fit_变换(train['title'])
将整个句子转换成数字,但不确定。你知道怎么做吗?

既然你想在角色级别上分类,我建议使用CHAR-CNN:

要预处理数据,您只需做两件事:

1) 获取一组您想要使用的字符-可能是每个字符(包括标点符号),也可能是最常用的字符

2) 建立字符编码并保存为整数。如果未使用1)中定义的集合中的所有字符,还应为未知字符创建一个整数

3) 修剪或填充句子,使其具有标准长度

下面是一个简单的CHAR-CNN示例,用于预测字符串中是否存在“a”:

首先对数据进行预处理: 这方面的代码可能如下所示:

from random import choice

lowercase = 'abcdefghijklmnopqrstuvwxyz'
x = [''.join(choice(lowercase) for _ in range(10)) for _ in range(5000)]
y = [int('a' in i) for i in x]

char_set = set(char for word in x for char in word)
encoding = {i: char+1 for char, i in enumerate(char_set)} # let 0 be the unknown character
将编码字典保存在某个位置,您可以将所有输入转换为整数:

x = [[encoding.get(char, 0) for char in sentence] for sentence in x]
然后按顺序填充:

max_len = max(len(i) for i in x)

from keras.preprocessing.sequence import pad_sequences
x = pad_sequences(x, maxlen=max_len)
每个句子都变成一个整数列表

数据预处理后,您将构建模型。由于我们的预处理数据是一个整数列表,我们将遇到一个大问题:

如果“a”=>2和“b”=>7,即使这不是真的,模型也会天真地假设“b”>a

为了解决这个问题(并让模型构建每个角色的内部表示),我将使用嵌入层将每个角色映射到一个N维向量

from keras.models import Sequential
from keras.layers import Embedding, Conv1D, GlobalMaxPooling1D, Dense

VOCAB_SIZE = len(encoding) + 1
N_VECTORS = 12

model = Sequential()
model.add(Embedding(VOCAB_SIZE, N_VECTORS, input_length = max_len))
在这个阶段,我们可以使用Conv1D层开始检测特征。不幸的是,我不能给你精确的超参数,因为我无法访问你的整个数据集,所以这只是一个示例模型

model.add(Conv1D(64, kernel_size=(3,)))
model.add(Conv1D(32, kernel_size=(3,)))
由于我们在这个阶段处理一个3D张量(嵌入层返回一个3D输出
(批大小,最大长度,N个向量))
,并且我们想要返回一个2D输出
(批大小,一个或零)
,我们将输出最大化,并将其送入一个密集层

model.add(GlobalMaxPooling1D())
model.add(Dense(1, activation='sigmoid')) #sigmoid activation to return number from 0-1

model.compile(loss='binary_crossentropy', optimizer='adam')
model.summary()
model.fit(x, y, epochs=1000)
最后,为了您的方便,我上传了我在pastebin上使用的代码的未拆分副本:。在玩具数据集上运行模型可以在两个时代内获得100%的准确性


我希望这个答案能让你更好地理解nlp文本的预处理以及一些你可以使用的技术。祝你好运

您的csv文件有多大?大约5000篇文章您正在进行二进制分类,对吗?首先,我将使用“二进制交叉熵”作为损失函数,而不是均方误差,因为如果它是线性回归/输出层,您可能会想使用它……这在这里没有意义。另外,读过words2vec吗?如果
le
是一个标签转换器,那么你是对的。另外,
input_dim=1
意味着每个样本仅表示为一个具有一个值的向量。如果您不想使用转移学习,并且您有一个非常小的训练集,我将通过标记句子、填充相同长度的标记以及使用与此长度相等的内核大小的卷积来帮助分类器。通过这种方式,你可以识别一个句子是否至少包含城市的名称。谢谢,我将尝试这种方法。我已经创建了一个新代码,它似乎运行得更好,但结果并不令人满意-您希望我做什么?复制粘贴到你的新问题?