我正在尝试创建一个模型,该模型确定句子的主要主题是否是布拉格市。
句子使用斯洛伐克语。即:
“ 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_transform(train['title'])
将整个句子转换为数字,但不确定。你知道该怎么办吗?
答案 0 :(得分:0)
因为您要在字符级别上进行分类,所以我建议使用CHAR-CNN:
https://papers.nips.cc/paper/5782-character-level-convolutional-networks-for-text-classification.pdf
要处理数据,您只需要做两件事:
1)获取一组您要使用的字符-这可能是每个字符(包括标点符号)或只是最常见的字符
2)建立并将字符编码保存为整数。如果您未使用1)中定义的集合内的所有字符,请为未知字符创建一个整数
3)修剪或填充句子以使其具有标准长度
下面是一个简单的CHAR-CNN示例,旨在预测字符串中是否存在“ a”:
首先预处理数据: 此代码可能类似于:
import numpy as np
import sympy as sp
import itertools as it
from sympy.abc import x, y, z
class Solver:
def __init__(self, vmat):
self._vfunc = sp.lambdify((x, y, z),
expr=vmat,
modules='numpy')
self._q_count, self._qs = None, [] # these depend on ksep!
################################################################
# How to vectorize this?
def eval_s(self, stiff):
assert len(self._qs) == self._q_count, "Run 'populate_qs' first!"
result = 0
for k in self._qs:
evs = np.linalg.eigvalsh(self._vfunc(*k))
result += np.sum(np.divide(1., (stiff + evs)))
return result.real - 4 * self._q_count
################################################################
def populate_qs(self, ksep: float = 1.7):
self._qs = [(kx, ky, kz) for kx, ky, kz
in it.product(np.arange(-3*np.pi, 3.01*np.pi, ksep),
np.arange(-3*np.pi, 3.01*np.pi, ksep),
np.arange(-3*np.pi, 3.01*np.pi, ksep))]
self._q_count = len(self._qs)
def test():
vmat = sp.Matrix([[1, sp.cos(x/4+y/4), sp.cos(x/4+z/4), sp.cos(y/4+z/4)],
[sp.cos(x/4+y/4), 1, sp.cos(y/4-z/4), sp.cos(x/4 - z/4)],
[sp.cos(x/4+z/4), sp.cos(y/4-z/4), 1, sp.cos(x/4-y/4)],
[sp.cos(y/4+z/4), sp.cos(x/4-z/4), sp.cos(x/4-y/4), 1]]) * 2
solver = Solver(vmat)
solver.populate_qs(ksep=1.7) # <---- Performance starts to worsen (in eval_s) when ksep is reduced!
print(solver.eval_s(0.65))
if __name__ == "__main__":
import timeit
print(timeit.timeit("test()", setup="from __main__ import test", number=100))
将编码字典保存在某个位置,您可以将所有输入转换为整数:
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]
每个句子变成一个整数列表。
对数据进行预处理后,您将构建模型。由于我们的预处理数据是整数列表,因此我们将遇到一个大问题:
如果“ a” => 2和“ b” => 7,则即使不正确,模型也会天真地假定为“ b”>“ a”。
为解决这个问题(并使模型建立每个字符的内部表示形式),我将使用嵌入层将每个字符映射到N维向量。
max_len = max(len(i) for i in x)
from keras.preprocessing.sequence import pad_sequences
x = pad_sequences(x, maxlen=max_len)
在此阶段,我们可以使用Conv1D图层开始检测特征。不幸的是,我无法为您提供确切的超参数,因为我无法访问您的整个数据集,因此,这只是一个示例模型。
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))
由于在此阶段我们正在处理3D张量(嵌入层返回3D输出model.add(Conv1D(64, kernel_size=(3,)))
model.add(Conv1D(32, kernel_size=(3,)))
,并且我们想返回2D输出(batch_size, max_len, N_VECTORS))
,所以我们将输出和提要最大化变成致密层。
(batch_size, one_or_zero)
为方便起见,最后我上传了我在pastebin:https://pastebin.com/SvvJaQJv上使用的完整代码副本。在玩具数据集上运行模型可在2个纪元内获得100%的准确性。
我希望这个答案可以使您更好地理解为nlp预处理文本以及可以使用的一些技术。祝你好运!