# 文本分析项目实战
# 背景:根据新闻文本中的内容,进行文本预处理,建模操作,从而可以自动将新闻划分到最
# 可能的类别中,节省人力资源。
# 具体实现内容:
# 能够对文本数据进行预处理【文本清洗(正则),分词(jieba),去除停用词,文本向量化(TfidfVectorizer)】
# 能够通过统计词频,生成词云图。【描述性统计分析】 chain,counter。 哪个词出现多,在这一部实现。
# 能够通过方差分析,进行特征选择【验证性统计分析】 f_classif,SelectKBest. 这两个类应该是基友吧。词袋模型的特征太多了。
# 文本向量化 TfidfVectorizer
# 特征筛选 f_classif,SelectKBest --> 拿到筛选后的 X
# 能够根据文本内容,对文本数据进行分类。【统计建模】
# 筛选后的X 就是数据源,用不同算法(KNN,贝叶斯)进行验证,选择较好的算法。
# 会用到网格搜索 GridSearchCV
# from itertools import chain
# 将多个迭代器作为参数, 但只返回单个迭代器,
# 它产生所有参数迭代器的内容, 就好像他们是来自于一个单一的序列.
# from collections import Counter
# Dict subclass for counting hashable items. Sometimes called a bag
# or multiset. Elements are stored as dictionary keys and their counts
# are stored as dictionary values.
# 停止词/停用词 stopword
# 正则表达式
# 正则表达式可以完成模糊匹配,非常灵活。这一点,特别适合处理文本数据的筛选等相关工作
# 正则表达式(regular expression)是使用单个字符串来描述、匹配一系列符合某种句法规则的字符串。在日常编程及数据处理过程中,我们会遇到许多
# 文本或字符串形式的数据及对其匹配、查找、替换等方面的需求。例如,检测用户输入的电话、邮箱等信息是否有效或符合规范;从网页中过滤筛选并提取
# 所需的特定信息又称爬虫;批量提取或替换有规律的字符串等等。面对这些需求,使用多条逻辑判断对文本进行分析耗时耗力,正则表达式可以方便快捷地
# 文本中找出满足你想要的格式的字符串,助力对文本数据的过滤清洗及分析。
# 结构化数据与非结构化数据
# 相对于结构化数据(即行数据,存储在数据库里,可以用二维表结构来逻辑表达实现的数据)而言,不方便用数据库二维逻辑表来表现的数据即称为
# 非结构化数据,包括所有格式的办公文档、文本、图片、XML、HTML、各类报表、图像和音频/视频信息等等。
# 除了存储在关系数据库和存储在一个关系数据库之外的明显区别之外,最大的区别在于分析结构化数据与非结构化数据的便利性。针对结构化数据存在成熟的
# 分析工具,但用于挖掘非结构化数据的分析工具正处于萌芽和发展阶段。
# 用户可以通过文本非结构化数据运行简单的内容搜索。但是,缺乏有序的内部结构使得传统数据挖掘工具的目标失败,企业从富有价值的数据源
# (如媒体、网络、博客、客户交互,以及社交媒体数据)获得的价值很小。即使非结构化数据分析工具在市场上出现,但没有任何一个供应商或工具集是
# 明确的赢家。许多客户不愿意投资于具有不确定发展路线图的分析工具。
# 除此之外,非结构化数据比结构化数据要多得多。非结构化数据占企业数据的80%以上,并且以每年55%和65%的速度增长。如果没有工具来分析这些海量数据,
# 组织会在商业智能表上留下大量有价值的数据。
# 传统上,结构化数据对大数据应用程序来说更容易消化,但如今的数据分析解决方案正在这方面取得重大进展。
# 可以使用新工具分析非结构化数据,特别是给定用例参数。大多数这些工具都基于机器学习。结构化数据分析也可以使用机器学习,但海量数据和许多不同
# 类型的非结构化数据都需要它。
# 几年前,使用关键字和关键短语的分析人员可以搜索非结构化数据,并对数据涉及的内容有一个清晰的概念。电子发现是这种方法的主要例子。但是,非结构化
# 数据的增长速度非常快,以至于用户不仅需要采用计算工作的分析,而且还要自动从他们的活动和用户决策中学习。自然语言处理(NLP)、模式感知和分类以及
# 文本挖掘算法都是常见的例子,文档相关性分析、情感分析和过滤器驱动的网页收集也是常见的例子。
# F分布
# 它是一种非对称分布,有两个自由度,且位置不可互换。F分布有着广泛的应用,如在方差分析、回归方程的显著性检验中都有着重要的地位
# 方差分析
# 方差分析(Analysis of Variance,简称ANOVA),又称“变异数分析”,是R.A.Fisher发明的,用于两个及两个以上样本均数差别的显著性检验。
# 由于各种因素的影响,研究所得的数据呈现波动状。造成波动的原因可分成两类,一是不可控的随机因素,另一是研究中施加的对结果形成影响的
# 可控因素。
# 原理
# 方差分析的基本原理是认为不同处理组的均数间的差别基本来源有两个:
# (1) 实验条件,即不同的处理造成的差异,称为组间差异。用变量在各组的均值与总均值之偏差平方和的总和表示,记作SSb,组间自由度dfb。
# (2) 随机误差,如测量误差造成的差异或个体间的差异,称为组内差异,用变量在各组的均值与该组内变量值之偏差平方和的总和表示, 记作SSw,
# 组内自由度dfw。
# 总偏差平方和 SSt = SSb + SSw。
# 组内SSw、组间SSb除以各自的自由度(组内dfw =n-m,组间dfb=m-1,其中n为样本总数,m为组数),得到其均方MSw和MSb,一种情况是处理没有作用,
# 即各组样本均来自同一总体,MSb/MSw≈1。另一种情况是处理确实有作用,组间均方是由于误差与不同处理共同导致的结果,即各样本来自不同总体。
# 那么,MSb>>MSw(远远大于)。
# MSb/MSw比值构成F分布。用F值与其临界值比较,推断各样本是否来自相同的总体。
# 方差分析的基本思想是:通过分析研究不同来源的变异对总变异的贡献大小,从而确定可控因素对研究结果影响力的大小。
# 若F值接近1,则说明各组均值间的差异没有统计学意义,若F值远大于1,则说明各组均值间的差异有统计学意义
# 画图预处理
# plt.rcParams['font.family'] = 'SimHei'
# plt.rcParams['axes.unicode_minus'] = False
# plt.rcParams['font.size'] = 15
# 文本数据预处理
# 缺失值的处理
# fillna(mean,bfill,0) 一般用于数值型
# df.loc[x,y] = 文本型
# data_null = data[data['content'].isnull()]
# index = data_null.index
# data.loc[index,'content'] = data_null['headline'] # 对DataFrame 赋值过程中,有两点需要注意。1) 选择用 loc[x,y] 而不要用 loc[x][y],
# # 后面一种赋值有可能不成功。2) 通过布尔值索引出来是个视图,无法直接改。最好通过copy下,然后
# # 通过index赋值。
# 异常值
# 文本类型一般不涉及异常值,因为无法判定什么为异常值
# 重复值
# drop_duplicated()
# 文本内容清洗
# 把无用的标点符号去掉,可以通过正则表达式实现。
# apply( )
# https://www.cnblogs.com/654321cc/p/12133295.html
# 分词
# 可以通过第三方库 jieba.cut 方法实现,该方法返回一个生成器,节省内存。
# data['content'] = data['content'].apply(lambda x:jieba.cut(x))
# 停用词处理
# 已经有统计好的停用词,直接拿来用就好。通过 set() 判断。
# def stopword_deal(x): # 这是我写的。
# words = []
# for word in x:
# if word not in stopwords:
# words.append(word)
# return words
# def stopword_deal(x):
# return [word for word in x if word not in stopwords] # 这是老师写的,高下立判。对于这种列表生成式可以完成的,要敏感。
# 这种的 是可以通过列表生成式实现的。
# 敏感点 words = [] for words.append
# 描述统计性分析
# from itertools import chain
# from collections import Counter
# c = chain(*df['content']) # 这个 * 有点吊啊
# counter = Counter(c) # 这两步 为统计学分析的 关键方法。 因为jieba将文本切开后是 值为列表,data['content'] 为series
# 无法使用ndarray的ravel()方法铺平。对于列表,使用 chain(*)方法,则可以实现嵌套列表铺平的效果。!!!!!
# counter.most_common()
# d = dict(counter) 还可以字典化,字典化之后取值就方便多了。!!!!!!
# d = dict(counter.most_common(20)) 这个也是ok的,取值更方便了!!!!!!
# data['date'].dt.year # 时间序列有这种方法。补充下
# 文本向量化
# https://blog.csdn.net/ZJL0105/article/details/82316056
# https://blog.csdn.net/youngshellzzz/article/details/88385801
# https://www.cnblogs.com/dogecheng/p/11470196.html
# 文本表示是自然语言处理中的基础工作,文本表示的好坏直接影响到整个自然语言处理系统的性能。文本向量化就是将文本表示成一系列能够表达文本语义的
# 向量,是文本表示的一种重要方式。目前对文本向量化大部分的研究都是通过词向量化实现的
# 词袋(Bag Of Word)模型是最早的以词语为基础处理单元的文本项量化方法。该模型产生的向量与原来文本中单词出现的顺序没有关系,而是词典中每个单词在
# 文本中出现的频率。该方法虽然简单易行,但是存在如下三个方面的问题:维度灾难,无法保留词序信息,存在语义鸿沟。
# 老师讲的是 离散表示(有局限)
# One-hot编码 --> 词袋模型 --> TF-IDF --> N-Gram https://www.cnblogs.com/dogecheng/p/11470196.html
# 还有分布式表示未讲
----------------------------------------------------------------------------------
# 文本向量化 + 特征筛选代码实现
# from sklearn.feature_extraction.text import TfidfVectorizer
# vector = TfidfVectorizer(ngram_range=(1,2),analyzer='char',lowercase=False)
# x_train_tran = vector.fit_transform(x_train)
# x_test_tran = vector.transform(x_test) # x_train_tran,x_test_tran 目前是稀疏矩阵
# from sklearn.feature_selection import f_classif
# from sklearn.feature_selection import SelectKBest
# select = SelectKBest(f_classif,k=min(20000,x_train_tran.shape[1]))
# select.fit(x_train_tran,y_train)
# x_train_tran = select.transform(x_train_tran)
# x_test_tran = select.transform(x_train_tran)
# print(x_train_tran.shape,x_test_tran.shape) # 这里的x_train_tran,x_test_tran 是有20000个标签的数据。就是文本向量化筛选后的 X 。
# # 形象的理解就是 iris[:,2]
# # 拿到这些数据后,我们可以选择KNN,逻辑回归,朴素贝叶斯等算法来试验。
-----------------------------------------------------------------------------------------------------------------------------
# 对content 的处理流程解释
# data['content'] --> 列表(去掉标点符号和停用词),通过jieba第三方库返回的就是列表 --> 字符串 第三方库 TfidfVectorizer 接收的参数是
# 元素为字符串的劣列表。!!!!!!!!!!!!!!!!!!!
------------------------------------------------------------------------------------------------------------------------------
# 特征分析
# https://www.jianshu.com/p/9ec363617da8
# 定量
# 集中趋势
# 离中趋势
# ...
# 定性
# 方差分析
# 用到了F检验,F检验适用于多种分类
# 备注:之前用到过 独立两样本T检验,适用于两个样本。(在AQI分析中,内陆和沿海AQI是否会有差异的推断统计中用到过)
# 特征选择
# 线性回归
# 递归式特征消除-RFECV(AQI分析,维度,经度,GDP)
# 验证性统计分析 ? 存疑
# 方差分析--ANOVA(文本分析,)
# 词云图
# from wordcloud import WordCloud
# wc = WordCloud(font_path=r'C:\Windows\Fonts\simfang.ttf',width=800,height=600).generate_from_frequencies(counter_dict) #注意
# generate_from_frequencies接收的是一个字典
# fig = plt.figure(figsize=(100,60))
# plt.imshow(wc)
# plt.axis(False)
# plt.savefig(r'C:\Users\zuogu\Desktop\wc.png')