| from importlib import import_module |
| import torch |
| import pandas as pd |
| import pickle as pkl |
| from tqdm import tqdm |
| from numpy.linalg import norm |
| from utils import build_vocab, build_iterator |
| import numpy as np |
| import os |
| from sklearn.feature_extraction.text import CountVectorizer |
| import jieba |
| import joblib |
| from sklearn.model_selection import train_test_split |
| import fasttext |
| import gradio as gr |
|
|
|
|
| MAX_VOCAB_SIZE = 10000 |
| UNK, PAD = '<UNK>', '<PAD>' |
| module = import_module("models.TextCNN") |
| dataset = 'THUCNews' |
| embedding = 'embedding_SougouNews.npz' |
| config = module.Config(dataset, embedding) |
| model = module.Model(config).to(config.device) |
| model.load_state_dict(torch.load(config.save_path,map_location='cpu')) |
| model.eval() |
|
|
|
|
| def build_dataset(content, config, ues_word): |
| if ues_word: |
| tokenizer = lambda x: x.split(' ') |
| else: |
| tokenizer = lambda x: [y for y in x] |
| if os.path.exists(config.vocab_path): |
| vocab = pkl.load(open(config.vocab_path, 'rb')) |
| else: |
| vocab = build_vocab(config.train_path, tokenizer=tokenizer, max_size=MAX_VOCAB_SIZE, min_freq=1) |
| pkl.dump(vocab, open(config.vocab_path, 'wb')) |
| def load_dataset(pad_size=32): |
| contents = [] |
| words_line = [] |
| token = tokenizer(content) |
| seq_len = len(token) |
| if pad_size: |
| if len(token) < pad_size: |
| token.extend([PAD] * (pad_size - len(token))) |
| else: |
| token = token[:pad_size] |
| seq_len = pad_size |
| for word in token: |
| words_line.append(vocab.get(word, vocab.get(UNK))) |
| contents.append((words_line, -1, seq_len)) |
| return contents |
| train = load_dataset(config.pad_size) |
| return vocab, train |
|
|
| def wordvector(config,df,pad_size=32): |
| wordvectorlist = [] |
| answerlist = [] |
| sentences = [] |
| department = [] |
| tokenizer = lambda x: [y for y in x] |
| if os.path.exists(config.vocab_path): |
| vocab = pkl.load(open(config.vocab_path, 'rb')) |
| else: |
| vocab = build_vocab(config.train_path, tokenizer=tokenizer, max_size=MAX_VOCAB_SIZE, min_freq=1) |
| pkl.dump(vocab, open(config.vocab_path, 'wb')) |
| for row in df.index: |
| content = df.loc[row]['ask'] |
| answer = df.loc[row]['answer'] |
| department.append(df.loc[row]['department']) |
| answerlist.append(answer) |
| sentences.append(content) |
| words_line = [] |
| token = tokenizer(content) |
| if pad_size: |
| if len(token) < pad_size: |
| token.extend([PAD] * (pad_size - len(token))) |
| else: |
| token = token[:pad_size] |
| seq_len = pad_size |
| for word in token: |
| words_line.append(vocab.get(word, vocab.get(UNK))) |
| vector = words_line |
| wordvectorlist.append(vector) |
| return wordvectorlist, answerlist |
| def cos_similarity_test(vector,word_vector_list): |
| best_cosine = -10 |
| for i in range(len(word_vector_list)): |
| best_index = 0 |
| B = word_vector_list[i] |
| cosine = np.dot(vector, B) / (norm(vector) * norm(B)) |
| if cosine > best_cosine: |
| best_cosine = cosine |
| best_index = i |
| return best_index |
|
|
| def predict_single_text(text,flag): |
| |
| ft_model = None |
| if flag == 4: |
| ft_model = fasttext.load_model("./fasttext_model_erke.bin") |
| if flag == 5: |
| ft_model = fasttext.load_model("./fasttext_model_waike.bin") |
| prediction = ft_model.predict([text], k=1) |
| if prediction: |
| label = prediction[0][0][len('__label__'):] |
| str = prediction[0][0][0] |
| label = str[9:-1] |
| |
| confidence = prediction[1][0] |
| return label, confidence |
| else: |
| return None, None |
| def proceed(content,NumOfChamber,content_vector): |
| with open('./stop_words.txt', 'r', encoding="utf-8") as f: |
| stop_words = list(l.strip() for l in f.readlines()) |
| stop_words.extend(['\n', '(', ')', ' ']) |
| if NumOfChamber == 0: |
| print("大类为:男科") |
| file = pd.read_csv("./THUCNews/data/Data/nanke/nanke1.csv", encoding='utf-8') |
| df = file[["department", "ask", "answer"]] |
| word_vector_list, answer_list = wordvector(config, df) |
| most_similar_index = cos_similarity_test(content_vector,word_vector_list) |
| most_similar_answer = answer_list[most_similar_index] |
| return None, most_similar_answer |
| if NumOfChamber == 2: |
| print("大类为:妇产科") |
| file = pd.read_csv("./THUCNews/data/Data/fuchanke/fuchanke1.csv", encoding='utf-8') |
| df = file[["department", "ask", "answer"]] |
| word_vector_list, answer_list = wordvector(config, df) |
| most_similar_index = cos_similarity_test(content_vector,word_vector_list) |
| most_similar_answer = answer_list[most_similar_index] |
| return None, most_similar_answer |
| if NumOfChamber == 3: |
| print("大类为:肿瘤科") |
| file = pd.read_csv("./THUCNews/data/Data/zhongliuke/zhongliuke1.csv", encoding='utf-8') |
| df = file[["department", "ask", "answer"]] |
| word_vector_list, answer_list = wordvector(config, df) |
| most_similar_index = cos_similarity_test(content_vector,word_vector_list) |
| most_similar_answer = answer_list[most_similar_index] |
| return None, most_similar_answer |
| if NumOfChamber == 1: |
| print("大类为:内科") |
| data2 = pd.read_excel(io="data2_pro.xlsx", engine="openpyxl") |
| department_counts = data2['department'].value_counts() |
| underrepresented_categories = department_counts[department_counts < 20000].index |
| data2 = data2[~data2['department'].isin(underrepresented_categories)] |
| data2['Pre_Text'].fillna('', inplace=True) |
| X = data2['Pre_Text'] |
| y = data2['department'] |
| X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) |
| count_vectorizer = CountVectorizer(stop_words=stop_words, max_features=5000) |
| X_train_count = count_vectorizer.fit_transform(X_train) |
| X_test_count = count_vectorizer.transform(X_test) |
| input_text = content |
| nb_classifier = joblib.load('naive_bayes_model.pkl') |
| input_text_processed = " ".join([w for w in list(jieba.cut(str(input_text))) if w not in stop_words]) |
| input_text_processed = count_vectorizer.transform([input_text_processed]) |
| predicted_department = nb_classifier.predict(input_text_processed) |
|
|
| file = pd.read_csv("./THUCNews/data/Data/neike/neike1.csv", encoding='utf-8') |
| df = file[file["department"] == predicted_department[0]] |
| df = df[["department", "ask", "answer"]] |
| word_vector_list, answer_list = wordvector(config, df) |
| most_similar_index = cos_similarity_test(content_vector,word_vector_list) |
| most_similar_answer = answer_list[most_similar_index] |
| return predicted_department[0], most_similar_answer |
| if NumOfChamber == 4: |
| print("大类为:儿科") |
| input_text = ' '.join([word for word in jieba.lcut(content) if word not in stop_words]) |
| predicted_department, confidence_score = predict_single_text(input_text,4) |
| file = pd.read_csv("./THUCNews/data/Data/erke/erke1.csv", encoding='utf-8') |
| df = file[file["department"] == predicted_department] |
| df = df[["department", "ask", "answer"]] |
| word_vector_list, answer_list = wordvector(config, df) |
| most_similar_index = cos_similarity_test(content_vector,word_vector_list) |
| most_similar_answer = answer_list[most_similar_index] |
| return predicted_department, most_similar_answer |
| if NumOfChamber == 5: |
| print("大类为:外科") |
| input_text = ' '.join([word for word in jieba.lcut(content) if word not in stop_words]) |
| predicted_department, confidence_score = predict_single_text(input_text,5) |
| file = pd.read_csv("./THUCNews/data/Data/waike/waike1.csv", encoding='utf-8') |
| print(type(predicted_department)) |
| print(predicted_department) |
| df = file[file["department"] == predicted_department] |
| df = df[["department", "ask", "answer"]] |
| word_vector_list, answer_list = wordvector(config, df) |
| most_similar_index = cos_similarity_test(content_vector,word_vector_list) |
| most_similar_answer = answer_list[most_similar_index] |
| return predicted_department, most_similar_answer |
|
|
|
|
|
|
| def working_func(content): |
| |
| vocab, train_data = build_dataset(content,config, False) |
| content_vector = train_data[0][0] |
| config.n_vocab = len(vocab) |
| train_iter = build_iterator(train_data, config) |
| predict_all = np.array([], dtype=int) |
| labels_all = np.array([], dtype=int) |
| result_list = ["男科","内科","妇产科","肿瘤科","儿科","外科"] |
| text = [] |
| for texts, labels in train_iter: |
| outputs = model(texts) |
| labels = labels.data.cpu().numpy() |
| predic = torch.max(outputs.data, 1)[1].cpu().numpy() |
| labels_all = np.append(labels_all, labels) |
| predict_all = np.append(predict_all, predic) |
| result = predict_all[0] |
| DaKeShi = result_list[result] |
| text.append(DaKeShi) |
| XiaoKeShi, most_similar_answer = proceed(content, result, content_vector) |
| text.append(XiaoKeShi) |
| text.append(most_similar_answer) |
| print(XiaoKeShi) |
| print(most_similar_answer) |
| return text |
|
|
|
|
|
|
|
|