# text-classify-course **Repository Path**: luu/text-classify-course ## Basic Information - **Project Name**: text-classify-course - **Description**: text-classify-course - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-11-09 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 整体方案 ![](整体设计.png) ### 介绍 主要分成3大模块: 1. 特征工程模块,主要是对原始数据进行处理 2. 通过模型训练调参对模型进行保存 3. 应用工程,主要复用训练好的模型和特征工程处理,进行接口的调用 ### 技术难点 #### 特征工程 1. 使用jieba分词后关键字非常多,造成的数据维度很大,对训练的效率影响很大 2. jieba分词失去了原始语义的分析,可能数据工程这块的效果上限就不是太高 #### 模型选择与调优 1. 这个是一个有监督的分类问题,从之前学过的知识来看主要可以采用下面几种方案 a. logistcregrssion b. svm c. desitiontree d. xgboost 2. kmeans 和 dbscan 属于无监督的聚类学习,和我们要解决的问题没有直接的联系 3. 从之前的学习经验上来看,xgboost的性能比较出色,所以第一优选的目标在xgboost上展开 4. 模型的融合目前也没什么经验和时间去研究,先放一放 ## 详细设计 ### 数据探索 [1_data_explore.ipynb](./notebook/1_data_explore.ipynb) ![count_plot.png](count_plot.png) #### 总结 1. 类型是从1开始的,最好改成从0开始计算 2. 各个类型的分类很不均,集中在2,3,5分类, 在模型校验的时候要设置权重 ### 数据特征工程 ![](特征工程.png) #### 遇到的问题 1. 由于准备的数据没有head栏,导致默认的第一行会被当做标题,最后才发现 2. 直接用jieba分词后有差不多36000多列,使用xgboost很慢,没有耐心等下去,必须要想做降维处理 #### code 1. [tf-dif](src/core/tf_idf.py) 2. [分词](src/core/TextUtils.py) 3. [特征工程转换](src/core/PandasUtils.py) ``` def convert2KeywordsDataframs(values): typemap = {} keywordmap = {} keywordset = set() index = 0; # 1. 相对每一行文本进行分词处理,同时记录分词后的2维数组 和 类型之间的映射关系 for type, text in values: map = textutils.dict(text) typemap[index] = type keywordmap[index] = map keywordset = keywordset.union(map.keys()) # print(map.keys()) index = index + 1 # 2. 合并所有的行的关键字,作为总的特征列名称,总计有3w多条,实在太大了 columns = list(keywordset) columns.sort() row_datas = [] row_types = [] # 3. 计算每一行数据对应在所有关键字中的出现频率,如果没有出现计算为0 for index in range(len(keywordmap)): # print(index) value_map = keywordmap.get(index) # print(value_map) row = [] row_types.append(typemap.get(index)) for column in columns: # print(column) if value_map.get(column): row.append(value_map.get(column)) else: row.append(0) row_datas.append(row) # 4. 根据所有的数据和特征,使用 scklearn提供的chi函数进行降维,从 3w多行直接降低到 500 chi_dataX = chi(pd.DataFrame(data=row_datas, columns=columns), row_types, 500) # 5. 使用scklearn提供的tf_dif函数对降维后的数据进行数据标准化处理,同时缓存训练过的数据转换器 tfidf_dataX = tf_idf.tf_dif_df(chi_dataX) return { "X": tfidf_dataX, "y": row_types } ``` ### 模型的训练 [测试代码](src/test/MainTest3.py) [日志](src/test/MainTest3.log) 1. LR accuracy_score: 0.8728263146867798 2. svm accuracy_score: 0.8981772470144563 3. xgboost accuracy_score: 0.9991619526503247 根据之前学习的经验和实际的测试(全部未做模型优化)的情况,xgboost的性能明显要好于逻辑回归和svm模型,所以之后就主要在 xgboost 上训练 #### 1. 确定n_estimators [src/test/Main_1_xgb_cv_estimate.py](src/test/Main_1_xgb_cv_estimate.py) 初步的到的值为: n_estimators #### 2. 确定树的权重和深度 [src/test/Main_2_xgb_cv_weight.py](src/test/Main_2_xgb_cv_weight.py) 初步得到的结论是: {'max_depth': 9, 'min_child_weight': 1} #### 3. 使用gridsearchcv进行模型预测和保存 [src/test/Main_3_xgb_save_model.py](src/test/Main_3_xgb_save_model.py) ``` Classification report for classifier: precision recall f1-score support 0 1.00 1.00 1.00 54 1 0.99 0.98 0.98 97 2 0.99 1.00 0.99 1271 3 0.98 0.98 0.98 1268 4 0.98 0.97 0.98 227 5 0.96 0.98 0.97 810 6 0.97 0.97 0.97 303 7 0.99 0.93 0.96 206 8 0.98 0.98 0.98 163 9 1.00 0.98 0.99 278 10 1.00 0.98 0.99 96 micro avg 0.98 0.98 0.98 4773 macro avg 0.99 0.98 0.98 4773 weighted avg 0.98 0.98 0.98 4773 Confusion matrix: [[ 54 0 0 0 0 0 0 0 0 0 0] [ 0 95 2 0 0 0 0 0 0 0 0] [ 0 1 1265 5 0 0 0 0 0 0 0] [ 0 0 3 1244 0 15 3 0 3 0 0] [ 0 0 1 1 221 3 1 0 0 0 0] [ 0 0 1 10 1 793 2 2 0 1 0] [ 0 0 0 3 0 5 295 0 0 0 0] [ 0 0 1 3 4 5 2 191 0 0 0] [ 0 0 0 1 0 2 1 0 159 0 0] [ 0 0 4 0 0 1 0 0 0 273 0] [ 0 0 1 1 0 0 0 0 0 0 94]] accuracy_score: 0.9813534464697256 ``` 最终的效果还可以,停止优化 ### 模型的应用 1. [src/core/TextClassfier.py](src/core/TextClassfier.py) 2. [src/core/webapp.py](src/core/webapp.py) 3. [run.sh](run.sh) 4. [测试数据结果](data/testing_result.csv) ### 总结 #### 项目各个阶段中的坑 1. pandas.read_csv 默认会读取第一行作为列名 2. 在数据维度很大的情况下,xgboost很慢,必须要做降维 3. 不同版本的scklearn的兼容性不太一样,本项目最终采用python3.7 4. 由于各个标签的数目不太均等,所以在做验证的时候要特别小心,好在sckilearn都封装进去了 #### 心得体会 1. 在训练过程中还是要有耐心,训练需要时间 2. xgboost的训练慢,但是效果确实不错 3. 先复习一下之前4周的课程,再做项目,感觉又掌握了一些 #### 项目不足与改进设想 1. 各种复杂的算法全部是调用现有的函数实现的,基础实在太差。后面继续再了解下原理吧 2. 目前还是xgboost的简单实现,优化的也不是很多,有时间的话还可以继续优化下去 3. 可以尝试使用深度学习