掘金 人工智能 5小时前
基于Doc2Vec的Markdown文档分类实战:从预处理到模型评估
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了一种使用Doc2Vec模型进行Markdown文档分类的方法。该方法通过加载Markdown文档、预处理文本、训练Doc2Vec模型生成文档向量,并使用分类器进行训练和评估。实验结果显示,模型在Python类别上表现最佳,C#类别表现中等,Java类别表现相对较弱。文章还提供了改进建议,如增加Java类别样本、调整特征提取方式,并指出了当前模型的局限性,如测试集样本量小和样本代表性不足。

💾 准备工作:文章首先介绍了所需的Python库,包括gensim、jieba、markdown和scikit-learn,这些库分别用于Doc2Vec模型的核心构建、中文分词、Markdown文档转换和文档相似度计算。

⚙️ 数据预处理:文章详细阐述了数据预处理的步骤,包括加载Markdown文档、去除Markdown语法、分词、去除HTML标签、去除特殊字符和数字,以及将文本转换为小写。对于中文文档,使用jieba进行分词;对于英文文档,则直接按空格分割。

💡 模型训练与评估:文章详细介绍了Doc2Vec模型的训练过程,包括设置文档向量维度、上下文窗口大小、最小词频和训练轮数等参数。此外,还介绍了如何生成文档向量,以及使用LogisticRegression分类器进行训练和评估。最终,文章给出了分类报告,分析了各类别(Python、C#、Java)的表现,并提出了改进建议。

📈 结果分析与改进:文章分析了模型的整体表现和各类别表现,准确率为77%。Python类别表现最好,C#类别表现中等,Java类别表现相对最弱。文章还提出了增加Java类别训练样本、调整特征提取方式等改进建议,并指出了测试集样本量小和样本代表性不足等限制。

准备工作

pip install gensim jieba markdown scikit-learn

步骤

    数据预处理: 加载Markdown文档并进行预处理,包括分词、去除停用词等。训练Doc2Vec模型: 使用预处理后的文档训练Doc2Vec模型,生成文档向量。相似度计算: 使用训练好的模型计算文档之间的相似度。结果展示: 展示相似度最高的文档及其相似度分数。

引入依赖

import osimport jiebaimport refrom gensim.models.doc2vec import Doc2Vec, TaggedDocumentfrom sklearn.model_selection import train_test_splitfrom sklearn.linear_model import LogisticRegressionfrom sklearn.metrics import classification_reportimport markdown

根据输入的Markdown文档目录加载和预处理文档

目录如图所示

# --- 1. 数据收集与预处理 ---def load_and_preprocess_markdown_documents(data_dir):    """    加载指定目录下所有Markdown文档,进行预处理(去除Markdown语法、分词)。    假设每个子文件夹代表一个类别。    """    documents = []    labels = []    doc_id_counter = 0    for category_name in os.listdir(data_dir):        category_path = os.path.join(data_dir, category_name)        if os.path.isdir(category_path):            print(f"Processing category: {category_name}")            for filename in os.listdir(category_path):                if filename.endswith(".md"):                    filepath = os.path.join(category_path, filename)                    with open(filepath, 'r', encoding='utf-8') as f:                        md_content = f.read()                    # 将Markdown转换为纯文本                    html = markdown.markdown(md_content)                    plain_text = re.sub('<[^<]+?>', '', html).strip() # 去除HTML标签                    # 简单的文本清理,去除特殊字符和数字,并转换为小写                    plain_text = re.sub(r'[^\w\s]', '', plain_text).lower()                    plain_text = re.sub(r'\d+', '', plain_text)                    # 中英文分词                    words = []                    if re.search(r'[\u4e00-\u9fa5]', plain_text): # 包含中文字符                        words = list(jieba.cut(plain_text))                    else: # 纯英文                        words = plain_text.split()                    # 过滤空字符串                    words = [word for word in words if word.strip()]                    if words:                        documents.append(TaggedDocument(words=words, tags=[f'DOC_{doc_id_counter}']))                        labels.append(category_name)                        doc_id_counter += 1    return documents, labels

模型训练

# --- 2. Doc2Vec模型训练 ---def train_doc2vec_model(tagged_documents, vector_size=100, window=5, min_count=1, epochs=20):    """    训练Doc2Vec模型。    """    print("Training Doc2Vec model...")    model = Doc2Vec(vector_size=vector_size, window=window, min_count=min_count, workers=4, epochs=epochs)    model.build_vocab(tagged_documents)    model.train(tagged_documents, total_examples=model.corpus_count, epochs=model.epochs)    print("Doc2Vec model training complete.")    return model

生成文档向量并训练分类器

# --- 3. 文档向量生成 ---def get_document_vectors(model, tagged_documents):    """    从训练好的Doc2Vec模型中获取每个文档的向量。    """    doc_vectors = []    for doc in tagged_documents:        doc_vectors.append(model.dv[doc.tags[0]]) # 获取通过tag训练的向量    return doc_vectors# --- 4. 分类器训练 ---def train_classifier(X_train, y_train):    """    训练一个分类器。    """    print("Training classifier...")    classifier = LogisticRegression(max_iter=1000) # 增加max_iter以避免收敛警告    classifier.fit(X_train, y_train)    print("Classifier training complete.")    return classifier

开始训练并评估

# --- 主训练流程 ---if __name__ == "__main__":        training_data_dir = 'data/training_docs' # 请替换为您的实际数据目录    print("--- Step 1: Loading and Preprocessing Documents ---")    all_tagged_documents, all_labels = load_and_preprocess_markdown_documents(training_data_dir)    if not all_tagged_documents:        print("No documents found or processed. Please check your data directory.")    else:        # 划分训练集和测试集 (用于分类器,而非Doc2Vec本身)        # Doc2Vec训练需要所有文档,但分类器需要独立测试集来评估性能        X_train_docs, X_test_docs, y_train, y_test = train_test_split(            all_tagged_documents, all_labels, test_size=0.4, random_state=42, stratify=all_labels        )        print(f"Total documents: {len(all_tagged_documents)}")        print(f"Training documents for classifier: {len(X_train_docs)}")        print(f"Testing documents for classifier: {len(X_test_docs)}")        # Doc2Vec训练使用所有文档,因为它学习的是文档的表示        print("\n--- Step 2: Training Doc2Vec Model ---")        doc2vec_model = train_doc2vec_model(all_tagged_documents, vector_size=150, epochs=30) # 增加向量维度和训练轮数        # 保存Doc2Vec模型,以便后续加载和使用        doc2vec_model_path = 'doc2vec_programming_docs.model'        doc2vec_model.save(doc2vec_model_path)        print(f"Doc2Vec model saved to {doc2vec_model_path}")        print("\n--- Step 3: Generating Document Vectors for Classifier Training ---")        # 为分类器训练集生成向量        X_train_vectors = get_document_vectors(doc2vec_model, X_train_docs)        print("\n--- Step 4: Training Classifier ---")        classifier = train_classifier(X_train_vectors, y_train)        # 保存分类器模型        import joblib        classifier_model_path = 'document_classifier.joblib'        joblib.dump(classifier, classifier_model_path)        print(f"Classifier model saved to {classifier_model_path}")        print("\n--- Step 5: Evaluating Classifier on Test Set ---")        X_test_vectors = get_document_vectors(doc2vec_model, X_test_docs)        y_pred = classifier.predict(X_test_vectors)        print("\nClassification Report:")        print(classification_report(y_test, y_pred))

运行结果如下:

    整体表现 :
    各类别表现 :
    改进建议 :
    当前限制 :

根据AI的分析,可以看出我们仍需要更多的样本数据来改进这个简单的编程语言分类模型。

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

Doc2Vec 文档分类 机器学习 自然语言处理
相关文章