赞
踩
本文的应用场景是对文本类字段进行预处理(包括分词、词语频次计算)、常用分类模型建模以及模型参数调优,对刚接触文本分类建模的同学能够有一个完整的操作路径呈现。
目录
- import pandas as pd
- import numpy as np
- import jieba
- import re
- from opencc import OpenCC #繁体转简体
- from sklearn import preprocessing
-
- from sklearn.linear_model import LogisticRegression
- from bayes_opt import BayesianOptimization
- from sklearn.svm import SVC
- from sklearn.tree import DecisionTreeClassifier
- from sklearn.ensemble import RandomForestClassifier
- from sklearn.model_selection import train_test_split
- import xgboost as xgb
-
- import time

- '''假设已经有一个待处理的数据集data,
- 已转换为dataframe形式,
- 包含一个特征列name和一个预测列category'''
-
- # 由于后续划分训练集和测试集时,若训练集分类数量小于2则会报错,
- # 因此这里筛选分类数量大于50的数据,避免出现某分类数量小于2的情况
-
- filtered_values = value_counts[value_counts < 50].index.tolist()
- print(filtered_values) #输出被删除的分类
- data=data[~data['category'].isin(filtered_values)]
- print(data.shape)
-
-
- cc = OpenCC('D:/python/python3.9.13/Lib/site-packages/opencc/config/t2s') #繁体转简体文件
-
- #清洗name字段,可根据字段的特点做特殊化处理,
- #这里作了去掉除中文数字英文外的字符、英文统一小写、中文繁体转简体的操作
- data['name_clean'] = data['name'].apply(lambda x: cc.convert(re.sub(r'[\u4e00-\u9fa5a-zA-Z0-9]','',x).lower()
-
- #jieba分词
- data['jieba_cut'] = data['name_clean'].apply(lambda i:jieba.cut(i))
- data['jieba_cut'] =[' '.join(i) for i in data['jieba_cut']]
-
-
- # 将文本标签转化为数字
- lbl_enc = preprocessing.LabelEncoder()
- y = lbl_enc.fit_transform(data.category.values.reshape(-1, 1))
- X= data.jieba_cut.values
-
- # 将数据分成训练和验证集
- xtrain, xtest, ytrain, ytest = train_test_split(X, y, stratify=y, random_state=42, test_size=0.3, shuffle=True)
- print (xtrain.shape)
- print (xtest.shape)
-
- # 使用TF-IDF来fit训练集和测试集(半监督学习)
-
- def number_normalizer(tokens):
- """ 将所有数字标记映射为一个占位符(Placeholder)。
- 对于许多实际应用场景来说,以数字开头的tokens不是很有用,
- 但这样tokens的存在也有一定相关性。 通过将所有数字都表示成同一个符号,可以达到降维的目的。
- """
- return ("#NUMBER" if token[0].isdigit() else token for token in tokens)
-
- class NumberNormalizingVectorizer(TfidfVectorizer):
- def build_tokenizer(self):
- tokenize = super(NumberNormalizingVectorizer, self).build_tokenizer()
- return lambda doc: list(number_normalizer(tokenize(doc)))
-
- stwlist=[] #停用词,可自定义
- tfv = NumberNormalizingVectorizer(min_df=3,
- max_df=0.5,
- max_features=None,
- ngram_range=(1, 2),
- use_idf=True,
- smooth_idf=True,
- stop_words = stwlist
- )
-
- tfv.fit(list(xtrain) + list(xtest))
- xtrain_tfv = tfv.transform(xtrain)
- xtest_tfv = tfv.transform(xtest)
-

TF-IDF(Term Frequency-Inverse Document Frequency)和Word Counts(词频统计)都是文本处理中常用的技术,但它们有一些不同点。
定义
特点
计算公式
其中,tf 表示单词在文档中的出现频率,idf 表示某个单词在整个语料库中的出现频率,公式如下:
应用场景
综上,如果你需要提取文本中的关键信息并进行分类或搜索,应该使用 TF-IDF;如果你只是统计文本中的出现次数,并不需要考虑文本中关键词的重要性,则可以使用 Word Counts。
附上Word Counts的使用代码
- from sklearn.feature_extraction.text import CountVectorizer
- # 词汇计数(Word Counts)
- ctv = CountVectorizer(min_df=3,
- max_df=0.5,
- ngram_range=(1,2))
-
- ctv.fit(list(xtrain) + list(xtest))
- xtrain_ctv = ctv.transform(xtrain)
- xtest_ctv = ctv.transform(xtest)
- #为了初步筛选适合的模型,以字典容纳常用的分类模型,并以各个模型的默认参数形式进行训练
-
- start_time=time.time()
- clf_dict={"逻辑回归":LogisticRegression(),"SVM":SVC(),"朴素贝叶斯":MultinomialNB(),"决策树":DecisionTreeClassifier(),"随机森林":RandomForestClassifier(),"XGBOOST":xgb.XGBClassifier()}
-
- for clf_name in clf_dict:
- clf=clf_dict[clf_name]
- clf.fit(xtrain_tfv,ytrain)
- print("模型得分:",clf_name,":",clf.score(xtest_tfv,ytest))
- print("模型对象:",clf.get_params())
- end_time = time.time()
- print("模型运行时间:",round((end_time-start_time)/60,2),'分钟')
-
-
模型参数调优常用的方法有三种:随机搜索法、贝叶斯优化法以及网格搜索法,一般所耗时间从小到大。由于前两种方法都带有一定的随机性,而本次优化的目的是希望找到全局最优解,因此选择网格搜索法作为此次模型优化的方法。
- #网格搜索法调参,以逻辑回归模型为例
- clf=LogisticRegression()
-
- #模型的参数集合
- params={'penalty': ['l1', 'l2'],
- 'C': [0.01, 0.1, 1, 10, 100],
- 'max_iter': [10, 100, 1000],
- 'solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag']}
-
-
-
- grid_search = GridSearchCV(estimator=clf, param_grid=params, cv=5)
- grid_search.fit(xtrain_tfv , ytrain)
-
-
- # 网格搜索训练后的副产品
- print("模型的最优参数:",grid_search.best_params_)
- print("最优模型分数:",grid_search.best_score_)
- print("最优模型对象:",grid_search.best_estimator_)
-
-

在使用 GridSearchCV
进行网格搜索时,参数 cv
是用来指定交叉验证的折数(folds)或者交叉验证生成器。它决定了将数据集划分为多少个部分来进行交叉验证。
通常情况下,较小的 cv
值会导致训练时间更快,但估计的性能可能会有较大的方差。较大的 cv
值会导致训练时间更长,但估计的性能通常会更稳定。
选择合适的 cv
值需要考虑以下几个因素:
数据集的大小:如果数据集较小,使用较小的 cv
值可能更合适,以避免过度拆分数据。而对于较大的数据集,可以选择较大的 cv
值以更好地利用数据。
计算资源:较大的 cv
值需要更长的训练时间和更多的计算资源。如果你的计算资源有限,可能需要选择较小的 cv
值。
模型复杂度:如果你的模型非常复杂,较小的 cv
值可能不足以准确评估模型的性能。在这种情况下,可以考虑使用较大的 cv
值。
一般来说,cv
值可以在 3 到 10 之间选择。常见的选择有 5 折交叉验证 (cv=5
) 和 10 折交叉验证 (cv=10
)。
网格搜索(Grid Search):
随机搜索(Random Search):
贝叶斯优化(Bayesian Optimization):
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。