sklearn中文文本分类 文本特征选择后选择了哪些词

应用过机器学习进行数据挖掘的同学应该都知道特征选择对模型表现的重要性。本文基于网上经典特征选择相关文章整理出干货:常用方法分类以及调包侠该如何用sklearn快速上手,供大家参考。
(一)预处理:
1 无量纲化:
1.1 区间缩放
from sklearn.preprocessing
import MinMaxScaler #区间缩放,返回值为缩放到[0, 1]区间的数据
MinMaxScaler().fit_transform(iris.data)
1.2 标准化(特征值服需从正态分布)
from sklearn.preprocessing import StandardScaler #标准化,返回值为标准化后的数据
StandardScaler().fit_transform(iris.data)
2 特征二值化:定量特征二值化的核心在于设定一个阈值,大于阈值的赋值为1,小于等于阈值的赋值为0
3 特征哑变量
4 缺失值计算:一般以均值填充
5 数据变换:常见的数据变换有基于多项式的、基于指数函数的、基于对数函数的
(二)特征选择
1.1 基于方差
from sklearn.feature_selection
import VarianceThreshold
#方差选择法,返回值为特征选择后的数据 #参数threshold为方差的阈值
VarianceThreshold(threshold=3).fit_transform(iris.data)
1.2 相关系数
from sklearn.feature_selection
import SelectKBest
from scipy.stats import pearsonr
SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)
1.3 卡方检验
from sklearn.feature_selection
import SelectKBest
from sklearn.feature_selection import chi2#选择K个最好的特征,返回选择特征后的数据
SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target)
1.4 互信息
2 递归特征消除:递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练
3.1 基于惩罚项的特征选择法
3.2 树模型中GBDT也可用来作为基模型进行特征选择,使用feature_selection库的SelectFromModel类结合GBDT模型,来选择特征的代码如下:
from sklearn.feature_selection
import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier
SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)
(四)降维
1 主成分分析
from sklearn.decomposition
import PCA2 3 #主成分分析法,返回降维后的数据 #参数n_components为主成分数目 PCA(n_components=2).fit_transform(iris.data)
2 线性判别分析
from sklearn.lda
import LDA2 3 #线性判别分析法,返回降维后的数据 #参数n_components为降维后的维数 LDA(n_components=2).fit_transform(iris.data, iris.target)
(收藏自公众号数据挖掘入门与实战)
你可能感兴趣的文章
4 收藏,540
19 收藏,2.1k
1 收藏,1.8k
分享到微博?
你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (????)? 表示感谢。
明天提醒我
我要该,理由是:
扫扫下载 Appscikit-learn系列之特征选择 - 简书
scikit-learn系列之特征选择
在建立一个机器学习模型时,并不是所有所有的数据属性都对模型有同等的贡献,因此也不是数据属性越多越好。在建立模型之前,要从众多的数据属性中选择对模型的输出和结果预测贡献最大的那些变量,这种对特征进行筛选的过程叫做“特征选择”。“特征选择”具有以下三方面的重要作用:
减少过度预测(overfit),减少噪音变量对模型的贡献。
增加准确性,依靠减少无关的变量提高模型的预测准确性。
减少模型训练时间,越少的训练数据,意味着越少的训练时间。
在scikit-learn中有两种特征选择的方法,一种叫做循环特征消减(Recursive Feature Elimination)和特征重要性评级 (feature importance ranking)。
1. 循环特征消减(Recursive Feature Elimination)
作为一种特征选择方法,其工作原理是:循环地移除变量和建立模型,通过模型的准确率来评估变量对模型的贡献。以下代码使用UCI的Iris数据集,使用sklearn.feature_selection的RFE方法来实现该方法。
from sklearn import datasets
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
dataset =datasets.load_iris() # laod iris dataset
model = LogisticRegression() # build logistic regression model
rfe = RFE(model,3) # limit number of variables to three
rfe = rfe.fit(dataset.data,dataset.target)
print(rfe.support_)
print(rfe.ranking_)
2. 特征重要性评级 (feature importance ranking)
“组合决策树算法”(例如Random Forest or Extra Trees)可以计算每一个属性的重要性。重要性的值可以帮助我们选择出重要的特征。以下代码使用UCI的Iris数据集,使用sklearn.metrics和sklearn.ensemble 的ExtraTreesClassifier来实现该算法。
from sklearn import datasets
from sklearn import metrics
from sklearn.ensemble import ExtraTreesClassifier
dataset =datasets.load_iris() # laod iris dataset
model = ExtraTreesClassifier() # build extra tree model
model.fit(dataset.data,dataset.target)
print(model.feature_importances_) #display importance of each variables
特征选择方法可以为你提供属性重要性的信息,利用这些信息,你可以利用更少而有效的变量来提高自己模型的准确性。
recursive feature elimination,feature_selection.RFE, ref.fit,ref.support_,ref.ranking_
ExtraTreeClassifier, model.feature_importances_
原文链接:
认知神经科学博士
数据科学(机器学习)践行者
时间、知识、自我管理者
印象笔记...使用sklearn做单机特征工程 - jasonfreak - 博客园
1 特征工程是什么?2 数据预处理  2.1 无量纲化    2.1.1 标准化    2.1.2 区间缩放法    2.1.3 标准化与归一化的区别  2.2 对定量特征二值化  2.3 对定性特征哑编码  2.4 缺失值计算  2.5 数据变换  2.6 回顾3 特征选择  3.1 Filter    3.1.1 方差选择法    3.1.2 相关系数法    3.1.3 卡方检验    3.1.4 互信息法
  3.2 Wrapper
    3.2.1 递归特征消除法  3.3 Embedded    3.3.1 基于惩罚项的特征选择法    3.3.2 基于树模型的特征选择法  3.4 回顾4 降维  4.1 主成分分析法(PCA)  4.2 线性判别分析法(LDA)  4.3 回顾5 总结6 参考资料
1 特征工程是什么?
  有这么一句话在业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。那特征工程到底是什么呢?顾名思义,其本质是一项工程活动,目的是最大限度地从原始数据中提取特征以供算法和模型使用。通过总结和归纳,人们认为特征工程包括以下方面:
  特征处理是特征工程的核心部分,sklearn提供了较为完整的特征处理方法,包括数据预处理,特征选择,降维等。首次接触到sklearn,通常会被其丰富且方便的算法模型库吸引,但是这里介绍的特征处理库也十分强大!
  本文中使用sklearn中的来对特征处理功能进行说明。IRIS数据集由Fisher在1936年整理,包含4个特征(Sepal.Length(花萼长度)、Sepal.Width(花萼宽度)、Petal.Length(花瓣长度)、Petal.Width(花瓣宽度)),特征值都为正浮点数,单位为厘米。目标值为鸢尾花的分类(Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾),Iris Virginica(维吉尼亚鸢尾))。导入IRIS数据集的代码如下:
1 from sklearn.datasets import load_iris
3 #导入IRIS数据集
4 iris = load_iris()
6 #特征矩阵
7 iris.data
9 #目标向量
10 iris.target
2 数据预处理
  通过特征提取,我们能得到未经处理的特征,这时的特征可能有以下问题:
不属于同一量纲:即特征的规格不一样,不能够放在一起比较。无量纲化可以解决这一问题。
信息冗余:对于某些定量特征,其包含的有效信息为区间划分,例如学习成绩,假若只关心&及格&或不&及格&,那么需要将定量的考分,转换成&1&和&0&表示及格和未及格。二值化可以解决这一问题。
定性特征不能直接使用:某些机器学习算法和模型只能接受定量特征的输入,那么需要将定性特征转换为定量特征。最简单的方式是为每一种定性值指定一个定量值,但是这种方式过于灵活,增加了调参的工作。:假设有N种定性值,则将这一个特征扩展为N种特征,当原始特征值为第i种定性值时,第i个扩展特征赋值为1,其他扩展特征赋值为0。哑编码的方式相比直接指定的方式,不用增加调参的工作,对于线性模型来说,使用哑编码后的特征可达到非线性的效果。
存在缺失值:缺失值需要补充。
信息利用率低:不同的机器学习算法和模型对数据中信息的利用是不同的,之前提到在线性模型中,使用对定性特征哑编码可以达到非线性的效果。类似地,对定量变量多项式化,或者进行其他的转换,都能达到非线性的效果。
  我们使用sklearn中的preproccessing库来进行数据预处理,可以覆盖以上问题的解决方案。
2.1 无量纲化
  无量纲化使不同规格的数据转换到同一规格。常见的无量纲化方法有标准化和区间缩放法。标准化的前提是特征值服从正态分布,标准化后,其转换成标准正态分布。区间缩放法利用了边界值信息,将特征的取值区间缩放到某个特点的范围,例如[0, 1]等。
2.1.1 标准化
  标准化需要计算特征的均值和标准差,公式表达为:
  使用preproccessing库的StandardScaler类对数据进行标准化的代码如下:
1 from sklearn.preprocessing import StandardScaler
3 #标准化,返回值为标准化后的数据
4 StandardScaler().fit_transform(iris.data)
2.1.2 区间缩放法
  区间缩放法的思路有多种,常见的一种为利用两个最值进行缩放,公式表达为:
  使用preproccessing库的MinMaxScaler类对数据进行区间缩放的代码如下:
1 from sklearn.preprocessing import MinMaxScaler
3 #区间缩放,返回值为缩放到[0, 1]区间的数据
4 MinMaxScaler().fit_transform(iris.data)
2.1.3 标准化与归一化的区别
  简单来说,标准化是依照特征矩阵的列处理数据,其通过求z-score的方法,将样本的特征值转换到同一量纲下。归一化是依照特征矩阵的行处理数据,其目的在于样本向量在点乘运算或其他核函数计算相似性时,拥有统一的标准,也就是说都转化为&单位向量&。规则为l2的归一化公式如下:
  使用preproccessing库的Normalizer类对数据进行归一化的代码如下:
1 from sklearn.preprocessing import Normalizer
3 #归一化,返回值为归一化后的数据
4 Normalizer().fit_transform(iris.data)
2.2 对定量特征二值化
  定量特征二值化的核心在于设定一个阈值,大于阈值的赋值为1,小于等于阈值的赋值为0,公式表达如下:
  使用preproccessing库的Binarizer类对数据进行二值化的代码如下:
1 from sklearn.preprocessing import Binarizer
3 #二值化,阈值设置为3,返回值为二值化后的数据
4 Binarizer(threshold=3).fit_transform(iris.data)
2.3 对定性特征哑编码
  由于IRIS数据集的特征皆为定量特征,故使用其目标值进行哑编码(实际上是不需要的)。使用preproccessing库的OneHotEncoder类对数据进行哑编码的代码如下:
1 from sklearn.preprocessing import OneHotEncoder
3 #哑编码,对IRIS数据集的目标值,返回值为哑编码后的数据
4 OneHotEncoder().fit_transform(iris.target.reshape((-1,1)))
2.4 缺失值计算
  由于IRIS数据集没有缺失值,故对数据集新增一个样本,4个特征均赋值为NaN,表示数据缺失。使用preproccessing库的Imputer类对数据进行缺失值计算的代码如下:
1 from numpy import vstack, array, nan
2 from sklearn.preprocessing import Imputer
4 #缺失值计算,返回值为计算缺失值后的数据
5 #参数missing_value为缺失值的表示形式,默认为NaN
6 #参数strategy为缺失值填充方式,默认为mean(均值)
7 Imputer().fit_transform(vstack((array([nan, nan, nan, nan]), iris.data)))
2.5 数据变换
  常见的数据变换有基于多项式的、基于指数函数的、基于对数函数的。4个特征,度为2的多项式转换公式如下:
  使用preproccessing库的PolynomialFeatures类对数据进行多项式转换的代码如下:
1 from sklearn.preprocessing import PolynomialFeatures
3 #多项式转换
4 #参数degree为度,默认值为2
5 PolynomialFeatures().fit_transform(iris.data)
  基于单变元函数的数据变换可以使用一个统一的方式完成,使用preproccessing库的FunctionTransformer对数据进行对数函数转换的代码如下:
1 from numpy import log1p
2 from sklearn.preprocessing import FunctionTransformer
4 #自定义转换函数为对数函数的数据变换
5 #第一个参数是单变元函数
6 FunctionTransformer(log1p).fit_transform(iris.data)
StandardScaler
标准化,基于特征矩阵的列,将特征值转换至服从标准正态分布
MinMaxScaler
区间缩放,基于最大最小值,将特征值转换到[0, 1]区间上
Normalizer
基于特征矩阵的行,将样本向量转换为&单位向量&
基于给定阈值,将定量特征按阈值划分
OneHotEncoder
将定性数据编码为定量数据
缺失值计算
计算缺失值,缺失值可填充为均值等
PolynomialFeatures
多项式数据转换
多项式数据转换
FunctionTransformer
自定义单元数据转换
使用单变元的函数来转换数据
3 特征选择
  当数据预处理完成后,我们需要选择有意义的特征输入机器学习的算法和模型进行训练。通常来说,从两个方面考虑来选择特征:
特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有什么用。
特征与目标的相关性:这点比较显见,与目标相关性高的特征,应当优选选择。除方差法外,本文介绍的其他方法均从相关性考虑。
  根据特征选择的形式又可以将特征选择方法分为3种:
Filter:过滤法,按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,选择特征。
Wrapper:包装法,根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。
Embedded:嵌入法,先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。类似于Filter方法,但是是通过训练来确定特征的优劣。
  我们使用sklearn中的feature_selection库来进行特征选择。
3.1 Filter
3.1.1 方差选择法
  使用方差选择法,先要计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征。使用feature_selection库的VarianceThreshold类来选择特征的代码如下:
1 from sklearn.feature_selection import VarianceThreshold
3 #方差选择法,返回值为特征选择后的数据
4 #参数threshold为方差的阈值
5 VarianceThreshold(threshold=3).fit_transform(iris.data)
3.1.2 相关系数法
  使用相关系数法,先要计算各个特征对目标值的相关系数以及相关系数的P值。用feature_selection库的SelectKBest类结合相关系数来选择特征的代码如下:
1 from sklearn.feature_selection import SelectKBest
2 from scipy.stats import pearsonr
4 #选择K个最好的特征,返回选择特征后的数据
5 #第一个参数为计算评估特征是否好的函数,该函数输入特征矩阵和目标向量,输出二元组(评分,P值)的数组,数组第i项为第i个特征的评分和P值。在此定义为计算相关系数
6 #参数k为选择的特征个数
7 SelectKBest(lambda X, Y: array(map(lambda x:pearsonr(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)
3.1.3 卡方检验
  经典的卡方检验是检验定性自变量对定性因变量的相关性。假设自变量有N种取值,因变量有M种取值,考虑自变量等于i且因变量等于j的样本频数的观察值与期望的差距,构建统计量:
  。用feature_selection库的SelectKBest类结合卡方检验来选择特征的代码如下:
1 from sklearn.feature_selection import SelectKBest
2 from sklearn.feature_selection import chi2
4 #选择K个最好的特征,返回选择特征后的数据
5 SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target)
3.1.4 互信息法
  经典的互信息也是评价定性自变量对定性因变量的相关性的,互信息计算公式如下:
  为了处理定量数据,最大信息系数法被提出,使用feature_selection库的SelectKBest类结合最大信息系数法来选择特征的代码如下:
1 from sklearn.feature_selection import SelectKBest
2 from minepy import MINE
4 #由于MINE的设计不是函数式的,定义mic方法将其为函数式的,返回一个二元组,二元组的第2项设置成固定的P值0.5
5 def mic(x, y):
m = MINE()
m.compute_score(x, y)
return (m.mic(), 0.5)
10 #选择K个最好的特征,返回特征选择后的数据
11 SelectKBest(lambda X, Y: array(map(lambda x:mic(x, Y), X.T)).T, k=2).fit_transform(iris.data, iris.target)
3.2 Wrapper
3.2.1 递归特征消除法
  递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。使用feature_selection库的RFE类来选择特征的代码如下:
1 from sklearn.feature_selection import RFE
2 from sklearn.linear_model import LogisticRegression
4 #递归特征消除法,返回特征选择后的数据
5 #参数estimator为基模型
6 #参数n_features_to_select为选择的特征个数
7 RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(iris.data, iris.target)
3.3 Embedded
3.3.1 基于惩罚项的特征选择法
  使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维。使用feature_selection库的SelectFromModel类结合带L1惩罚项的逻辑回归模型,来选择特征的代码如下:
1 from sklearn.feature_selection import SelectFromModel
2 from sklearn.linear_model import LogisticRegression
4 #带L1惩罚项的逻辑回归作为基模型的特征选择
5 SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(iris.data, iris.target)
  ,所以没选到的特征不代表不重要。故,可结合L2惩罚项来优化。具体操作为:若一个特征在L1中的权值为1,选择在L2中权值差别不大且在L1中权值为0的特征构成同类集合,将这一集合中的特征平分L1中的权值,故需要构建一个新的逻辑回归模型:
1 from sklearn.linear_model import LogisticRegression
3 class LR(LogisticRegression):
def __init__(self, threshold=0.01, dual=False, tol=1e-4, C=1.0,
fit_intercept=True, intercept_scaling=1, class_weight=None,
random_state=None, solver='liblinear', max_iter=100,
multi_class='ovr', verbose=0, warm_start=False, n_jobs=1):
#权值相近的阈值
self.threshold = threshold
LogisticRegression.__init__(self, penalty='l1', dual=dual, tol=tol, C=C,
fit_intercept=fit_intercept, intercept_scaling=intercept_scaling, class_weight=class_weight,
random_state=random_state, solver=solver, max_iter=max_iter,
multi_class=multi_class, verbose=verbose, warm_start=warm_start, n_jobs=n_jobs)
#使用同样的参数创建L2逻辑回归
self.l2 = LogisticRegression(penalty='l2', dual=dual, tol=tol, C=C, fit_intercept=fit_intercept, intercept_scaling=intercept_scaling, class_weight = class_weight, random_state=random_state, solver=solver, max_iter=max_iter, multi_class=multi_class, verbose=verbose, warm_start=warm_start, n_jobs=n_jobs)
def fit(self, X, y, sample_weight=None):
#训练L1逻辑回归
super(LR, self).fit(X, y, sample_weight=sample_weight)
self.coef_old_ = self.coef_.copy()
#训练L2逻辑回归
self.l2.fit(X, y, sample_weight=sample_weight)
cntOfRow, cntOfCol = self.coef_.shape
#权值系数矩阵的行数对应目标值的种类数目
for i in range(cntOfRow):
for j in range(cntOfCol):
coef = self.coef_[i][j]
#L1逻辑回归的权值系数不为0
if coef != 0:
#对应在L2逻辑回归中的权值系数
coef1 = self.l2.coef_[i][j]
for k in range(cntOfCol):
coef2 = self.l2.coef_[i][k]
#在L2逻辑回归中,权值系数之差小于设定的阈值,且在L1中对应的权值为0
if abs(coef1-coef2) & self.threshold and j != k and self.coef_[i][k] == 0:
idx.append(k)
#计算这一类特征的权值系数均值
mean = coef / len(idx)
self.coef_[i][idx] = mean
return self
  使用feature_selection库的SelectFromModel类结合带L1以及L2惩罚项的逻辑回归模型,来选择特征的代码如下:
1 from sklearn.feature_selection import SelectFromModel
3 #带L1和L2惩罚项的逻辑回归作为基模型的特征选择
4 #参数threshold为权值系数之差的阈值
5 SelectFromModel(LR(threshold=0.5, C=0.1)).fit_transform(iris.data, iris.target)
3.3.2 基于树模型的特征选择法
  树模型中GBDT也可用来作为基模型进行特征选择,使用feature_selection库的SelectFromModel类结合GBDT模型,来选择特征的代码如下:
1 from sklearn.feature_selection import SelectFromModel
2 from sklearn.ensemble import GradientBoostingClassifier
4 #GBDT作为基模型的特征选择
5 SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)
VarianceThreshold
方差选择法
SelectKBest
可选关联系数、卡方校验、最大信息系数作为得分计算的方法
递归地训练基模型,将权值系数较小的特征从特征集合中消除
SelectFromModel
训练基模型,选择权值系数较高的特征
  当特征选择完成后,可以直接训练模型了,但是可能由于特征矩阵过大,导致计算量大,训练时间长的问题,因此降低特征矩阵维度也是必不可少的。常见的降维方法除了以上提到的基于L1惩罚项的模型以外,另外还有主成分分析法(PCA)和线性判别分析(LDA),线性判别分析本身也是一个分类模型。PCA和LDA有很多的相似点,其本质是要将原始的样本映射到维度更低的样本空间中,但是PCA和LDA的映射目标不一样:。所以说PCA是一种无监督的降维方法,而LDA是一种有监督的降维方法。
4.1 主成分分析法(PCA)
  使用decomposition库的PCA类选择特征的代码如下:
1 from sklearn.decomposition import PCA
3 #主成分分析法,返回降维后的数据
4 #参数n_components为主成分数目
5 PCA(n_components=2).fit_transform(iris.data)
4.2 线性判别分析法(LDA)
  使用lda库的LDA类选择特征的代码如下:
1 from sklearn.lda import LDA
3 #线性判别分析法,返回降维后的数据
4 #参数n_components为降维后的维数
5 LDA(n_components=2).fit_transform(iris.data, iris.target)
decomposition
主成分分析法
线性判别分析法
  再让我们回归一下本文开始的特征工程的思维导图,我们可以使用sklearn完成几乎所有特征处理的工作,而且不管是数据预处理,还是特征选择,抑或降维,它们都是通过某个类的方法fit_transform完成的,fit_transform要不只带一个参数:特征矩阵,要不带两个参数:特征矩阵加目标向量。这些难道都是巧合吗?还是故意设计成这样?方法fit_transform中有fit这一单词,它和训练模型的fit方法有关联吗?接下来,我将在中阐述其中的奥妙!
6 参考资料
Trackbacks - 03807人阅读
数据挖掘(28)
Python(22)
机器学习(42)
之前做过一些文本挖掘的项目,比如网页分类、微博情感分析、用户评论挖掘,也曾经将libsvm进行包装,写了一个文本分类的开软软件Tmsvm。所以这里将之前做过一些关于文本分类的东西整理总结一下。
1 基础知识
1. 1 样本整理
文本分类属于有监督的学习,所以需要整理样本。根据业务需求,确定样本标签与数目,其中样本标签多为整数。在svm中其中如果为二分类,样本标签一般会设定为-1和1,而在朴素贝叶斯方法中,一般为0和1,但不是固定的,标签的设置和算法本身的性质有关的。
如下面的整理的样本,1为正类,-1为反类(为了能便于展示,这里使用了一些即时聊天工具中的文本,里面的一些对话都是YY,并非真实的)。
表 1.1-1 一个训练样本的例子
如要购买商品的请加我qq联系我购买!
你好需要订购请加扣扣
索尼爱立信手机的体验是一个月吗
不好意思这个价钱最便宜了
3件的那个他是高价在卖&&&&&
1.2 特征选择
文本分类中最著名的特征提取方法就是向量空间模型(),即将样本转换为向量的形式。为了能实现这种转换,需要做两个工作:确定特征集和提取特征。
1.2.1 确定特征集
特征集其实就是词典,而且还需要给每个词设定一个编号。
一般可以将所有样本的词都提取出来作为词典,而词典的编号可以随意设置,默认情况下,所有词的权重都是等同的。如何从样本中提取出一个个意义的词呢?最常用的方法就是使用分词工具,比如“如要购买商品的请加我qq联系我购买!”,可以分成“如^要^购买^商品^的^请^加^我^qq^联系^我^购买^!”,其中“^”是用来分割词的。现在比较常见的分词工具有ICTCLAS(C++),Iksegment()。
下图是一个典型的生成词典的流程图。
图 1.1-1 从样本中提取词典流程图
1.2.2 特征选择
根据不同的业务,文本分类中词典的规模在万级到千万级甚至亿级。而这么大的维度可能会带来,因此就要想办法从大量的特征中选择一些有代表性的特征而又不影响分类的效果(而根据文献中的结果,特征选择可以在一定程度上提高分类的效果)。特征选择就是从特征集中选择一些代表性的词。而如何衡量词的代表性呢?一般的计算方法有词频、卡方公式、信息增益等。当前文献中一致认为比较好的方法是卡方公式。
下面几个链接是几篇写的比较详细介绍如何进行特征选择的文章
特征选择与特征权重计算的区别
2.&&&&& & 特征选择方法之信息增益
3.&&&&& & 特征选择之开方检验
1.2.3 特征抽取
另外一种解决维度灾难的思路就是特征抽取。同样是降维,相比特征选择,特征抽取采用了一种高级的方法来进行。Topic Modeling是原理就是将利用映射将高纬度空间映射到低纬空间,从而达到降维的目的。具体可以见2.1特征抽取部分
1.3 计算特征权重
给定一个样本,如何转换成向量呢?
首先给一张流程图:
图 1.1-2 计算特征权重的流程
1)首先,对样本进行分词,提取出所有的词。
2)根据已经生成的词典,如果词典中的词出现,就在相应对应的位置填入该词的词频。
3)对生成的向量进行归一化
上面的所示的方法是比较简单的一种,其中特征权重采用的为词频来表示,现在比较常用的特征权重的计算方式为TF*IDF,TF*RF。详见2.3 特征权重
1.4&&&模型训练与预测
当把文本转换成向量的形式后,大部分的工作其实已经做完了。后面所要做的就是利用算法进行训练和预测了。
现在文本分类的算法很多,常见的有Na?ve Bayes,SVM,KNN,Logistic回归等。其中SVM据文献中说是在工业界和学术界通吃的,不过据我了解现在公司里用SVM来做分类的不多 = =,而Logistic回归则是比较常用的,因为相对来说简单,而且可以并行化训练。最重要是简单可依赖。
而至于这些算法具体是什么我这里也不再累述了,因为网络上介绍相关的算法的文献很多,而且源程序也很多。可以直接下来下来使用。
资料与程序
1.&&&&& 介绍Na?veBayes方法如何应用在文本分类上
2.&&&&& 详细分析了Mahout中如何实现Na?veBayes
3.&&&&& & Libsvm是用来进行SVM训练与预测的开源工具。下载下来就可以直接用,作者的文档写的很详细。
4.&&&&& SVM的八股介绍,讲解的还是通俗易懂的
介绍支持向量机的
&Tmsvm是我之前写的利用svm进行文本分类的程序,涉及到文本分类的所有流程。
1.5 进一步阅读:
文本分类的技术已经被研究了很多年,所以相关的资料也是非常多,可以进一步阅读下面的一些资料
这里有一个文本分类的入门系列,介绍的还是比较详细的。
2.&&&&& 《》,这本书很薄,但是写的很深入,对文本挖掘的一些重点问题进行了讨论
2 若干问题的讨论
2.1 特征选择
特征选择是就是依据某种权重计算公式从词典中选择一些有代表性的词。常用的特征选择的方法有很多种,Chi、Mutual Information、Information Gain。另外TF、IDF也可以作为特征选择的一种方法。在这个问题上很多人做了大量的实验,Chi方法是效果最好的一种,所以本系统(指的是)中采用了这种方法。关于特征选择无论是还是中都有很细致的讲解。
2.2 特征抽取
特征抽取和特征选择都是为了降维。特征选择的方法是从词典中选出一些有代表性的词,而特征抽取是利用映射将高纬度空间映射到低纬空间,从而达到降维的目的。最常见的特征抽取的方法是Latent Semantic Analysis(潜在语义分析),其中LSA也被称作Topic Modeling,比较常用的Topic Modeling的方法有LSA、PLSA、LDA。之前使用的方法LSA。
假设原来的词-文档矩阵为,即有m个term,n篇文档。表示第j篇文档的向量。,经过SVD分解后,选择前k个特征值后。再去重组文档的特征向量,,这样新的文档特征向量就由原来的m维降至k维。而一个新的文档即可通过,映射到U空间上。其实还有另外一种方法,就是,但是在实验中发现,前一种映射效果会更好一点。另外也有很详细的阐述
本系统将LSA用来Classification上的方法是一种叫做的方法。其主要步骤为
*&&&&&&&&&&&&&模型训练
①&&&&&&&&&&&&&训练初始分类器C0
②&&&&&&&&&&&&&对训练样本预测,生成初始分值
③&&&&&&&&&&&&&文档特征向量变换
④&&&&&&&&&&&&&设定阈值,选择top n文档作为局部LSA区域
⑤&&&&&&&&&&&&&对局部词/文档 矩阵做SVD分解。得到U、S、V矩阵
⑥&&&&&&&&&&&&&将其他的训练样本映射到U空间中
⑦&&&&&&&&&&&&&对所有经过变换后的训练样本进行训练,得到LSA分类器
*&&&&&&&&&&&&&模型预测
①&&&&&&&&&&&&&利用C0预测得到其初始分值
②&&&&&&&&&&&&&文档特征向量变换
③&&&&&&&&&&&&&映射到U空间
④&&&&&&&&&&&&&利用LSA模型进行预测得分
2.3 特征权重计算
文档特征向量的特征权重计算的一般公式为,即第i个term在第j篇文档向量中的权重。其中Local(i,j)被称为局部因子,与term在文档中出现的次数有关。global(i)又称为term的全局因子,与在整个训练集中term出现有关。通常我们熟悉的公式都可以转化为这一个通用的表达式。如最常用的tf形式,tf*idf形式。因此我们就可以在构造词典的时候就计算term的全局因子,把这个值放在词典中,然后在计算特征权重的时候直接调用。
具体的流程图如下:
图 2.3-1 特征权重的计算流程
在Classification中哪种特征权重的计算方式最好??tf*idf ?在文献中最常用的是tf*idf,但是其效果并一定好。曾经有人也在这上面做了一些工作,比如新加坡国立大学的曾在和上发表过文章来阐述这个问题。也对各种feature weight的方法做了,最终的结论是tf*idf并不是最佳的,而最简单的tf表现不错,一些具有区分性的方法比如tf*chi等效果差强人意。
后来在09年发表了,对term
weighting方法做了一个综合细致的阐述,并对其提出的tf*rf方法做了各方面的论证。
2.4 TSVM的模型训练和预测流程
训练过程:对文本自动做SVM模型的训练。包括Libsvm、Liblinear包的选择,分词,词典生成,特征选择,SVM参数的选优,SVM模型的训练等都可以一步完成。示意图见下面
图 2.4-1 TMSVM模型训练流程
模型预测过程:
图 2.4-2 多个模型同时预测流程
模型结果:
模型会返回两个结果:label和score,其中label即其预测的标签。而score是该样本属于该类的隶属度,分值越大,代表属于该类的置信度越大。具体的计算方式则是根据公式,,其中k为所有支持判别类得个数,n为所有类别个数,si 为所有支持判别类的分数。返回score的好处是对与information filtering问题,因为训练样本的unbalance和randomly sampling 问题,依据判别的标签得到的结果准确率较低,因此需要通过阈值控制。
2.5 SVM参数选择
Libsvm中最重要的两个参数为C和gamma。C是惩罚系数,即对误差的宽容度。c越高,说明越不能容忍出现误差。C过大或过小,泛化能力变差。gamma是选择RBF函数作为kernel后,该函数自带的一个参数。隐含地决定了数据映射到新的特征空间后的分布,gamma越大,支持向量越少,gamma值越小,支持向量越多。支持向量的个数影响训练与预测的速度。这个问题在其上有详细的介绍。
而Liblinear的C参数也是非常重要的。
因此在系统中会通过5-flods交叉验证的方法对一定范围内的C,gamma进行grid 搜索,关于grid搜索可以参考以及libsvm中tool文件夹中grid.py源文件。grid搜索是可以得到全局最优的参数的。
为了加快SVM参数搜索的效率,采用两种粒度的搜索粗粒度和细粒度,两种搜索方式的区别就是搜索步长不同。粗粒度是指搜索步长较大,为了能在较大的搜索范围内找到一个最优解所在的大体区域。细粒度搜索搜索步长较小,为了能在一个较小范围内找到一个精确参数。
而对与大样本的文件,使用上面的方法仍然会比较耗费时间。为了进一步提高效率,同时在保证得到全局最优的情况下,先对选择大样本的子集进行粗粒度的搜索,然后得到在得到的最优区间内对全量样本进行细粒度的搜索。
2.6 SVM参数选择的并行化
SVM对训练过程还是比较久的,尤其是为了能够找到最合适的参数。自然就想到能不能对SVM的巡检并行化。我之前做的方法是对参数的选择并行化,而单个参数的训练还是放在一个机器上串行进行。我把训练的方法放在我上,就不再粘贴到这里了。
2.7 Libsvm 与liblinear的多分类策略
libsvm的多分类策略为one-againt-one。总共有k*(k-1)/2个binary classifier,对这k*(k-1)/2个的value进行遍历,如果第i个类和第j个类binary 的classifier的value大于0,则会给第i个类投1票,否则给第j个类投1票。选择最终获得投票数最多的类作为最终的类别。
而liblinear的策略为one-against-rest。总共有k个binary classifier。从所有binary classifier中选择值最大多对应的类别作为最终的预测类标签。
2.8 重复样本对SVM模型的影响
重复样本对于SVM模型有怎样的影响呢?
我自己做了个实验,用来看重复样本的影响。
原有一个训练样本共有Positive样本1000,Negative样本2000,然后将Positive样本*2,构造了一个Positive样本2000,Negative样本2000的训练样本。然后测试一个包含Positive样本4494 ,Negative样本24206的样本。最终的结果如下:
图2.8-1重复样本对结果影响
从结果上来看:在F值上,无重复的样本会比重复样本稍高(图中保留了2位小数,其实差异不超过0.5%)。而正确率上,重复样本会比无重复样本稍高。
然后我又把模型放入到一个包含3千万样本中去测试,具体的指标无法测算。但是感觉还是重复样本会好一点。
具体分析:
1、&&&&&&&一个样本被重复的多次,意义上相当于增加了该样本的权重。在SVM有一种WeightedInstance。在正常样本难免会有些误判,如果同一条样本同时出现在Positive和Negative类中,包含重复样本的Positive类就会把Negative类误判的样本的影响抵消。而在SVM分类中对这些离群点会用惩罚函数进行控制。
2、&&&&&&&但是如果保留重复样本,会增加样本的量,对libsvm来说,分类的复杂度为O(Nsv3),而且如果一个样本是支持向量,那么所有重复的样本也都会被加入到支持向量中去。而且如果要为SVM模型选择合适的参数的,如果在SVM选择的是RBF核函数,挑选合适的惩罚cost和RBF的参数gramma,如果在都是在[1,5,0.5]进行挑选,则总共会有9*9=81组参数需要挑选,在每组参数下如果要进行5-flods的交叉验证,则需要81*5=405次训练与测试的过程。如果每次训练与测试花费2分钟(在样本达到10万数量级的时候,libsvm的训练时间差不多按分钟计算),则总共需要405*2/60=12.3小时,所以说训练一个好的SVM模型十分不容易。因此如果去掉重复样本对训练效率来说大有裨益。
&2.9 将分类应用与信息过滤
分类应用与信息过滤,对最终效果影响最大的是什么?分类算法?词典大小?特征选择?模型参数?这些都会影响到最终的过滤效果,但是如果说对过滤效果影响最大的,还是训练样本的采样。
现在基于的分类算法一般都是基于一个假设:训练集和测试集的分布是一致的,这样在训练集上训练出来的分类器应用与测试集时其效果才会比较有效。
但是信息过滤面对的数据集一般是整个互联网,而互联网的数据集一般很难去随机采样。如下图所示:通常来说,信息过滤或其它面向全互联网的应用在分类,选择数据集时,需要包含P(Positive,即用户感兴趣的样本),N(Negative,即用户不关心、不敢兴趣的样本)。最理想的情况是:P选择是用户感兴趣的,而N是全网中除去P,显而易见N是无限大的,而且很难估计其真正的分布,即无法对其随机取样。
图2.9-1样本分布
同样面对整个互联网的应用时网页分类,网页分类应用一般会选择Yahoo!或者是专门整理网页分类专门网站的网页作为初始训练样本。
信息过滤的样本一般来说,感兴趣的样本是很好随机采样的。但是与感兴趣相对于的是正常样本,这个很难去选择。而正常样本对全网测试效果是影响非常大的。我曾经做过一个实验:
首先,有一个包含5万条样本的数据集,有2.5万条Positive样本,2.5万条Negative样本。这里的Negative样本是以前用关键字的方法找出的不正确的样本。用4万条样本做训练样本,用1万条样本做测试样本。训练出得模型交叉验证的结果可以达到97%以上。在测试样本中的测试效果,然后选定阈值为0.9,这是的召回率可以达到93%,正确率为96%。
然后把这个模型放到一个包含3千万条中去测试,设置阈值为0.9,共找出疑似违规样本300万条。对这个实验来说,召回的样本实在是太多了,其正确率是很低的。
然后,我又更换了一下正常样本。从这3千万样本中随机采样出3万条样本,然后经过校验,将其中Positive的样本剔除掉。剩下大约2万7千条样本放入到训练样本重新训练。
把得到的新模型放到3千万样本中测试,同样设置阈值为0.9,共找出疑似样本15万。正确率可以达到70%左右。所以正常样本的随机选择对分类来说同样至关重要。
举一个小例子:
下图左面的图是用P和N训练出得模型。右面的图中有一个未知的类C,根据已知的模型,他应该会被分入到P中,但是实际上他是不属于P的。一般情况下,这种情况可以用阈值来控制。
图2.9-2分类用于信息过滤
2.10& SVM解决样本倾斜的问题
所谓数据偏斜(unbalanced),它指的是参与分类的两个类别(也可以指多个类别)样本数量差异很大。比如说正类有10,000个样本,而负类只给了100个,这会引起的问题显而易见,可以看看下面的图:
图2.10-1样本倾斜示例
方形的点是负类。H,H1,H2是根据给的样本算出来的分类面,由于负类的样本很少很少,所以有一些本来是负类的样本点没有提供,比如图中两个灰色的方形点,如果这两个点有提供的话,那算出来的分类面应该是H’,H2’和H1,他们显然和之前的结果有出入,实际上负类给的样本点越多,就越容易出现在灰色点附近的点,我们算出的结果也就越接近于真实的分类面。但现在由于偏斜的现象存在,使得数量多的正类可以把分类面向负类的方向“推”,因而影响了结果的准确性。
具体的解决方法还是看我博客上的,这里就不单独贴出来了。
2.11& 其他
文本分类的问题点很多,之前还想再写写如何对短文本(比如query)进行分类,利用利用Wikipedia的知识增强文本分类的效果,如何利用未标记样本来提高分类的效果。现在时间不多,等有时间了再继续深入的写吧。
安装完Scikit-learn 之后,利用其进行文本分类。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
背景知识:
现在文本分类的很多,常见的有Na?ve Bayes,SVM,KNN,Logistic回归等。其中SVM据文献中说是在工业界和学术界通吃的。
资料与程序
1.&&&&&介绍NaiveBayes方法如何应用在文本分类上
2.&&&&&详细分析了Mahout中如何实现Na?veBayes
Libsvm是用来进行SVM训练与预测的开源工具。下载下来就可以直接用,作者的文档写的很详细。
4.&&&&& SVM的八股介绍,讲解的还是通俗易懂的
介绍支持向量机的
6.&&&&& &Tmsvm是我之前写的利用svm进行文本分类的程序,涉及到文本分类的所有流程。
这里有一个文本分类的入门系列,介绍的还是比较详细的。
8.&&&&& 《》,这本书很薄,但是写的很深入,对文本挖掘的一些重点问题进行了讨论
本文主要包括4个部分:
Pipline 训练模型
GridSearchCV 寻找最优参数
1. Sklearn 文本分类的数据集:
categories&=&['alt.atheism',&&&&&&&&&&&&&&&&&&&&&&&&&'soc.religion.christian',&&&&&&&&&&&&&&&&&&&&&&&&&'comp.graphics',&&&&&&&&&&&&&&&&&&&&&&&&&'comp.sys.ibm.pc.hardware',&&&&&&&&&&&&&&&&&&&&&&&&&&'sci.med']&&twenty_train&=&fetch_20newsgroups(subset&=&'train',categories&=&categories,shuffle=True,&random_state=42)&&twenty_test&=&fetch_20newsgroups(subset='test',categories=categories,&shuffle=True,&random_state=42)&&
2. 提取特征
1)语料文件可以用一个词文档矩阵代表,每行是一个文档,每列是一个标记(即词)。将文档文件转化为数值特征的一般过程被称为向量化。这个特殊的策略(标记,计数和正态化)被称为词袋或者Bag of n-grams表征。用词频描述文档,但是完全忽略词在文档中出现的相对位置信息。
CountVectorizer在一个类中实现了标记和计数:
from&sklearn.feature_extraction.text&import&CountVectorizer&&&vectorizer&=&CountVectorizer(min_df=1)&&
vectorizer.get_feature_names()&&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)&&
2)TF-IDF 计算词的权重
from sklearn.feature_extraction.textimportTfidfTransformer
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(X)
*大文本向量可以选择哈希向量,限定特征个数
from sklearn.feature_extraction.textimportHashingVectorizer
hv =HashingVectorizer(n_features=10)
hv.transform(corpus)
HashingVectorizer的局限:
不能反转模型(没有inverse_transform方法),也无法访问原始的字符串表征,因为,进行mapping的哈希方法是单向本性。没有提供了IDF权重,因为这需要在模型中引入状态。如果需要的话,可以在管道中添加TfidfTransformer。
详细内容见官网
3. 测试简单的 模型训练+预测
from&sklearn.feature_extraction.text&import&CountVectorizer,TfidfTransformer&&from&sklearn.naive_bayes&import&MultinomialNB&&&&vect&=&CountVectorizer()&&X_train=&count_vect.fit_transform(twenty_train.data)&&&&tfidf_transformer&=&TfidfTransformer()&&X_train_tfidf&=&tfidf_transformer.fit_transform(X_train)&&&&clf&=&MultinomialNB().fit(X_train_tfidf,&twenty_train.target&&docs_new&=&['God&is&love',&'OpenGL&on&the&GPU&is&fast']&&X_new&=&vect.transform(docs_new)&&X_new_tfidf&=&tfidf_transformer.transform(X_new)&&&&predicted&=&clf.predict(X_new_tfidf)&&&for&doc,&category&in&zip(docs_new,&predicted):&&&&&&&print('%r&=&&%s'&%&(doc,&twenty_train.target_names[category]))&&&
4. Pipline 串联处理器
&&def&test():&&&&&&docs_new&=&['God&is&love',&'OpenGL&on&the&GPU&is&fast']&&&&&&text_clf&=&Pipeline([('vect',&CountVectorizer()),&&&&&&&&&&&&&&&&&&&('tfidf',&TfidfTransformer()),&&&&&&&&&&&&&&&&&&&('clf',&MultinomialNB()),&&&&&&&&&&&&&&&&&&&])&&&&&&&&&&&&text_clf.fit(twenty_train.data,&twenty_train.target)&&&&&&&&&&&&new_predicted&=&text_clf.predict(docs_new)&&&&&&&&&&&&for&doc,&category&in&zip(docs_new,new_predicted):&&&&&&&&&&&&&&&&&&&&print&('%r&=&&%s'&%(doc,&twenty_train.target_names[category]))&&
5. 模型训练+预测
def&testPipline():&&&&&&&&&&&&&&&&&print&'*************************\nNB\n*************************'&&&&&&text_clf&=&Pipeline([('vect',&CountVectorizer()),&&&&&&&&&&&&&&&&&&&('tfidf',&TfidfTransformer()),&&&&&&&&&&&&&&&&&&&('clf',&MultinomialNB()),&&&&&&&&&&&&&&&&&&&])&&&&&&text_clf.fit(twenty_train.data,&twenty_train.target)&&&&&&&&&&&&docs_test&=&twenty_test.data&&&&&&&nb_predicted&=&text_clf.predict(docs_test)&&&&&&&&&&&&accuracy=np.mean(nb_predicted&==&twenty_test.target)&&&&&&&&&&&&print&(&The&accuracy&of&twenty_test&is&%s&&%accuracy)&&&&&&&&&&&&print(metrics.classification_report(twenty_test.target,&nb_predicted,target_names=twenty_test.target_names))&&&&&&&&&&&&&&&&&&print&'*************************\nKNN\n*************************'&&&&&&text_clf&=&Pipeline([('vect',&CountVectorizer()),&&&&&&&&&&&&&&&&&&&('tfidf',&TfidfTransformer()),&&&&&&&&&&&&&&&&&&&('clf',&KNeighborsClassifier()),&&&&&&&&&&&&&&&&&&&])&&&&&&text_clf.fit(twenty_train.data,&twenty_train.target)&&&&&&&&&&&&docs_test&=&twenty_test.data&&&&&&&knn_predicted&=&text_clf.predict(docs_test)&&&&&&&&&&&&accuracy=np.mean(knn_predicted&==&twenty_test.target)&&&&&&&&&&&&print&(&The&accuracy&of&twenty_test&is&%s&&%accuracy)&&&&&&&&&&&&print(metrics.classification_report(twenty_test.target,&knn_predicted,target_names=twenty_test.target_names))&&&&&&&&&&&&&&&&&&print&'*************************\nSVM\n*************************'&&&&&&text_clf&=&Pipeline([('vect',&CountVectorizer()),&&&&&&&&&&&&&&&&&&&&&&&('tfidf',&TfidfTransformer()),&&&&&&&&&&&&&&&&&&&&&&&('clf',&SGDClassifier(loss='hinge',&penalty='l2',&alpha=1e-3,&n_iter=5,&random_state=42)),])&&&&&&&&&&&&text_clf.fit(twenty_train.data,&twenty_train.target)&&&&&&&&&&&&svm_predicted&=&text_clf.predict(docs_test)&&&&&&&&&&&&accuracy=np.mean(svm_predicted&==&twenty_test.target)&&&&&&&&&&&&print&(&The&accuracy&of&twenty_test&is&%s&&%accuracy)&&&&&&&&&&&print(metrics.classification_report(twenty_test.target,&svm_predicted,target_names=twenty_test.target_names))&&&&&&&&&&&&&&&&print&'*************************\nHashingVectorizer\n*************************'&&&&&&text_clf&=&Pipeline([('vect',&HashingVectorizer(stop_words&=&'english',non_negative&=&True,&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&n_features&=&10000)),&&&&&&&&&&&&&&&&&&&&&&&('tfidf',&TfidfTransformer()),&&&&&&&&&&&&&&&&&&&&&&&('clf',&SGDClassifier(loss='hinge',&penalty='l2',&alpha=1e-3,&n_iter=5,&random_state=42)),])&&&&&&&&&&&&text_clf.fit(twenty_train.data,&twenty_train.target)&&&&&&&&&&&&svm_predicted&=&text_clf.predict(docs_test)&&&&&&&&&&&&accuracy=np.mean(svm_predicted&==&twenty_test.target)&&&&&&&&&&&&print&(&The&accuracy&of&twenty_test&is&%s&&%accuracy)&&&&&&&&&&&print(metrics.classification_report(twenty_test.target,&svm_predicted,target_names=twenty_test.target_names))&&
*************************&&NB&&*************************&&The&accuracy&of&twenty_test&is&0.&&&&&&&&&&&&&&&&&&&&&&&&&&precision&&&&recall&&f1-score&&&support&&&&&&&&&&&&&&&alt.atheism&&&&&&&0.97&&&&&&0.58&&&&&&0.73&&&&&&&319&&&&&&&&&&&comp.graphics&&&&&&&0.95&&&&&&0.85&&&&&&0.89&&&&&&&389&&&comp.sys.mac.hardware&&&&&&&0.93&&&&&&0.92&&&&&&0.93&&&&&&&385&&&&&&&&&&&&&&&&&sci.med&&&&&&&0.96&&&&&&0.81&&&&&&0.87&&&&&&&396&&soc.religion.christian&&&&&&&0.62&&&&&&0.99&&&&&&0.76&&&&&&&398&&&&&&&&&&&&&&&avg&/&total&&&&&&&0.88&&&&&&0.84&&&&&&0.84&&&&&&1887&&&&*************************&&KNN&&*************************&&The&accuracy&of&twenty_test&is&0.&&&&&&&&&&&&&&&&&&&&&&&&&&precision&&&&recall&&f1-score&&&support&&&&&&&&&&&&&&&alt.atheism&&&&&&&0.56&&&&&&0.86&&&&&&0.68&&&&&&&319&&&&&&&&&&&comp.graphics&&&&&&&0.84&&&&&&0.73&&&&&&0.78&&&&&&&389&&&comp.sys.mac.hardware&&&&&&&0.82&&&&&&0.75&&&&&&0.78&&&&&&&385&&&&&&&&&&&&&&&&&sci.med&&&&&&&0.87&&&&&&0.58&&&&&&0.69&&&&&&&396&&soc.religion.christian&&&&&&&0.75&&&&&&0.84&&&&&&0.79&&&&&&&398&&&&&&&&&&&&&&&avg&/&total&&&&&&&0.78&&&&&&0.75&&&&&&0.75&&&&&&1887&&&&*************************&&SVM&&*************************&&The&accuracy&of&twenty_test&is&0.&&&&&&&&&&&&&&&&&&&&&&&&&&precision&&&&recall&&f1-score&&&support&&&&&&&&&&&&&&&alt.atheism&&&&&&&0.94&&&&&&0.81&&&&&&0.87&&&&&&&319&&&&&&&&&&&comp.graphics&&&&&&&0.89&&&&&&0.92&&&&&&0.91&&&&&&&389&&&comp.sys.mac.hardware&&&&&&&0.92&&&&&&0.96&&&&&&0.94&&&&&&&385&&&&&&&&&&&&&&&&&sci.med&&&&&&&0.94&&&&&&0.90&&&&&&0.92&&&&&&&396&&soc.religion.christian&&&&&&&0.88&&&&&&0.96&&&&&&0.92&&&&&&&398&&&&&&&&&&&&&&&avg&/&total&&&&&&&0.91&&&&&&0.91&&&&&&0.91&&&&&&1887&&&&*************************&&HashingVectorizer&&*************************&&The&accuracy&of&twenty_test&is&0.&&&&&&&&&&&&&&&&&&&&&&&&&&precision&&&&recall&&f1-score&&&support&&&&&&&&&&&&&&&alt.atheism&&&&&&&0.91&&&&&&0.77&&&&&&0.84&&&&&&&319&&&&&&&&&&&comp.graphics&&&&&&&0.89&&&&&&0.91&&&&&&0.90&&&&&&&389&&&comp.sys.mac.hardware&&&&&&&0.92&&&&&&0.95&&&&&&0.93&&&&&&&385&&&&&&&&&&&&&&&&&sci.med&&&&&&&0.91&&&&&&0.89&&&&&&0.90&&&&&&&396&&soc.religion.christian&&&&&&&0.87&&&&&&0.94&&&&&&0.90&&&&&&&398&&&&&&&&&&&&&&&avg&/&total&&&&&&&0.90&&&&&&0.90&&&&&&0.90&&&&&&1887&&
分析:对比CountVectorizer 和HashingVectorizer,全部特征的结果要更好一些,虽然加大了内存压力。
&&&&&&&&&&& 对比NB,SVM和KNN分类结果,SVM结果最好,接下来继续采用次算法。
6. GridSearch 搜索最优参数,见代码注释
&&def&testGridSearch():&&&&&&print&'*************************\nPipeline+GridSearch+CV\n*************************'&&&&&&text_clf&=&Pipeline([('vect',&CountVectorizer()),&&&&&&&&&&&&&&&&&&&&&&&('tfidf',&TfidfTransformer()),&&&&&&&&&&&&&&&&&&&&&&&('clf',&SGDClassifier()),])&&&&&&&&&&&&parameters&=&{&&&&&&&&&&'vect__ngram_range':&[(1,&1),&(1,&2)],&&&&&&&&'vect__max_df':&(0.5,&0.75),&&&&&&&&&&'vect__max_features':&(None,&5000,&10000),&&&&&&&&&&'tfidf__use_idf':&(True,&False),&&&&&&&&&&&&&&&&&'clf__alpha':&(0.00001,&0.000001),&&&&&&&&&&&&&&&&&'clf__n_iter':&(10,&50),&&&&&&&&}&&&&&&&&&&&&&&flag&=&0&&&&&&if&(flag!=0):&&&&&&&&&&grid_search&=&GridSearchCV(text_clf,parameters,n_jobs&=&1,verbose=1)&&&&&&&&&&grid_search.fit(twenty_train.data,&twenty_train.target)&&&&&&&&&&&&&print(&Best&score:&%0.3f&&%&grid_search.best_score_)&&&&&&&&&&&best_parameters&=&dict();&&&&&&&&&&&best_parameters&=&grid_search.best_estimator_.get_params()&&&&&&&&&&&&print(&Out&the&best&parameters&);&&&&&&&&&&&&for&param_name&in&sorted(parameters.keys()):&&&&&&&&&&&&&&&print(&\t%s:&%r&&%&(param_name,&best_parameters[param_name]));&&&&&&&&&&&&&&&&&&&&text_clf.set_params(clf__alpha&=&1e-05,&&&&&&&&&&&&&&&&&&&&&&&&&clf__n_iter&=&50,&&&&&&&&&&&&&&&&&&&&&&&&&tfidf__use_idf&=&True,&&&&&&&&&&&&&&&&&&&&&&&&vect__max_df&=&0.5,&&&&&&&&&&&&&&&&&&&&&&&&vect__max_features&=&None);&&&&&&&&text_clf.fit(twenty_train.data,&twenty_train.target)&&&&&&&&&&&&pred&=&text_clf.predict(twenty_test.data)&&&&&&&&&&&&accuracy=np.mean(pred&==&twenty_test.target)&&&&&&&&&&&&print&(&The&accuracy&of&twenty_test&is&%s&&%accuracy)&&&&&&&&&&&print(metrics.classification_report(twenty_test.target,&pred,target_names=twenty_test.target_names))&&&&&&array&=&metrics.confusion_matrix(twenty_test.target,&pred)&&&&&&print&array&&
*************************&&Pipeline+GridSearch+CV&&*************************&&The&accuracy&of&twenty_test&is&0.&&&&&&&&&&&&&&&&&&&&&&&&&&precision&&&&recall&&f1-score&&&support&&&&&&&&&&&&&&&alt.atheism&&&&&&&0.95&&&&&&0.84&&&&&&0.89&&&&&&&319&&&&&&&&&&&comp.graphics&&&&&&&0.90&&&&&&0.92&&&&&&0.91&&&&&&&389&&&comp.sys.mac.hardware&&&&&&&0.92&&&&&&0.95&&&&&&0.93&&&&&&&385&&&&&&&&&&&&&&&&&sci.med&&&&&&&0.95&&&&&&0.91&&&&&&0.93&&&&&&&396&&soc.religion.christian&&&&&&&0.89&&&&&&0.96&&&&&&0.92&&&&&&&398&&&&&&&&&&&&&&&avg&/&total&&&&&&&0.92&&&&&&0.92&&&&&&0.92&&&&&&1887&&
1)每一个算法会输出分类结果报表
分类结果报表,其中:
准确率=被识别为该分类的正确分类记录数/被识别为该分类的记录数召回率=被识别为该分类的正确分类记录数/测试集中该分类的记录总数F1-score=2(准确率 * 召回率)/(准确率 + 召回率),F1-score是F-measure(又称F-score)beta=1时的特例support=测试集中该分类的记录总数
2)混淆矩阵
array&=&metrics.confusion_matrix(twenty_test.target,&pred)&&print&array&&
SVM分类结果的混淆矩阵,类别数n,结果是一个n*n的矩阵,每一行的所有数字之和表示测试集中该分类的记录总数,等于结果报表中的support值。
[[268&&&7&&&1&&&7&&36]&&&[&&5&359&&17&&&3&&&5]&&&[&&0&&12&366&&&6&&&1]&&&[&&4&&16&&13&359&&&4]&&&[&&6&&&6&&&1&&&4&381]]&&&&&&categories&=&['alt.atheism',&&&&&&&&&&&&&&&'soc.religion.christian',&&&&&&&&&&&&&&&'comp.graphics',&&&&&&&&&&&&&&&'comp.sys.mac.hardware',&&&&&&&&&&&&&&&&'sci.med']&&
其中对角线上的元素表示正确分类结果数目,如comp.graphics 测试集中有319个文档记录,在这里有268个文档被分类正确,其他文档散落在了其他分类中。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:30972次
排名:千里之外
原创:34篇
转载:60篇
(6)(1)(27)(11)(2)(2)(1)(2)(8)(20)(4)(9)(1)(3)

我要回帖

更多关于 sklearn 文本特征提取 的文章

 

随机推荐