AI應用開發相關目錄
本專欄包括AI應用開發相關內容分享,包括不限于AI算法部署實施細節、AI應用后端分析服務相關概念及開發技巧、AI應用后端應用服務相關概念及開發技巧、AI應用前端實現路徑及開發技巧
適用于具備一定算法及Python使用基礎的人群
- AI應用開發流程概述
- Visual Studio Code及Remote Development插件遠程開發
- git開源項目的一些問題及鏡像解決辦法
- python實現UDP報文通信
- python實現日志生成及定期清理
- Linux終端命令Screen常見用法
- python實現redis數據存儲
- python字符串轉字典
- python實現文本向量化及文本相似度計算
- python對MySQL數據的常見使用
- 一文總結python的異常數據處理示例
- 基于selenium和bs4的通用數據采集技術(附代碼)
- 基于python的知識圖譜技術
- 一文理清python學習路徑
- Linux、Git、Docker常用指令
- linux和windows系統下的python環境遷移
- linux下python服務定時(自)啟動
- windows下基于python語言的TTS開發
- python opencv實現圖像分割
- python使用API實現word文檔翻譯
- yolo-world:”目標檢測屆大模型“
- 爬蟲進階:多線程爬蟲
- python使用modbustcp協議與PLC進行簡單通信
- ChatTTS:開源語音合成項目
- sqlite性能考量及使用(附可視化操作軟件)
- 拓撲數據的關鍵點識別算法
- python腳本將視頻抽幀為圖像數據集
- 圖文RAG組件:360LayoutAnalysis中文論文及研報圖像分析
- Ubuntu服務器的GitLab部署
- 無痛接入圖像生成風格遷移能力:GAN生成對抗網絡
- 一文理清OCR的前世今生
- labelme使用筆記
- HAC-TextRank算法進行關鍵語句提取
- Segment any Text:優質文本分割是高質量RAG的必由之路
- 無痛接入FastText算法進行文本分類
文章目錄
- AI應用開發相關目錄
- 簡介
- 數據集情況
- 環境部署:
- 代碼及使用
簡介
FastText的特點如下:
速度:FastText的設計初衷就是為了高效,它的訓練速度比許多其他文本處理工具快得多。
簡單:FastText的模型結構相對簡單,易于理解和實現。
準確性:盡管模型簡單,但FastText在許多文本分類任務中都能達到與其他復雜模型相媲美的準確度。
多功能性:除了文本分類,FastText還可以用于詞嵌入的生成,它可以捕捉到詞的語義信息,比如相似的詞在嵌入空間中會彼此接近。
支持多語言:FastText能夠處理多種語言的文本,這對于跨語言文本分類任務非常有用。
無需大量數據:對于一些小語種或者數據稀缺的場景,FastText也能夠有效工作。
FastText的核心思想是將文本數據轉換成向量表示,然后使用這些向量進行分類或相似度計算。它使用了一種層次化的softmax技術來加速訓練過程,并采用了負采樣來改善分類性能。
在文本分類任務中,FastText將文本轉換成一系列的n-gram,然后通過模型學習每個n-gram的權重,最后將這些權重組合起來,形成整個文本的向量表示。這個向量隨后被送入一個softmax層進行分類。
此外,文本分類算法在大模型領域也具有一定的應用前景:
訓練FastText分類器,從大量領域不可知數據中識別領域內數據。具體來說,為了訓練FastText分類器,選擇了一定數量的領域內數據作為正面樣本,并選擇了同等數量的領域外數據作為負面樣本。訓練好的二元分類器隨后被用來從通用語料庫(例如,網絡語料庫)中選擇領域內數據;其次,應用過濾器,以確保領域內數據(包括原始的領域內語料庫和選擇的數據)具有高教育價值。通過這種方式,可以提高過濾后的領域內數據的質量,進而提高模型的性能。
數據集情況
停用詞集:
原始數據集:
環境部署:
https://pypi.org/project/fasttext-wheel/#files
下載對應版本的fasttext.whl文件,直接pip會出現輪子文件構建失敗的現象。
此外下載一下處理繁體文本的文字:
pip install langconv -i https://pypi.tuna.tsinghua.edu.cn/simple
代碼及使用
項目文件夾總體情況:
數據清理文件text_cleaner.py:
# -*- coding: utf-8 -*-from types import MethodType, FunctionType
import jieba
import re
# 導入用于繁體/簡體轉換的包
from langconv import *def clean_txt(raw):fil = re.compile(r"[^0-9a-zA-Z\u4e00-\u9fa5]+")return fil.sub(' ', raw)def seg(sentence, sw, apply=None, cut_all=False):"""對中文文本去特殊符號、去停用詞、分詞:param sentence: 原始中文文本:param sw::param apply::param cut_all::return: 分詞后中文文本"""if isinstance(apply, FunctionType) or isinstance(apply, MethodType):sentence = apply(sentence)return ' '.join([i for i in jieba.cut(sentence, cut_all=cut_all) if i.strip() and i not in sw])def stop_words():with open('stopwords.txt', 'r', encoding='utf-8') as swf:stopwords = [i.strip() for i in swf.readlines()]return stopwordsdef cht_to_chs(line):"""中文繁體文本轉簡體:param line: 原始文本:return: 中文簡體文本"""line = Converter('zh-hans').convert(line)line.encode('utf-8')return linedef replace_text(input_str, str_targ, str_rep):if isinstance(input_str, list):return [replace_text(s, str_targ, str_rep) for s in input_str]return input_str.replace(str_targ, str_rep)# 對某個sentence進行處理:
if __name__ == '__main__':content = '海爾(Haier)新風機 室內外空氣交換 恒氧新風機 XG-100QH/AA'res = seg(content.lower().replace('\n', ''), stop_words(), apply=clean_txt)print(res)test = stop_words()print(test)
數據預處理步驟,生成中間csv文檔,訓練集文檔,驗證集文檔:
# -*- coding: utf-8 -*-import pandas as pd
import numpy as np
import random
from text_cleaner import *
from tqdm import tqdm
import os
import re
from sklearn.utils import shuffledef load_df(file_path, encoding='utf-8', drop_dup=True, drop_na=True):"""從csv文件讀取dataframe:param file_path: csv文件路徑:param encoding: 編碼,默認 UTF-8:param drop_dup: 去掉重復行:param drop_na: 去掉空行:return: dataframe"""df = pd.read_csv(file_path, encoding=encoding, engine='python')if drop_dup:df = df.drop_duplicates()if drop_na:df = df.dropna()return dfdef write_txt(file_name, df_data, delimiter=' ', fmt="%s", encoding='utf-8'):"""把dataframe寫入txt,用于DF轉fasttext訓練集:param delimiter::param file_name: 寫入的txt文件路徑:param df_data: <label> <text>型的DataFrame:param fmt: 格式,默認為字符串:param encoding: 編碼,默認為 UTF-8:return:"""np.savetxt(file_name, df_data.values, delimiter=delimiter, fmt=fmt, encoding=encoding)def dataframe_split(df_text, train_ratio):"""將dataframe按比例分割:param df_text: 原始dataframe:param train_ratio: 訓練集占比:return: 訓練集和驗證集"""df_text = shuffle(df_text)train_set_size = int(len(df_text) * train_ratio)valid_set_size = int(len(df_text) * (1 - train_ratio))df_train_data = df_text[:train_set_size]df_valid_data = df_text[train_set_size:(train_set_size + valid_set_size)]return df_train_data, df_valid_datadef count_diff_in_col(df_text, col_name):"""統計某一列不同種類的個數:param df_text: dataframe:param col_name: 需要統計的列名:return: 一個字典"""col_set = set(df_text[col_name].values)col_list = list(df_text[col_name].values)compute = dict()for item in col_set:compute.update({item: col_list.count(item)})return dict(sorted(compute.items()))def drop_rows_where_col_has(dataframe, col_name, target):"""刪除 dataframe中, col_name列包含target的行:param dataframe::param col_name::param target::return: 新的dataframe"""return dataframe.drop(dataframe[dataframe[col_name] == target].index)def df_data_augmentation(dataframe, col_label='label', col_text='text', num_sample=50, sample_length=18):"""將每一類標簽的樣本擴充至指定數量:param dataframe::param col_label::param col_text::param num_sample: 擴充后每個種類樣本的數量,默認50:param sample_length: 樣本文本的長度, 默認18:return: 返回擴充后的dataframe 和 記錄不同標簽樣本的字典"""dict_tmp = count_diff_in_col(dataframe, col_label)df_sample = dataframe.copy(deep=True)for key in list(dict_tmp.keys()):if dict_tmp[key] < num_sample:df_tmp = df_sample[(df_sample[col_label] == key)]list_text = []for text in df_tmp[col_text].values.tolist():list_text.extend(text.split())while dict_tmp[key] < num_sample:str_tmp = ' '.join(random.sample(list_text, sample_length))df_sample = df_sample.append({col_label: key, col_text: str_tmp}, ignore_index=True)dict_tmp.update({key: dict_tmp[key] + 1})return df_sample, dict_tmpdef repalce_df_text(dataframe, col_name, str_targ, str_rep):"""將dataframe中某一列的字符串中 str_tage 替換為 str_rep:param dataframe::param col_name::param str_targ::param str_rep::return:"""li0 = dataframe[col_name].values.tolist()li1 = replace_text(li0, str_targ, str_rep)if len(li1) == len(li0):dataframe[col_name] = li1return dataframeelse:print('Lenghth of dataframe has been changed !')return -1def df_cut_ch(dataframe, col_name, save_path=''):"""對 dataframe的col_name列中的中文文本分詞, 默認cut_all:param dataframe::param col_name::param save_path:保存路徑,默認不保存:return:"""df_cut = dataframe.copy(deep=True)text_cut = []stopwords = stop_words()for text in tqdm(dataframe[col_name].astype(str)):datacutwords = ' '.join([i for i in jieba.cut(text) if i.strip() and i not in stopwords])text_cut.append(datacutwords)del df_cut[col_name]df_cut[col_name] = text_cutif len(save_path):df_cut.to_csv(save_path, encoding='utf_8_sig', index=False)return df_cut# 頭條數據抽取方法
def getdata(filepath):data = pd.read_table(filepath, encoding='utf-8', sep='\n', header=None)pattern = re.compile('(\d+)_!_(.*?)_!_(.*?)_!_(.*?)_!_([\s\S]*)')datanew = data[0].str.extract(pattern)columsdic = {0:'id',1:'num',2:'catgor',3:'content',4:'keys'}datanew.rename(columns=columsdic, inplace=True)datanew['text'] = datanew['content'] + datanew['keys']datanew['pre'] = '__label__'datanew['labels'] = datanew['pre']+datanew['catgor']datanew = datanew.loc[:, ['labels', 'text']]return datanewif __name__ == '__main__':basepath = os.getcwd()file = r'toutiao_cat_data.txt'filepath = os.path.join(basepath, file)print(filepath)# print(getdata(filepath))cutfile = r'cutdata.csv'cutfilepath = os.path.join(basepath, cutfile)datanotcut = getdata(filepath)datacut = df_cut_ch(dataframe=datanotcut, col_name='text', save_path=cutfilepath)data = pd.read_csv(cutfilepath, encoding='utf-8')data = shuffle(data)df_train_data, df_valid_data = dataframe_split(df_text=data, train_ratio=0.7)write_txt(file_name=r'df_train_data.txt', df_data=df_train_data, encoding='utf-8')write_txt(file_name=r'df_valid_data.txt', df_data=df_valid_data, encoding='utf-8')
模型訓練及測試:
# -*- coding: utf-8 -*-import fasttext
import pandas as pd
from sklearn.metrics import classification_report
import os
import time
import rereport_index = 0def train_model(train_file, dim=100, epoch=100, lr=0.5, loss='softmax', wordNgrams=2, save_dir=''):"""訓練fasttext模型并保存在 save_dir 文件夾, 詳細參數參閱https://fasttext.cc/docs/en/python-module.html#train_supervised-parameters:param train_file: 訓練數據文件:param dim: 詞向量大小, 默認100:param epoch: 默認100:param lr: 學習率, 默認0.5:param loss: 損失函數,默認softmax, 多分類問題推薦 ova:param wordNgrams: 默認2:param save_dir: 模型保存文件夾,默認不保存:return: 文本分類器模型"""classifier = fasttext.train_supervised(train_file, label='__label__', dim=dim, epoch=epoch,lr=lr, wordNgrams=wordNgrams, loss=loss)if len(save_dir):# model_name = f'model_dim{str(dim)}_epoch{str(epoch)}_lr{str(lr)}_loss{str(loss)}' \# f'_ngram{str(wordNgrams)}_{str(report_index)}.model'# if not os.path.exists(save_dir):# os.mkdir(save_dir)# classifier.save_model(os.path.join(save_dir, model_name))classifier.save_model(savepath)return classifierdef give_classification_report(classifier, valid_csv, col_label=0, col_text=1, report_file=''):"""使用 classification_report 驗證 fasttext 模型分類效果,需在_FastText 類中添加dict_args()屬性:param classifier: fasttext文本分類模型:param valid_csv: 驗證數據集,需要csv格式:param col_label: 標簽列名,默認 'label':param col_text: 文本列名, 默認'text':param report_file: 保存report文件名,默認不保存:return: classification report"""df_valid = pd.read_table(valid_csv, sep='\n', header=None)print(df_valid)pattern = re.compile('(.*?) ([\s\S]*)')datause = df_valid[0].str.extract(pattern)print(classifier.predict(str(datause.iloc[0,1]))[0][0])alluse = []for i in range(datause.shape[0]):predict = classifier.predict(str(datause.iloc[i,1]))[0][0]alluse.append(predict)datause["predicted"] = alluseprint(datause)tags = list(set(datause[0]))report = classification_report(datause[0].tolist(), datause["predicted"].tolist(), target_names=tags)return report
train_file = r'df_train_data.txt'
savepath = r'model.bin'
rainmodel = train_model(train_file=train_file, save_dir=savepath)
modeluse = fasttext.load_model(r'model.bin')
valid_csv = r'df_valid_data.txt'
report_file = r'report_file.txt'
report = give_classification_report(classifier=modeluse, valid_csv=valid_csv, col_label= 0,col_text =1,report_file = '')
print(report)
precision recall f1-score support__label__news_edu 0.90 0.89 0.90 5835__label__news_culture 0.95 0.93 0.94 10658__label__news_travel 0.88 0.91 0.89 8519__label__news_world 0.92 0.92 0.92 7961__label__news_finance 0.91 0.92 0.92 11853__label__news_house 0.85 0.84 0.84 8213__label__news_tech 0.94 0.94 0.94 8749__label__news_car 0.94 0.93 0.93 5324__label__news_sports 0.90 0.89 0.89 7556__label__news_story 0.97 0.96 0.96 11319__label__news_game 0.88 0.77 0.82 1880__label__stock 0.88 0.90 0.89 12442__label__news_agriculture 0.85 0.87 0.86 6390__label__news_military 0.84 0.86 0.85 7993
__label__news_entertainment 0.35 0.06 0.10 114accuracy 0.90 114806macro avg 0.86 0.84 0.84 114806weighted avg 0.90 0.90 0.90 114806
其中數據集可參考:https://github.com/aceimnorstuvwxz/toutiao-text-classfication-dataset