【问题标题】:Doc2Vec & classification - very poor resultsDoc2Vec 和分类 - 结果很差
【发布时间】:2019-08-14 00:08:33
【问题描述】:

我有一个包含 6000 个观测值的数据集;它的一个示例如下:

job_id      job_title                                           job_sector
30018141    Secondary Teaching Assistant                        Education
30006499    Legal Sales Assistant / Executive                   Sales
28661197    Private Client Practitioner                         Legal
28585608    Senior hydropower mechanical project manager        Engineering
28583146    Warehouse Stock Checker - Temp / Immediate Start    Transport & Logistics
28542478    Security Architect Contract                         IT & Telecoms

目标是根据职位来预测每一行的职位部门。

首先,我对job_title 列进行了一些预处理:

def preprocess(document):
    lemmatizer = WordNetLemmatizer()
    stemmer_1 = PorterStemmer()
    stemmer_2 = LancasterStemmer()
    stemmer_3 = SnowballStemmer(language='english')

    # Remove all the special characters
    document = re.sub(r'\W', ' ', document)

    # remove all single characters
    document = re.sub(r'\b[a-zA-Z]\b', ' ', document)

    # Substituting multiple spaces with single space
    document = re.sub(r' +', ' ', document, flags=re.I)

    # Converting to lowercase
    document = document.lower()

    # Tokenisation
    document = document.split()

    # Stemming
    document = [stemmer_3.stem(word) for word in document]

    document = ' '.join(document)

    return document

df_first = pd.read_csv('../data.csv', keep_default_na=True)

for index, row in df_first.iterrows():

    df_first.loc[index, 'job_title'] = preprocess(row['job_title'])

然后我对GensimDoc2Vec 执行以下操作:

X = df_first.loc[:, 'job_title'].values
y = df_first.loc[:, 'job_sector'].values

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=0)

tagged_train = TaggedDocument(words=X_train.tolist(), tags=y_train.tolist())
tagged_train = list(tagged_train)

tagged_test = TaggedDocument(words=X_test.tolist(), tags=y_test.tolist())
tagged_test = list(tagged_test)

model = Doc2Vec(vector_size=5, min_count=2, epochs=30)

training_set = [TaggedDocument(sentence, tag) for sentence, tag in zip(X_train.tolist(), y_train.tolist())]

model.build_vocab(training_set)

model.train(training_set, total_examples=model.corpus_count, epochs=model.epochs)   

test_set = [TaggedDocument(sentence, tag) for sentence, tag in zip(X_test.tolist(), y_test.tolist())]

predictors_train = []
for sentence in X_train.tolist():

    sentence = sentence.split()
    predictor = model.infer_vector(doc_words=sentence, steps=20, alpha=0.01)

    predictors_train.append(predictor.tolist())

predictors_test = []
for sentence in X_test.tolist():

    sentence = sentence.split()
    predictor = model.infer_vector(doc_words=sentence, steps=20, alpha=0.025)

    predictors_test.append(predictor.tolist())

sv_classifier = SVC(kernel='linear', class_weight='balanced', decision_function_shape='ovr', random_state=0)
sv_classifier.fit(predictors_train, y_train)

score = sv_classifier.score(predictors_test, y_test)
print('accuracy: {}%'.format(round(score*100, 1)))

但是,我得到的结果是 22% 的准确率。

这让我很怀疑,尤其是因为使用TfidfVectorizer 而不是Doc2Vec(两者都使用相同的分类器),那么我的准确率就达到了 88% (!)。

因此,我想我在应用Doc2VecGensim 的方式上一定做错了。

它是什么,我该如何解决?

或者仅仅是我的数据集相对较小,而更高级的方法(如词嵌入等)需要更多的数据?

【问题讨论】:

    标签: python classification gensim text-classification doc2vec


    【解决方案1】:

    通常训练 doc2vec/word2vec 需要大量通用数据(word2vec 在 3 milian Wikipedia 文章上训练过),因为它在 doc2vec 上的表现不佳,请考虑使用预先训练的 doc2vec 进行试验,请参阅 this

    或者您可以尝试使用 word2vec 并对整个文档进行平均,因为 word2vec 会为每个单词提供向量。

    让我知道这有什么帮助?

    【讨论】:

      【解决方案2】:

      您没有提及数据集的大小 - 以行、总字数、唯一字词或唯一类为单位。 Doc2Vec 最适合处理大量数据。大多数已发表的工作都包含数万到数百万个文档,每个文档有几十到数千个单词。 (您的数据似乎每个文档只有 3-5 个单词。)

      此外,已发表的作品倾向于在每个文档都有唯一 ID 的数据上进行训练。有时使用已知标签作为标签来代替或补充唯一 ID 是有意义的。但这不一定是更好的方法。通过使用 known-labels 作为唯一的标签,您实际上只为每个标签训练一个 doc-vector。 (本质上类似于将具有相同标签的所有行连接到一个文档中。)

      你在推理中使用的 steps 比在训练中使用的 epochs 少得多 - 事实上这些是类似的值。在gensim 的最新版本中,默认情况下,推理将使用与模型配置用于训练的相同数量的推理时期。而且,在推理过程中使用 更多 个 epoch 比训练更常见。 (此外,您莫名其妙地使用不同的起始 alpha 值进行分类器训练和分类器测试的推理。)

      但主要问题可能是您选择了微小的size=5 文档向量。而不是TfidfVectorizer,它将每一行总结为一个宽度等于唯一字数的向量——可能是数百或数千个维度——你的Doc2Vec模型将每个文档总结为5个值。你基本上已经切除了Doc2Vec。这里的通常值是 100-1000 - 但如果数据集很小,可能需要更小的尺寸。

      最后,词形还原/词干化可能不是绝对必要的,甚至可能是破坏性的。很多Word2Vec/Doc2Vec 的工作不需要词根化/词干——通常是因为数据丰富,所有单词形式都有很多外观。

      这些步骤最有可能帮助处理较小的数据,确保将较稀有的词形式与相关的较长形式相结合,以仍然从本来太稀有而无法保留的词中获得价值(或获得有用的向量)。

      但我可以看到它们可能会损害您的域的许多方面。 ManagerManagement 在这种情况下不会有完全相同的含义,但都可以归结为 managSecuritySecurities 都变成 secur 和其他词类似。如果您可以通过评估证明它们有帮助,我只会执行这些步骤。 (传递给TfidfVectorizer 的词是否被词根化/词干化?)

      【讨论】:

      • 非常感谢您在这里的回答,并为我迟来的回复道歉。我已经看到您是 StackOverflow 中 gensim 标签问题的主要贡献者之一,我一直期待您的回复。您的观点绝对中肯,并且总体上对应如何应用 Doc2Vec 非常有见地。我会考虑的。
      • 如果我们排除我在 Gensim API 上犯了任何微不足道的代码错误的可能性(你看到我的代码并且你没有提到类似的东西)那么我认为我的 Doc2Vec 模型不会的主要原因正如您所说,表现如此出色的是我的数据集数量相当有限(6000 个观测值)。显然,我弄乱了超参数的值这一事实也起到了一定的作用,但我认为只有这样才能使准确率从 22% 跃升至 90%。
      • 我可以很容易地想象单独使用size=5 的驱动精度任意低,与使用更合适的维度所能达到的精度相比。知道Doc2Vec 是否具有竞争力的唯一方法是测试它。小型数据集的少数好处之一是可以快速检查修复/参数调整!因此,无需猜测什么可能会或可能不会产生足够的改进。
      • 嘿,我也有同样的问题。但是,我注意到 lemma/stem 对我的 tfidf 模型有很大帮助,但我注意到在我的 doc2vec 上没有它们我会得到更好的结果。这有意义吗?在任何情况下,我的 tfidf 模型仍然比我的 doc2vec 执行得更好
      • 根据所使用的其他算法,词干提取/词形还原有时会有所帮助,有时会造成伤害,这并不奇怪。在某些情况下,它们可能会使重要的模式(许多相关的词)对某些下游分类器更加清晰易读;在另一些情况下,他们可能会丢弃其他算法(具有足够数据)也可以利用的信息(相关含义的阴影)。值得建立一个系统,您可以在其中评估许多选项。
      【解决方案3】:

      您使用的工具不适合分类。我建议你研究一下 char-rnn 之类的东西。

      https://pytorch.org/tutorials/intermediate/char_rnn_classification_tutorial.html

      本教程处理类似的问题,它对名称进行分类。

      【讨论】:

      • 感谢您的回答。但是,我不确定这一点,因为互联网上有很多帖子使用 Doc2Vec 进行分类。
      • 您是否有任何理由使用支持向量分类器而不是简单的逻辑回归分类器。您也可以使用逻辑回归进行多类预测。 fzr72725.github.io/2018/01/14/genism-guide.html。这篇文章做了类似的事情。但请记住,要使 doc2vec 工作,与 word2vec 类似,您需要一个大小合适的语料库,否则这些向量将不够好。您可以尝试不同的尺寸大小,看看是否有帮助。
      • 原因是通常支持向量分类器优于逻辑回归,或者至少与它们相当。你关于拥有一个相对较小的语料库的最后一点是我也想到的,这可能是与我使用的tf-idfSVC 相比结果较差的原因。不过老实说,我没想到他们会那么穷。这表明我可能只是在使用Gensim 的方式上做错了什么。在这方面,如果您使用过Gensim,并且您可以在我上面的代码中发现任何错误,请告诉我。
      猜你喜欢
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 2018-06-02
      • 2022-01-13
      • 2021-02-20
      相关资源
      最近更新 更多