还是同前一篇作为学习入门。

1. KNN算法描述:

step1: 文本向量化表示,计算特征词的TF-IDF值

step2: 新文本到达后,根据特征词确定文本的向量

step3 : 在训练文本集中选出与新文本向量最相近的k个文本向量,相似度度量采用“余弦相似度”,根据实验测试的结果调整k值,此次选择20

step4: 在新文本的k个邻居中,依次计算每类的权重,

step5: 比较类的权重,将新文本放到权重最大的那个类中

2. 文档TF-IDF计算和向量化表示

# -*- coding: utf-8 -*-
import time
from os import listdir
from math import log
from numpy import *
from numpy import linalg
from operator import itemgetter###################################################
## 计算所有单词的IDF值
###################################################
def computeIDF():fileDir = 'processedSampleOnlySpecial_2'wordDocMap = {}  # <word, set(docM,...,docN)>IDFPerWordMap = {}  # <word, IDF值>countDoc = 0.0cateList = listdir(fileDir)for i in range(len(cateList)):sampleDir = fileDir + '/' + cateList[i]sampleList = listdir(sampleDir)for j in range(len(sampleList)):sample = sampleDir + '/' + sampleList[j]for line in open(sample).readlines():word = line.strip('\n')if word in wordDocMap.keys():wordDocMap[word].add(sampleList[j]) # set结构保存单词word出现过的文档else:wordDocMap.setdefault(word,set())wordDocMap[word].add(sampleList[j])print 'just finished %d round ' % ifor word in wordDocMap.keys():countDoc = len(wordDocMap[word]) # 统计set中的文档个数IDF = log(20000/countDoc)/log(10)IDFPerWordMap[word] = IDFreturn IDFPerWordMap###################################################
## 将IDF值写入文件保存
###################################################
def main():start=time.clock()IDFPerWordMap = computeIDF()end=time.clock()print 'runtime: ' + str(end-start)fw = open('IDFPerWord','w')for word, IDF in IDFPerWordMap.items():fw.write('%s %.6f\n' % (word,IDF))fw.close()########################################################
## 生成训练集和测试集的文档向量,向量形式<cate, doc, (word1, tdidf1), (word2, tdidf2),...> 存入文件
## @param indexOfSample 迭代的序号
## @param trainSamplePercent 训练集合和测试集合划分百分比
########################################################
def computeTFMultiIDF(indexOfSample, trainSamplePercent):IDFPerWord = {} # <word, IDF值> 从文件中读入后的数据保存在此字典结构中for line in open('IDFPerWord').readlines():(word, IDF) = line.strip('\n').split(' ')IDFPerWord[word] = IDF        fileDir = 'processedSampleOnlySpecial_2'trainFileDir = "docVector/" + 'wordTFIDFMapTrainSample' + str(indexOfSample)testFileDir = "docVector/" + 'wordTFIDFMapTestSample' + str(indexOfSample)tsTrainWriter = open(trainFileDir, 'w')tsTestWriter = open(testFileDir, 'w')cateList = listdir(fileDir)for i in range(len(cateList)):sampleDir = fileDir + '/' + cateList[i]sampleList = listdir(sampleDir)testBeginIndex = indexOfSample * ( len(sampleList) * (1-trainSamplePercent) )testEndIndex = (indexOfSample+1) * ( len(sampleList) * (1-trainSamplePercent) )for j in range(len(sampleList)):TFPerDocMap = {} # <word, 文档doc下该word的出现次数>sumPerDoc = 0  # 记录文档doc下的单词总数sample = sampleDir + '/' + sampleList[j]for line in open(sample).readlines():sumPerDoc += 1word = line.strip('\n')TFPerDocMap[word] = TFPerDocMap.get(word, 0) + 1if(j >= testBeginIndex) and (j <= testEndIndex):tsWriter = tsTestWriterelse:tsWriter = tsTrainWritertsWriter.write('%s %s ' % (cateList[i], sampleList[j])) # 写入类别cate,文档docfor word, count in TFPerDocMap.items():TF = float(count)/float(sumPerDoc)tsWriter.write('%s %f ' % (word, TF * float(IDFPerWord[word]))) # 继续写入类别cate下文档doc下的所有单词及它的TF-IDF值
tsWriter.write('\n')print 'just finished %d round ' % i#if i==0: break
tsTrainWriter.close()tsTestWriter.close()tsWriter.close()

3. KNN算法的实现

def doProcess():trainFiles = 'docVector/wordTFIDFMapTrainSample0'testFiles = 'docVector/wordTFIDFMapTestSample0'kNNResultFile = 'docVector/KNNClassifyResult'trainDocWordMap = {}  # 字典<key, value> key=cate_doc, value={{word1,tfidf1}, {word2, tfidf2},...}for line in open(trainFiles).readlines():lineSplitBlock = line.strip('\n').split(' ')trainWordMap = {}m = len(lineSplitBlock)-1for i in range(2, m, 2):  # 在每个文档向量中提取(word, tfidf)存入字典trainWordMap[lineSplitBlock[i]] = lineSplitBlock[i+1]temp_key = lineSplitBlock[0] + '_' + lineSplitBlock[1]  # 在每个文档向量中提取类目cate,文档doc,trainDocWordMap[temp_key] = trainWordMap testDocWordMap = {}for line in open(testFiles).readlines():lineSplitBlock = line.strip('\n').split(' ')testWordMap = {} m = len(lineSplitBlock)-1for i in range(2, m, 2):testWordMap[lineSplitBlock[i]] = lineSplitBlock[i+1]temp_key = lineSplitBlock[0] + '_' + lineSplitBlock[1]testDocWordMap[temp_key] = testWordMap #<类_文件名,<word, TFIDF>>#遍历每一个测试样例计算与所有训练样本的距离,做分类count = 0rightCount = 0KNNResultWriter = open(kNNResultFile,'w')for item in testDocWordMap.items():classifyResult = KNNComputeCate(item[0], item[1], trainDocWordMap)  # 调用KNNComputeCate做分类
count += 1print 'this is %d round' % countclassifyRight = item[0].split('_')[0]KNNResultWriter.write('%s %s\n' % (classifyRight,classifyResult))if classifyRight == classifyResult:rightCount += 1print '%s %s rightCount:%d' % (classifyRight,classifyResult,rightCount)accuracy = float(rightCount)/float(count)print 'rightCount : %d , count : %d , accuracy : %.6f' % (rightCount,count,accuracy)return accuracy#########################################################
## @param cate_Doc 测试集<类别_文档>
## @param testDic 测试集{{word, TFIDF}}
## @param trainMap 训练集<类_文件名,<word, TFIDF>>
## @return sortedCateSimMap[0][0] 返回与测试文档向量距离和最小的类
#########################################################
def KNNComputeCate(cate_Doc, testDic, trainMap):simMap = {} #<类目_文件名,距离> 后面需要将该HashMap按照value排序for item in trainMap.items():similarity = computeSim(testDic,item[1])  # 调用computeSim()simMap[item[0]] = similaritysortedSimMap = sorted(simMap.iteritems(), key=itemgetter(1), reverse=True) #<类目_文件名,距离> 按照value排序
k = 20cateSimMap = {} #<类,距离和>for i in range(k):cate = sortedSimMap[i][0].split('_')[0]cateSimMap[cate] = cateSimMap.get(cate,0) + sortedSimMap[i][1]sortedCateSimMap = sorted(cateSimMap.iteritems(),key=itemgetter(1),reverse=True)return sortedCateSimMap[0][0]   #################################################
## @param testDic 一维测试文档向量<<word, tfidf>>
## @param trainDic 一维训练文档向量<<word, tfidf
## @return 返回余弦相似度
def computeSim(testDic, trainDic):testList = []  # 测试向量与训练向量共有的词在测试向量中的tfidf值trainList = []  # # 测试向量与训练向量共有的词在训练向量中的tfidf值for word, weight in testDic.items():if trainDic.has_key(word):testList.append(float(weight)) # float()将字符型数据转换成数值型数据,参与下面运算trainList.append(float(trainDic[word]))testVect = mat(testList)  # 列表转矩阵,便于下面向量相乘运算和使用Numpy模块的范式函数计算trainVect = mat(trainList)num = float(testVect * trainVect.T)denom = linalg.norm(testVect) * linalg.norm(trainVect)#print 'denom:%f' % denomreturn float(num)/(1.0+float(denom))

输出结果:

运行时遇到几种语法错误:

Error1:

split(' ')按空格分割后最后一位是空串,不检查分割后数组的最后一位很难发现,以致产生越界

Error2:

因为导入数据用字符串运算strip切分后,返回的都是字符型数据,而string不能计算,需int(string) float(string)转换后参与计算,错误如下:

Error3:

sorted()对字典中每对<key, value>数据进行排序,返回的是包含tuple(key, value)的列表,之前不了解这一点,出现了index的错误:

sorted()的返回形式:

转载于:https://www.cnblogs.com/ffan/p/4043562.html

基于KNN的newsgroup 18828文本分类器的Python实现相关推荐

  1. 【Python】基于kNN算法的手写识别系统的实现与分类器测试

    基于kNN算法的手写识别系统 1.      数据准备 使用windows画图工具,手写0-9共10个数字,每个数字写20遍,共200个BMP文件. 方法如下,使用画图工具,打开网格线,调整像素为32 ...

  2. 基于 KNN 和 人体关键点的动作分类 - Pose classification

    动作分类 0. 摘要 1. 介绍 1.1 KNN 2. 代码 2.1 安装 MediaPipe 环境 2.2 训练数据 3. 实验 3.1 生成训练数据结果 3.2 根据训练集的样本来预测测试视频的动 ...

  3. 基于KNN算法的手写体数字识别

    基于KNN算法的手写体数字识别 KNN分类算法是一种经典的分类算法,属于懒惰学习算法的一种. 1.算法原理 工作原理:存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道 ...

  4. 基于统计概率和机器学习的文本分类技术

    基于统计概率和机器学习的文本分类技术 -- 社区产品机器审核机制 一.现状 目前,所在公司社区类产品(论坛.博客.百科)每天都会接收到大量的垃圾.灌水信息,高峰期16小时内(晚6点以后到第二天9点前) ...

  5. Python 计算机视觉(十七)—— 基于KNN的图像分类

    参考的一些文章以及论文我都会给大家分享出来 -- 链接就贴在原文,论文我上传到资源中去,大家可以免费下载学习,如果当天资源区找不到论文,那就等等,可能正在审核,审核完后就可以下载了.大家一起学习,一起 ...

  6. 朴素贝叶斯网络matlab实现_基于朴素贝叶斯的文本分类方法实战

    基于朴素贝叶斯的文本分类方法 一.朴素贝叶斯原理的介绍 二.朴素贝叶斯分类器的代码实现 分类器有时会产生错误结果,这时可以要求分类器给出一个最优的类别猜测结果,同时会给出这个猜测的概率估计值.朴素贝叶 ...

  7. 产品级垃圾文本分类器

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx 任务场景 文本反垃圾是网络社区应用非常常见的任务.因为各种利益关系,网络社区通常都难以避免地会 ...

  8. 文本分类器,可自由加载BERT、Bert-wwm、Roberta、ALBert以及ERNIE1.0

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx 基于谷歌开源的BERT编写的文本分类器(基于微调方式),可自由加载NLP领域知名的预训练语言模 ...

  9. (5)【整合】基于机器学习的酒店评论文本倾向性分析

    酒店评论情感分析系统(五)-- [整合]基于机器学习的酒店评论文本倾向性分析 本文主要是对之前的第三.四节所介绍的各分块进行整合. 流程: 对GUI界面输入的评论文本,先进行中文分词和去停用词,然后再 ...

最新文章

  1. Hyper-v 3.0虚拟化平台群集共享磁盘无法failover的故障
  2. 网页中Google Map的使用
  3. SAP SD基础知识之现金销售
  4. vivo Y93s的USB调试模式在哪里,打开vivo Y93sUSB调试模式的步骤
  5. spring获取bean的方案
  6. 使用 Google Calendar 免费自动发送手机短信、Email 的方法
  7. linux命令行引导iso,如何在Linux上使用命令行从可启动ISO创建可启动USB?
  8. 图文并茂的带你彻底理解悲观锁与乐观锁
  9. android edittext不可复制_精选Android中高级面试题:性能优化,JNI,设计模式
  10. 从零开始学习Oracle—安装及删除
  11. 使用JGit API探索Git内部
  12. WebView 和JS 之间交互
  13. 10、并发容器,ConcurrentHashMap
  14. Being a Good Boy in Spring Festival【博弈】
  15. Mac上QQ音乐无损保存音频方法
  16. IRS2110S+IGBT半桥驱动调试问题记录
  17. 雷蛇鼠标:单机偶尔变成双击
  18. 张国荣一生57部电影海报全集
  19. 卫星移动通信现状与未来发展
  20. 【DockerCE】RHEL 7.9完整安装DockerCE 20.10.5的包集合

热门文章

  1. [论文笔记]如何通过加package cap有效减少GPU的droop noise
  2. python自动化办公之python操作PPT
  3. 基于百度EasyDL定制化图像识别平台的海洋鱼类识别方法
  4. 11种提升抖音直播间人气玩法
  5. 七首爱情诗词:愿有岁月可回首,且以深情共白头
  6. 2021Autojs实战自动聊天挂机编程实战分享
  7. 关于Hadoop的杂乱无章(续更)
  8. 计算FDTD光纤耦合效率!煞费苦心熬了几个通宵!!!
  9. nginx 加载图片 nginx图片服务器
  10. 英语_长难句_语法_定语