將關(guān)于地鐵的留言文本進(jìn)行自動分類。
不要著急,一步步來。
導(dǎo)入需要的庫。
import numpy as np
import pandas as pd
import jieba # 分詞
import re # 正則
from fnmatch import fnmatch # 通配符
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_extraction.text import CountVectorizer # 文本向量化
from sklearn.feature_extraction.text import TfidfTransformer # 文本向量化
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
from sklearn import svm # 支持向量機模型
定義函數(shù),加載用來分詞的自定義詞典。
# 可根據(jù)實際需要,手動調(diào)整自定義詞典路徑和自定義詞匯
def jieba_fenci():
# 在jieba中加載自定義的地鐵線路名、地鐵站點名詞典
jieba.load_userdict("mydict_line.csv")
jieba.load_userdict("mydict_station.csv")
# 一些在市民留言中常見的高頻的詞,發(fā)現(xiàn)了就手動添加進(jìn)去
myaddword_ls = ["公共自行車", "金溪園"]
for w in myaddword_ls:
jieba.add_word(w)
定義函數(shù),生成自己的停用詞詞典,得到一個文件。
我找的4個停用詞詞典下載地址:https://gitcode.net/mirrors/goto456/stopwords/-/tree/master
后面我會把自己整合好的停用詞詞典上傳。
# 這段代碼只用跑一次,以后可以直接用這個文件
# 自己給停用詞文件起好名字(路徑),作為投入函數(shù)的參數(shù)
def get_mystopwords_file(mystopwords_file_name):
stopwords_path_ls = ["baidu_stopwords.txt", "cn_stopwords.txt", "hit_stopwords.txt", "scu_stopwords.txt"]
stopwords_set = set() # 集合可以自動去重
for p in stopwords_path_ls:
with open(p, 'r', encoding = 'utf-8') as stopwords_file:
for stopword in stopwords_file:
if u'\u4e00'<= stopword[0] <= u'\u9fff': # 只放中文的停用詞
stopwords_set.add(stopword.strip('\n'))
with open(mystopwords_file_name, 'w') as mystopwords_file:
for stopword in stopwords_set:
mystopwords_file.write(stopword + '\n')
定義函數(shù),讀取停用詞詞典文件,得到一個停用詞列表。
# 可以根據(jù)實際需要,手動添加或刪除停用詞
def get_mystopwords_list(mystopwords_file_name):
mystopwords_ls = []
with open(mystopwords_file_name, 'r') as mystopwords_file:
for stopword in mystopwords_file:
mystopwords_ls.append(stopword.strip('\n'))
# 對于一些高頻出現(xiàn)的、但對于分類沒什么特征幫助的詞,可以手動加進(jìn)停用詞列表
zdy_stopword = ["建議", "信訪", "杭州"]
for w in zdy_stopword:
mystopwords_ls.append(w)
# 對于一些停用詞表里有的、但認(rèn)為對后面分析有用的詞,可以手動從停用詞列表剔除
zdy_not_stopword = [] # 目前還沒想好剔除什么詞,所以列表是空的
for w in zdy_not_stopword:
mystopwords_ls.remove(w)
return mystopwords_ls
定義函數(shù),統(tǒng)一地鐵線路名稱格式。
# 投入?yún)?shù)是一個已經(jīng)分好詞的列表,返回一個處理好的列表
def unify_line_name(mylist):
num_dict = {1:'一', 2:'二', 3:'三', 4:'四', 5:'五', 6:'六', 7:'七', 8:'八', 9:'九', \
10:'十', 11:'十一', 12:'十二', 13:'十三', 14:'十四', 15:'十五', 16:'十六', 17:'十七', \
18:'十八', 19:'十九', 20:'二十', 21:'二十一', 22:'二十二', 23:'二十三'}
for i in range(len(mylist)):
if fnmatch(mylist[i], "*號線") or fnmatch(mylist[i], "*號地鐵"):
for j in range(len(num_dict),0,-1):
if str(j) in mylist[i] or num_dict[j] in mylist[i]:
mylist[i] = "地鐵" + str(j) + "號線"
break
if mylist[i] in ["機場快線", "機場軌道快線"]:
mylist[i] = "地鐵19號線"
return mylist
定義文本預(yù)處理的函數(shù),作用:去除無用字符、去除停用詞、統(tǒng)一地鐵線路名。
# 投入的參數(shù)是一個原始字符串,返回一個處理好的字符串(分好的詞之間空格連接)
# 要在使用這個函數(shù)之前弄好停用詞列表,列表名稱是mystopwords_ls
def mychuli(x):
# 僅保留漢字、英文字母、阿拉伯?dāng)?shù)字
mystr = ''.join(re.findall('[a-zA-Z0-9\u4e00-\u9fa5]',x))
# 分詞,每個字符串變成一個列表
mylist = jieba.lcut(mystr, cut_all = False)
# 統(tǒng)一線路名稱
mylist = unify_line_name(mylist)
# 去除停用詞
for word in mylist:
if word in mystopwords_ls:
mylist.remove(word)
return ' '.join(mylist)
定義模型實際應(yīng)用的函數(shù),輸入文本,輸出分類結(jié)果。
# 輸入一條文本,經(jīng)預(yù)處理后投進(jìn)支持向量機模型進(jìn)行預(yù)測
def mypre():
lebel_dict = dict(zip([0,1,2,3,4,5,6,7,8,9], le.inverse_transform([0,1,2,3,4,5,6,7,8,9])))
mytext = input("輸入要預(yù)測的文本:")
mytext_yichuli = mychuli(mytext)
print("文本預(yù)處理結(jié)果:{}".format(mytext_yichuli))
X_new = []
X_new.append(mytext_yichuli)
X_new_vec = tf.fit_transform(cv_new.fit_transform(X_new)).toarray()
y_new_pre = SVM.predict(X_new_vec)
print("模型預(yù)測的分類編號為:{}".format(y_new_pre[0]))
print("對應(yīng)的分類名稱為:{}".format(lebel_dict[y_new_pre[0]]))
讀取文本,去重。
# 讀取語料文件
df = pd.read_csv("xxx.csv")
print("去重前:")
print(df.info())
# 去除重復(fù)數(shù)據(jù)
df1 = df.drop_duplicates()
print("去重后:")
print(df1.info())
print(df1.head())
jieba_fenci() # 加載自定義的分詞詞典
get_mystopwords_file("mystopwords.txt") # 得到一個整合好的停用詞文件,只用跑一次
mystopwords_ls = get_mystopwords_list("mystopwords.txt") # 得到停用詞列表
# 新建一列yichuli_title,放已經(jīng)處理好的文本數(shù)據(jù)
df1['yichuli_title'] = df1['title'].apply(mychuli)
# 給類別進(jìn)行編號
le = LabelEncoder()
le.fit(df1['class1'])
df1['yichuli_label'] = le.transform(df1['class1'])
# 把處理好的結(jié)果寫入一個新的csv文件,方便以后使用
# 用gb18030編碼可實現(xiàn)外面打開這個文件看顯示正常中文,而不是亂碼
df1.to_csv("test0908_result.csv", columns = ['yichuli_title', 'yichuli_label', 'class1'], encoding = "gb18030")
構(gòu)建訓(xùn)練集、測試集。?
# 讀取已經(jīng)處理好的csv文件
df1 = pd.read_csv("test0908_result.csv", encoding = "gb18030")
# 構(gòu)建訓(xùn)練集、測試集
cv = CountVectorizer()
tf = TfidfTransformer()
X = df1['yichuli_title']
y = df1['yichuli_label']
X = tf.fit_transform(cv.fit_transform(X)).toarray()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)
print(X_train.shape)
print(X_test.shape)
訓(xùn)練模型。文章來源:http://www.zghlxwxcb.cn/news/detail-700523.html
SVM = svm.LinearSVC() #支持向量機分類器LinearSVC
SVM.fit(X_train, y_train)
y_pre = SVM.predict(X_test)
print("支持向量機模型結(jié)果:")
print(classification_report(y_test, y_pre))
# 支持向量機的混淆矩陣
svm_confuse = pd.DataFrame(confusion_matrix(y_test, y_pre))
print(svm_confuse)
預(yù)測新數(shù)據(jù)。文章來源地址http://www.zghlxwxcb.cn/news/detail-700523.html
cv_new = CountVectorizer(vocabulary = cv.vocabulary_) # vocabulary參數(shù)保證向量維度與訓(xùn)練集一致
mypre()
到了這里,關(guān)于Python 自然語言處理 文本分類 地鐵方面留言文本的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!