机器学习文本分类复现配套B站逐行讲解(含代码数据集)

B站资料
对着这个up的资料学习一遍,
他的GitHub

机器学习文本分类~
这个是 贝叶斯的,
之前在B站学过knn的,
联想之前自己的毕设 所有的机器学习模型都用到过。
参考自己以前写过各种机器学习算法的优缺点
然后把原理弄懂,都做一个文本分类模型。

具体的代码在知乎

复现知乎大佬一步到位给出了多种机器学习方法

手把手教你在Python中实现文本分类(附代码、数据集) - 清华大学大数据研究中心的文章 - 知乎
https://zhuanlan.zhihu.com/p/37157010

但是这个是英文的数据集,现在开始复现,

from sklearn import model_selection, preprocessing, linear_model, naive_bayes, metrics, svm
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn import decomposition, ensemble

import pandas, xgboost, numpy, textblob, string
from keras.preprocessing import text, sequence
from keras import layers, models, optimizers

一开始一直复现不了,是因为这个引用包的顺序不对。
preprocessing 这个引用出现了两次才是重点!!!!
但其实真正用到的是

from sklearn import model_selection, preprocessing

这句话里面的代码, 把另一个 preprocessing去掉之后 能正常使用了。
在这里插入图片描述
如图报错 所以注释掉第二行的导包!!
这样就不会冲突了。
底层逻辑是因为
在这里插入图片描述
fit_transform
这个类看不懂又去搜了一下。

总的一句话就是 去重+索引。

python掉包的优先级,多个from 优先调用 第一列的包,其次才是第二列,第三列。
所以优先调用注释掉的包会导致bug。
fit_transform就是将序列重新排列后再进行标准化,
这个重新排列可以把它理解为查重加升序,像下面的序列,经过重新排列后可以得到:array([1,3,7])
而这个新的序列的索引是 0:1, 1:3, 2:7,这个就是fit的功能
所以transform根据索引又产生了一个新的序列,于是便得到array([0, 1, 1, 2, 1, 0])
这个序列是这样来的
————————————————
版权声明:本文为CSDN博主「皮卡丘黄了吧唧丿」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_47125742/article/details/115449648

这是一个svm算法的文本四分类

这个已经复现过了在B站做了视频

在这里插入图片描述
所以说我决定先把这个搞懂,之后再去看知乎那一篇,试着换成中文看看。
接下来复现 这个大佬的,私聊要到了源码(数据放在百度网盘了)。

有部分看不懂的结合B站的视频,明天互补一下弄懂。
他的代码

#!D:/workplace/python
# -*- coding: utf-8 -*-
# @File  : TFIDF_svm_wy.py
# @Author: WangYe
# @Date  : 2020/11/29
# @Software: PyCharm
# 机器学习之文本分类(附带训练集+数据集+所有代码)
# 博客链接:https://blog.csdn.net/qq_28626909/article/details/80382029
from sklearn.multiclass import OneVsRestClassifier  #结合SVM的多分类组合辅助器
import sklearn.svm as svm  #SVM辅助器
import jieba
from numpy import *
import os
from sklearn.feature_extraction.text import TfidfTransformer  # TF-IDF向量转换类
 
from sklearn.feature_extraction.text import CountVectorizer   #词频矩阵
 
 
def readFile(path):
    with open(path, 'r', errors='ignore',encoding='gbk') as file:  # 文档中编码有些问题,所有用errors过滤错误
        content = file.read()
        file.close()
        return content
 
 
def saveFile(path, result):
    with open(path, 'w', errors='ignore',encoding='gbk') as file:
        file.write(result)
        file.close()
 
 
def segText(inputPath):
    data_list = []
    label_list = []
    fatherLists = os.listdir(inputPath)  # 主目录
    for eachDir in fatherLists:  # 遍历主目录中各个文件夹
        eachPath = inputPath +"/"+ eachDir + "/"  # 保存主目录中每个文件夹目录,便于遍历二级文件
        childLists = os.listdir(eachPath)  # 获取每个文件夹中的各个文件
        for eachFile in childLists:  # 遍历每个文件夹中的子文件
            eachPathFile = eachPath + eachFile  # 获得每个文件路径
            content = readFile(eachPathFile)  # 调用上面函数读取内容
            result = (str(content)).replace("\r\n", "").strip()  # 删除多余空行与空格
            cutResult = jieba.cut(result)  # 默认方式分词,分词结果用空格隔开
            # print( " ".join(cutResult))
            label_list.append(eachDir)
            data_list.append(" ".join(cutResult))
    return  data_list,label_list
 
def getStopWord(inputFile):
    stopWordList = readFile(inputFile).splitlines()
    return stopWordList
 
 
def getTFIDFMat(train_data,train_label, stopWordList):  # 求得TF-IDF向量
    class0 = ''
    class1 = ''
    class2 = ''
    class3 = ''
    for num in range(len(train_label)):
        if train_label[num]=='体育':
            class0 = class0 + train_data[num]
        elif train_label[num]=='女性':
            class1 = class1 + train_data[num]
        elif train_label[num]=='文学出版':
            class2 = class2+ train_data[num]
        elif train_label[num]=='校园':
            class3 = class3 + train_data[num]
    train = [class0,class1,class2,class3]
    vectorizer = CountVectorizer(stop_words=stopWordList, min_df=0.5)  # 其他类别专用分类,该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
    transformer = TfidfTransformer()  # 该类会统计每个词语的tf-idf权值
    cipin = vectorizer.fit_transform(train)
    tfidf = transformer.fit_transform(cipin)  # if-idf中的输入为已经处理过的词频矩阵
    model = OneVsRestClassifier(svm.SVC(kernel='linear'))
    train_cipin = vectorizer.transform(train_data)
    train_arr = transformer.transform(train_cipin)
    clf = model.fit(train_arr, train_label)
 
    while 1:
        print('请输入需要预测的文本:')
        a = input()
        sentence_in = [' '.join(jieba.cut(a))]
        b = vectorizer.transform(sentence_in)
        c = transformer.transform(b)
        prd = clf.predict(c)
        print('预测类别:',prd[0])
#
if __name__ == '__main__':
    data,label = segText('data')
    stopWordList = getStopWord('stop/stopword.txt')  # 获取停用词表
    getTFIDFMat(train_data=data,train_label=label,stopWordList=stopWordList)

下面这些不是很懂,仔细研究一下。

下面代码关于前几行的解释

vectorizer = CountVectorizer(stop_words=stopWordList, min_df=0.5)  # 其他类别专用分类,该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
    transformer = TfidfTransformer()  # 该类会统计每个词语的tf-idf权值
    cipin = vectorizer.fit_transform(train)
    tfidf = transformer.fit_transform(cipin)  # if-idf中的输入为已经处理过的词频矩阵
    model = OneVsRestClassifier(svm.SVC(kernel='linear'))
    train_cipin = vectorizer.transform(train_data)
    train_arr = transformer.transform(train_cipin)
    clf = model.fit(train_arr, train_label)

还有一些需要研究一下第三方的库的方法,然后逐行解释。
里面用到的两个主要的类详细讲解。

这篇很详细了,具体的运行代码也给出来了,

然后打印实际测试的结果。文章里面也给到了。
唯一美中不足的的是,
他分的特征词 把单个字去掉了。。。。

搞懂前几行 ,就只剩下最后训练的这几行了。

model = OneVsRestClassifier(svm.SVC(kernel='linear'))
    train_cipin = vectorizer.transform(train_data)
    train_arr = transformer.transform(train_cipin)

model那行好理解,

下面的vectorizer.transform类是干嘛的呢?
本身的解释:

类 CountVectorizer def 转换(self,raw _ document: Any)-> 将任何转换文档转换为文档术语矩阵。

import jieba
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer

corpus = ["我 来到 北京 清华大学",  # 第一类文本切词后的结果,词之间以空格隔开
          "他 来到 了 网易 杭研 大厦",  # 第二类文本的切词结果
          "小明 硕士 毕业 于 中国 科学院",  # 第三类文本的切词结果
          "我 爱 北京 天安门"]  # 第四类文本的切词结果

vectorizer = CountVectorizer()  # 该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频

transformer = TfidfTransformer()  # 该类会统计每个词语的tf-idf权值
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))  # 第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵
print(corpus[0])
sentence_in = [' '.join(jieba.cut(corpus[0]))]
b = vectorizer.transform(sentence_in)
print(b)
#b = vectorizer.transform(corpus[0])
# print((vectorizer.fit_transform(corpus)).toarray())
# print(tfidf)
word = vectorizer.get_feature_names()  # 获取词袋模型中的所有词语
print(word)

运行结果的截图能很好地说明问题:
在这里插入图片描述

从结果来看就是去掉了单个的字,之后第一列是列表索引,第二列是 在总词语中出现的位置,
第三列是 在总文档中出现了多少次。
最后一行就代表tf-idf的值了。
代码和截图如下:

import jieba
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer

corpus = ["我 来到 北京 清华大学",  # 第一类文本切词后的结果,词之间以空格隔开
          "他 来到 了 网易 杭研 大厦",  # 第二类文本的切词结果
          "小明 硕士 毕业 于 中国 科学院",  # 第三类文本的切词结果
          "我 爱 北京 天安门"]  # 第四类文本的切词结果

vectorizer = CountVectorizer()  # 该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频

transformer = TfidfTransformer()  # 该类会统计每个词语的tf-idf权值
tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))  # 第一个fit_transform是计算tf-idf,第二个fit_transform是将文本转为词频矩阵
print(corpus[0])
sentence_in = [' '.join(jieba.cut(corpus[0]))]
#计算词频
b = vectorizer.transform(sentence_in)
print(b)
#计算tf-idf
c = transformer.transform(b)
print(c)
#b = vectorizer.transform(corpus[0])
# print((vectorizer.fit_transform(corpus)).toarray())
# print(tfidf)
word = vectorizer.get_feature_names()  # 获取词袋模型中的所有词语
print(word)
#
# weight = tfidf.toarray()  # 将tf-idf矩阵抽取出来,元素a[i][j]表示j词在i类文本中的tf-idf权重
# for i in range(len(weight)):  # 打印每类文本的tf-idf词语权重,第一个for遍历所有文本,第二个for便利某一类文本下的词语权重
#     print("-------这里输出第", i, "类文本的词语tf-idf权重------")
#     for j in range(len(word)):
#         print(word[j], weight[i][j])
# print(weight)

在这里插入图片描述

但是有个小问题,我要编码的文本动词非常重要,默认单个字不会切分出来。

这篇很好的解决了问题

from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer(min_df=1)

corpus = ['This is the first document.',
          'This is the second second document.',
          'And the third one.',
          'Is this the first document?',
          ]
X = vectorizer.fit_transform(corpus)
feature_name = vectorizer.get_feature_names()

print(X)
print(feature_name)
print(X.toarray())

在这里插入图片描述
这个列表的意思就是 第一列表示 字典的索引,行顺序 表示 字典第一个元素的词语顺序,
所以与之对应的 第二列表示 词语顺序在字典中所在的位置
那么第三列 就表示词频,
这篇文章说的很清楚

复现知乎的中文数据

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方-教育技术博主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值