脚本如何实现文件内容模糊粗糙贝叶斯分类器

wen 实用脚本 29

本文目录导读:

脚本如何实现文件内容模糊粗糙贝叶斯分类器

  1. 安装依赖
  2. 核心特性
  3. 使用方法
  4. 参数调优建议

模糊分类器,这是一个完整的Python实现:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""模糊朴素贝叶斯分类器
用于对文本文件内容进行分类
"""
import os
import re
import math
import pickle
from collections import defaultdict, Counter
from typing import Dict, List, Tuple, Optional
import chardet
class FuzzyNaiveBayesClassifier:
    """模糊朴素贝叶斯分类器"""
    def __init__(self, alpha: float = 1.0):
        """
        初始化分类器
        Args:
            alpha: 拉普拉斯平滑参数,控制模糊程度
        """
        self.alpha = alpha  # 模糊程度参数
        self.classes = []  # 类别列表
        self.class_prior = {}  # 类别先验概率
        self.word_counts = defaultdict(lambda: defaultdict(float))  # 词频统计
        self.class_word_counts = defaultdict(float)  # 每个类别的总词数
        self.vocabulary = set()  # 词汇表
        self.word_weights = {}  # 词权重(用于模糊处理)
    def _preprocess_text(self, text: str) -> List[str]:
        """
        文本预处理:分词并清洗
        Args:
            text: 原始文本
        Returns:
            分词后的词列表
        """
        # 转换为小写
        text = text.lower()
        # 去除特殊字符,保留中英文和数字
        text = re.sub(r'[^\w\u4e00-\u9fff\s]', ' ', text)
        # 简单分词(按空格分割)
        words = text.split()
        # 过滤短词和数字
        words = [word for word in words if len(word) > 1 or word.isalpha()]
        return words
    def _fuzzy_tokenize(self, words: List[str], fuzziness: float = 0.3) -> List[Tuple[str, float]]:
        """
        模糊分词:为每个词添加模糊权重
        Args:
            words: 原始词列表
            fuzziness: 模糊程度 (0-1)
        Returns:
            (词, 权重) 元组列表
        """
        from random import random, uniform
        fuzzy_words = []
        for word in words:
            # 基础权重为1.0
            base_weight = 1.0
            # 添加模糊扰动
            noise = uniform(-fuzziness, fuzziness)
            weight = max(0.1, base_weight + noise)  # 确保权重不为负
            # 对长词给予更高的权重(启发式)
            if len(word) > 4:
                weight *= 1.2
            elif len(word) < 3:
                weight *= 0.8
            fuzzy_words.append((word, weight))
        return fuzzy_words
    def _calculate_word_entropy(self, word: str) -> float:
        """
        计算词的信息熵(用于模糊处理)
        Args:
            word: 词
        Returns:
            信息熵值
        """
        if word not in self.word_counts:
            return 0.0
        total = sum(self.word_counts[word].values())
        if total == 0:
            return 0.0
        entropy = 0.0
        for count in self.word_counts[word].values():
            if count > 0:
                prob = count / total
                entropy -= prob * math.log2(prob + 1e-10)
        return entropy
    def train(self, file_paths: Dict[str, List[str]]) -> None:
        """
        训练分类器
        Args:
            file_paths: 类别到文件路径列表的映射
                        {'类别1': ['file1.txt', 'file2.txt'], 
                              '类别2': ['file3.txt', 'file4.txt']}
        """
        self.classes = list(file_paths.keys())
        # 计算每个类别的文档数量
        class_doc_counts = {cls: len(paths) for cls, paths in file_paths.items()}
        total_docs = sum(class_doc_counts.values())
        # 计算先验概率
        for cls in self.classes:
            self.class_prior[cls] = math.log(class_doc_counts[cls] / total_docs)
        # 统计词频
        for cls, paths in file_paths.items():
            for file_path in paths:
                try:
                    text = self._read_file(file_path)
                    words = self._preprocess_text(text)
                    fuzzy_words = self._fuzzy_tokenize(words)
                    for word, weight in fuzzy_words:
                        self.word_counts[cls][word] += weight
                        self.class_word_counts[cls] += weight
                        self.vocabulary.add(word)
                except Exception as e:
                    print(f"读取文件 {file_path} 时出错: {e}")
        # 计算词权重(基于信息熵)
        for word in self.vocabulary:
            entropy = self._calculate_word_entropy(word)
            # 权重与信息熵成反比(熵高的词包含信息少)
            self.word_weights[word] = 1.0 / (1.0 + entropy)
    def _read_file(self, file_path: str) -> str:
        """
        读取文件内容,自动检测编码
        Args:
            file_path: 文件路径
        Returns:
            文件内容字符串
        """
        with open(file_path, 'rb') as f:
            raw_data = f.read()
        # 检测编码
        result = chardet.detect(raw_data)
        encoding = result['encoding'] if result['encoding'] else 'utf-8'
        try:
            return raw_data.decode(encoding, errors='replace')
        except:
            return raw_data.decode('utf-8', errors='replace')
    def predict(self, file_path: str, top_n: int = 3) -> List[Tuple[str, float]]:
        """
        预测文件类别
        Args:
            file_path: 待分类的文件路径
            top_n: 返回前N个可能的类别
        Returns:
            (类别, 概率) 元组列表,按概率降序排列
        """
        text = self._read_file(file_path)
        return self.predict_text(text, top_n)
    def predict_text(self, text: str, top_n: int = 3) -> List[Tuple[str, float]]:
        """
        预测文本类别
        Args:
            text: 待分类的文本
            top_n: 返回前N个可能的类别
        Returns:
            (类别, 概率) 元组列表
        """
        words = self._preprocess_text(text)
        fuzzy_words = self._fuzzy_tokenize(words)
        # 计算每个类别的后验概率
        scores = {}
        for cls in self.classes:
            # 先验概率
            score = self.class_prior[cls]
            # 条件概率
            class_total = self.class_word_counts[cls]
            vocab_size = len(self.vocabulary)
            for word, weight in fuzzy_words:
                # 添加模糊因子
                fuzzy_alpha = self.alpha * self.word_weights.get(word, 1.0)
                # 计算条件概率(使用拉普拉斯平滑)
                word_count = self.word_counts[cls].get(word, 0)
                conditional_prob = (word_count + fuzzy_alpha) / (class_total + fuzzy_alpha * vocab_size)
                # 应用词权重
                weighted_prob = conditional_prob ** weight
                score += math.log(weighted_prob + 1e-10)
            scores[cls] = score
        # 转换为概率
        total = sum(math.exp(s) for s in scores.values())
        probabilities = {cls: math.exp(s) / total for cls, s in scores.items()}
        # 排序并返回Top N
        sorted_probs = sorted(probabilities.items(), key=lambda x: x[1], reverse=True)
        return sorted_probs[:top_n]
    def save_model(self, filepath: str) -> None:
        """
        保存模型到文件
        Args:
            filepath: 模型文件路径
        """
        model_data = {
            'classes': self.classes,
            'class_prior': self.class_prior,
            'word_counts': dict(self.word_counts),
            'class_word_counts': dict(self.class_word_counts),
            'vocabulary': self.vocabulary,
            'word_weights': self.word_weights,
            'alpha': self.alpha
        }
        with open(filepath, 'wb') as f:
            pickle.dump(model_data, f)
    def load_model(self, filepath: str) -> None:
        """
        从文件加载模型
        Args:
            filepath: 模型文件路径
        """
        with open(filepath, 'rb') as f:
            model_data = pickle.load(f)
        self.classes = model_data['classes']
        self.class_prior = model_data['class_prior']
        self.word_counts = defaultdict(lambda: defaultdict(float), model_data['word_counts'])
        self.class_word_counts = defaultdict(float, model_data['class_word_counts'])
        self.vocabulary = model_data['vocabulary']
        self.word_weights = model_data['word_weights']
        self.alpha = model_data['alpha']
# 使用示例
def create_demo_data():
    """创建演示数据"""
    import tempfile
    demo_files = {
        '技术': [],
        '体育': [],
        '娱乐': []
    }
    # 创建临时文件
    for category, texts in [
        ('技术', [
            '人工智能和机器学习正在改变世界,深度学习算法可以处理大量数据',
            '计算机编程需要掌握多种语言和框架,算法和数据结构很重要',
            '云计算和大数据技术正在推动数字化转型,网络安全不容忽视'
        ]),
        ('体育', [
            '足球比赛中有11名球员,篮球是5对5的团队运动',
            '奥运会上有各种体育项目,运动员们为金牌而努力拼搏',
            '健身和运动对健康很重要,训练需要持之以恒'
        ]),
        ('娱乐', [
            '电影和音乐是人们喜爱的娱乐方式,新的作品不断涌现',
            '游戏产业正在快速发展,电子竞技吸引了大量观众',
            '综艺节目和电视剧丰富了人们的休闲生活'
        ])
    ]:
        for i, text in enumerate(texts):
            # 创建临时文件
            with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
                f.write(text)
                file_path = f.name
            demo_files[category].append(file_path)
    return demo_files
def main():
    """主函数"""
    print("=" * 60)
    print("模糊朴素贝叶斯分类器示例")
    print("=" * 60)
    # 创建演示数据
    print("\n[1] 创建演示数据...")
    train_files = create_demo_data()
    # 初始化分类器
    print("[2] 初始化分类器...")
    classifier = FuzzyNaiveBayesClassifier(alpha=0.5)  # 较低的alpha值表示较少的模糊
    # 训练模型
    print("[3] 训练模型...")
    classifier.train(train_files)
    print(f"    类别: {classifier.classes}")
    print(f"    词汇表大小: {len(classifier.vocabulary)}")
    # 测试分类
    print("\n[4] 测试分类...")
    test_texts = [
        "Python编程语言有很多应用,包括数据分析",
        "足球明星C罗再次打破纪录",
        "最新上映的电影票房很高",
        "人工智能在医疗领域的应用"
    ]
    for text in test_texts:
        print(f"\n    文本: '{text}'")
        results = classifier.predict_text(text, top_n=3)
        print(f"    分类结果:")
        for category, prob in results:
            print(f"      - {category}: {prob:.2%}")
    # 保存和加载模型
    print("\n[5] 保存模型...")
    classifier.save_model("fuzzy_bayes_model.pkl")
    print("[6] 加载模型...")
    new_classifier = FuzzyNaiveBayesClassifier()
    new_classifier.load_model("fuzzy_bayes_model.pkl")
    # 验证加载的模型
    print("[7] 验证加载的模型...")
    test_text = "云计算技术不断发展"
    results = new_classifier.predict_text(test_text)
    print(f"    文本: '{test_text}'")
    for category, prob in results:
        print(f"      - {category}: {prob:.2%}")
    print("\n" + "=" * 60)
    print("分类器使用完毕!")
    print("=" * 60)
if __name__ == "__main__":
    main()

安装依赖

pip install chardet

核心特性

模糊处理机制

  • alpha 参数控制平滑程度
  • _fuzzy_tokenize() 为词添加随机权重
  • 基于信息熵的动态词权重

文件处理

  • 自动检测文件编码
  • 中英文混合文本支持
  • 批量文件训练

高级功能

  • 模型保存/加载
  • 概率输出
  • Top-N 分类结果

使用方法

# 基本使用
classifier = FuzzyNaiveBayesClassifier(alpha=0.5)
# 训练数据(文件路径)
train_data = {
    '类别1': ['file1.txt', 'file2.txt'],
    '类别2': ['file3.txt', 'file4.txt']
}
classifier.train(train_data)
# 分类新文件
result = classifier.predict('new_file.txt')
for category, prob in result:
    print(f"{category}: {prob:.2%}")

参数调优建议

  • alpha (0.1-1.0): 控制模糊程度,值越小分类越严格
  • fuzziness (0.1-0.5): 词权重扰动范围
  • top_n: 返回结果数量

这个分类器实现了文件内容的模糊分类,特别适合处理噪声较大的文本数据。

抱歉,评论功能暂时关闭!