├── .gitignore
├── ReadMe.md
├── __init__.py
├── cache
├── corpus.txt
└── query.txt
├── chat.png
├── chat.py
├── getQA.py
├── matcher
├── BM-25
│ ├── __init__.py
│ ├── invdx.py
│ ├── main.py
│ ├── parse.py
│ ├── query.py
│ └── rank.py
├── __init__.py
├── aimlMatcher.py
├── bm25Matcher.py
├── levenshteinMatcher.py
├── rules
│ ├── Common_conversation.aiml
│ ├── OrdinaryQuestion.aiml
│ ├── bad.aiml
│ ├── bye.aiml
│ ├── funny.aiml
│ ├── personname.aiml
│ ├── tools.aiml
│ └── tuling.aiml
├── rulesMapper.py
└── vectorMatcher.py
├── stopwords
├── chinese_sw.txt
├── specialMarks.txt
└── stopwords.txt
├── train_w2v.py
└── userdict
└── user_dict.csv
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | /cache/*.csv
3 | /model/
4 | /corpus/*.csv
5 | /notebook/
--------------------------------------------------------------------------------
/ReadMe.md:
--------------------------------------------------------------------------------
1 | ## 基于相似问法的闲聊场景对话机器人(Version 2)
2 |
3 | ---
4 | ## ChatBot运行步骤:
5 |
6 | Step 1. 在根目录下新建corpus文件夹,将[语料文件][1]下载并解压到corpus文件夹 (密码:0n2x)
7 |
8 | Step 2. 在根目录下新建model文件夹,将训练好的[词向量文件][2]下载并解压到model文件夹 (egg9)
9 |
10 | Step 3. 运行getQA.py获得所需的运行文件,这里已经有训练好的_词向量模型_,所以getQA运行时会
11 | 直接加载,并获得chat所需的所有文件。
12 |
13 | Step 4. 运行chat.py进行问答测试
14 |
15 | > 几种对话匹配策略
16 | > - aiml 自定义对话模板
17 | > - vectorMatcher 句子词向量加权表示的余弦相似度
18 | > - levenshteinMatcher 编辑距离匹配
19 | > - BM-25 相似匹配(暂未使用)
20 |
21 |
22 | ---
23 |
24 | ## 对话结果
25 |
26 | 
27 |
28 |
29 | <-old version->
30 |
31 | #### 与Version 1的不同
32 |
33 | - 扩充了机器人的语料库(闲谈逸致,文理类,生活相关,职场职业,城市问题,教育类,情感类,旅游景点,电影,考试相关,名人巨星,生活常识,歌曲歌词,国家相关)
34 |
35 | ---
36 |
37 | > 2017/09/07 <-new version->
38 | > 将相似匹配算法移到了matcher
39 | > 增加了BM-25匹配算法
40 | ---
41 | [1]:http://pan.baidu.com/s/1kVFwrpP
42 | [2]:http://pan.baidu.com/s/1dFzZxc9
43 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StephenLee2016/simple-chatbot/348d4b81a7406d2ab0e04b137e5b9f146281f01a/__init__.py
--------------------------------------------------------------------------------
/cache/query.txt:
--------------------------------------------------------------------------------
1 | 京巴
2 | 周杰伦
3 | 周杰伦 演唱会
4 |
--------------------------------------------------------------------------------
/chat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StephenLee2016/simple-chatbot/348d4b81a7406d2ab0e04b137e5b9f146281f01a/chat.png
--------------------------------------------------------------------------------
/chat.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | import numpy as np
5 | import json
6 | import random
7 | import jieba
8 | import pandas as pd # 这里选择pandas存储矩阵,numpy无法解决索引问题,后续解决
9 | from matcher import aimlMatcher
10 | from matcher import vectorMatcher
11 | from matcher import levenshteinMatcher
12 | import logging
13 |
14 | import sys
15 | reload(sys)
16 | sys.setdefaultencoding('utf-8')
17 | logger = logging.getLogger('chat.py')
18 |
19 |
20 | # 获得问题回答
21 | def get_response(response_frame, inputs_str):
22 | '''
23 | for index in list(response_index):
24 | yield id2sent[str(index)]
25 | '''
26 |
27 | if response_frame is None:
28 | return u'这句话我还无法回答...'
29 | else:
30 | lm = levenshteinMatcher
31 | response_frame['leven'] = response_frame[1].apply(lambda x: lm.levenstein_ratio(inputs_str, str(x)))
32 |
33 | # 这里用levenshtein ratio进行过滤,只选大于0.8的匹配度的问题
34 | response_frame = response_frame[response_frame['leven'] > 0.6]
35 | try:
36 | response_frame = response_frame.sort_values(by='cosine',ascending=False)
37 | if response_frame.shape[0] > 3:
38 | i = random.randint(0,3)
39 |
40 | if '_RBT_NAME_' in response_frame.iloc[i,0]:
41 | return response_frame.iloc[i,0].replace('_RBT_NAME_', '小京灵')
42 | else:
43 | return response_frame.iloc[i,0]
44 | else:
45 | if '_RBT_NAME_' in response_frame.iloc[0,0]:
46 | return response_frame.iloc[0,0].replace('_RBT_NAME_', '小京灵')
47 | else:
48 | return response_frame.iloc[0,0]
49 | except:
50 | return u'这个问题我不知道如何回答哦~~'
51 |
52 |
53 | if __name__ == '__main__':
54 |
55 | sent_vec = pd.read_csv('./cache/sentence2vec.csv', header=None, sep='|', error_bad_lines=True)
56 | vec_model = vectorMatcher.load_w2vModel()
57 | mybot = aimlMatcher.get_rules()
58 | T = jieba.initialize()
59 | jieba.load_userdict('./userdict/user_dict.csv')
60 |
61 | while True:
62 | # 获取用户的输入
63 | inputs_str = raw_input(u'Me > ')
64 | inputs_seg = ' '.join(jieba.cut(inputs_str))
65 | # cosine 相似度
66 | cosine_sim = vectorMatcher.match(inputs_seg, sent_vec, vec_model)
67 | sent_vec['cosine'] = cosine_sim
68 | # print sent_vec.head()
69 |
70 | try:
71 | # 保留余弦相似度top10
72 | response_frame = sent_vec.sort_values(by='cosine', ascending=False)[:10]
73 | # print response_frame
74 | except:
75 | response_frame = None
76 |
77 | # 获得回答
78 | if '#NoMatchingTemplate' not in aimlMatcher.match(inputs_seg, mybot):
79 | response = aimlMatcher.match(inputs_seg, mybot)
80 | else:
81 | print '模板无结果,从相似匹配获得结果'
82 | response = get_response(response_frame, inputs_str)
83 | print (u'ChatBot > %s'%response)
84 |
85 | # 需要把之前计算的概率值去掉,要不然计算相似度时候维度不同
86 | sent_vec = sent_vec.iloc[:, 0:202]
--------------------------------------------------------------------------------
/getQA.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # __author__=='jrlimingyang@jd.com'
3 | import os
4 | import re
5 | import jieba
6 | import codecs
7 | import numpy as np
8 | import pandas as pd
9 | from train_w2v import train
10 | from gensim.models import KeyedVectors
11 |
12 | import logging
13 | logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s', level=logging.INFO)
14 |
15 | import sys
16 | reload(sys)
17 | sys.setdefaultencoding('utf-8')
18 |
19 | '''
20 | 1.将对话数据拆成question、answer两个文件
21 | 2.将question转换成sentence vector
22 | 3.获得训练vector model的数据
23 | '''
24 |
25 | def get_qa(file_path):
26 | '''
27 | :param file_path:原始语料路径
28 | :return: question 和 answer
29 | '''
30 | corpus = pd.read_csv(file_path, error_bad_lines=True)
31 | # domain = ['闲谈逸致','文理类','生活相关','职场职业','城市问题','教育类','情感类','旅游景点','电影','考试相关','名人巨星','生活常识','歌曲歌词','国家相关']
32 | # corpus = corpus[corpus[3].isin(domain)]
33 | # corpus = corpus[[10,0]]
34 | # corpus.columns = ['question','answer']
35 | corpus['question_seg'] = corpus['question'].apply(lambda x: _remove_stopwords(' '.join(jieba.cut(str(x)))))
36 | corpus.index = range(0,corpus.shape[0])
37 |
38 | return corpus
39 |
40 |
41 | def sentence2vec(corpus, vec_model):
42 | '''
43 | :param sentence:
44 | :param vec_model: 训练好的词向量模型
45 | :return: 句子的向量化表示
46 | '''
47 | vecFrame = pd.DataFrame(np.zeros((corpus.shape[0],200)))
48 | corpus['sent2vec'] = corpus['question'].apply(lambda x: ' '.join(jieba.cut(str(x))))
49 |
50 | for index, row in corpus.iterrows():
51 | sentVec = np.zeros((1, 200))
52 | if (index+1) % 1000 == 0:
53 | logging.info(u'%s lines complete'%(index+1))
54 | word_count = 0
55 |
56 | for word in row['sent2vec'].split(' '):
57 | try:
58 | word_count += 1
59 | sentVec += vec_model[word]
60 | except Exception:
61 | pass
62 |
63 | vecFrame.iloc[index,:] = sentVec[0]/float(word_count)
64 | with open(os.path.join(os.getcwd(),'cache/corpus.txt'), 'w') as f:
65 | for index, row in corpus.iterrows():
66 | f.write('# '+ str(index))
67 | f.write('\n')
68 | f.write(row[2])
69 | f.write('\n')
70 | del corpus['sent2vec']
71 | corpus = pd.concat([corpus,vecFrame], axis=1)
72 | return corpus
73 |
74 |
75 | def _remove_stopwords(segwords):
76 | stopwords = [stopword for stopword in codecs.open(os.path.join(os.getcwd(), 'stopwords/stopwords.txt'), 'r', 'utf-8').read()]
77 | wordlist = ''
78 | for word in segwords.split(' '):
79 | if word not in stopwords:
80 | wordlist += word + ' '
81 | return wordlist
82 |
83 | def get_vector_data(corpus):
84 | '''
85 | :param file_path: 原始语料路径
86 | :return: 分词后的预料数据,用于vector model训练
87 | '''
88 | #corpus = pd.read_csv(file_path, header=None, error_bad_lines=True)
89 |
90 | vec_data = corpus['question'] + corpus['answer']
91 | vec_data = vec_data.apply(lambda x: _remove_stopwords(' '.join(jieba.cut(str(x)))))
92 | return vec_data
93 |
94 | def main():
95 | # 训练闲聊模型需要的数据问题件路径
96 | corpus_path = './corpus/corpus_1509417971.2.csv'
97 | # 需要保存的向量数据路径
98 | vector_path = './corpus/vec_data.csv'
99 |
100 | corpus = get_qa(corpus_path)
101 | # 如果vector model 存在则直接载入
102 | # 这里有一点小trick,如果语料发生了变化,那么词向量是否需要重新训练其实是需要看效果而定
103 | # 假如需要重新训练词向量模型,只需要将model文件夹下的四个文件删除,然后重新运行程序就行
104 | if os.path.exists('./model/all.zh.text.vector'):
105 | vec_model = KeyedVectors.load_word2vec_format('./model/all.zh.text.vector')
106 | else:
107 | vec_data = get_vector_data(corpus)
108 | vec_data.to_csv(vector_path, index=None, header=None, encoding='utf-8')
109 | vec_model = train(vector_path)
110 |
111 |
112 | sent2vec = sentence2vec(corpus, vec_model)
113 | del sent2vec['question_seg']
114 | # 存储转化好的sentence向量
115 | sent2vec.to_csv('./cache/sentence2vec.csv', index=None, sep='|', header=None)
116 |
117 |
118 | if __name__ == '__main__':
119 | main()
--------------------------------------------------------------------------------
/matcher/BM-25/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StephenLee2016/simple-chatbot/348d4b81a7406d2ab0e04b137e5b9f146281f01a/matcher/BM-25/__init__.py
--------------------------------------------------------------------------------
/matcher/BM-25/invdx.py:
--------------------------------------------------------------------------------
1 | # -*- coding;utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | class InvertedIndex:
5 | def __init__(self):
6 | self.index = dict()
7 |
8 | def __contains__(self, item):
9 | return item in self.index
10 |
11 | def __getitem__(self, item):
12 | return self.index[item]
13 |
14 | def add(self, word, docid):
15 | if word in self.index:
16 | if docid in self.index[word]:
17 | self.index[word][docid] += 1
18 | else:
19 | self.index[word][docid] = 1
20 | else:
21 | d = dict()
22 | d[docid] = 1
23 | self.index[word] = d
24 |
25 | # Frequency of word in document
26 | def get_document_frequency(self, word, docid):
27 | if word in self.index:
28 | if docid in self.index[word]:
29 | return self.index[word][docid]
30 | else:
31 | raise LookupError('%s not in document %s' % (str(word), str(docid)))
32 | else:
33 | raise LookupError('%s not in index' % str(word))
34 |
35 | # Frequency of word in index, i.e. number of documents that contain word
36 | def get_index_frequency(self, word):
37 | if word in self.index:
38 | return len(self.index[word])
39 | else:
40 | raise LookupError('%s not in index' % word)
41 |
42 | class DocumentLengthTable:
43 | def __init__(self):
44 | self.table = dict()
45 |
46 | def __len__(self):
47 | return len(self.table)
48 |
49 | def add(self, docid, length):
50 | self.table[docid] = length
51 |
52 | def get_length(self, docid):
53 | if docid in self.table:
54 | return self.table[docid]
55 | else:
56 | raise LookupError('%s not found in table' % str(docid))
57 |
58 | def get_average_length(self):
59 | sum = 0
60 | for length in self.table.itervalues():
61 | sum += length
62 | return float(sum) / float(len(self.table))
63 |
64 | def build_data_structures(corpus):
65 | idx = InvertedIndex()
66 | dlt = DocumentLengthTable()
67 | for docid in corpus:
68 | # build inverted index
69 | for word in corpus[docid]:
70 | idx.add(str(word), str(docid))
71 |
72 | # build document length table
73 | length = len(corpus[str(docid)])
74 | dlt.add(docid, length)
75 |
76 | return idx, dlt
--------------------------------------------------------------------------------
/matcher/BM-25/main.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | from parse import *
5 | from query import QueryProcessor
6 | import operator
7 |
8 | def main():
9 | qp = QueryParser(filename='C:\\Users\\jrlimingyang\\PycharmProjects\\chatbot-version2\\cache\\query.txt')
10 | cp = CorpusParser(filename='C:\\Users\\jrlimingyang\\PycharmProjects\\chatbot-version2\\cache\\corpus.txt')
11 | qp.parse()
12 | queries = qp.get_queries()
13 | cp.parse()
14 | corpus = cp.get_corpus()
15 | proc = QueryProcessor(queries, corpus)
16 | results = proc.run()
17 | qid = 0
18 | for result in results:
19 | sorted_x = sorted(result.iteritems(), key=operator.itemgetter(1))
20 | sorted_x.reverse()
21 | index = 0
22 | for i in sorted_x[:10]:
23 | tmp = (qid, qid, i[0], index, i[1])
24 | print '{:>1}\tQ{:>1}\t{:>4}\t{:>2}\t{:>12}\tL-BM25'.format(*tmp)
25 | index += 1
26 | qid += 1
27 |
28 | if __name__ == '__main__':
29 | main()
30 |
--------------------------------------------------------------------------------
/matcher/BM-25/parse.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | import codecs
5 | import re
6 |
7 | class CorpusParser:
8 | def __init__(self, filename):
9 | self.filename = filename
10 | self.regex = re.compile('^#\s*\d+')
11 | self.corpus = dict()
12 |
13 | def parse(self):
14 | with codecs.open(self.filename, 'r') as f:
15 | s = ''.join(f.readlines())
16 | blobs = s.split('#')[1:]
17 | for x in blobs:
18 | text = x.split()
19 | docid = text.pop(0)
20 | self.corpus[docid] = text
21 |
22 | def get_corpus(self):
23 | return self.corpus
24 |
25 | class QueryParser:
26 | def __init__(self, filename):
27 | self.filename = filename
28 | self.queries = []
29 |
30 | def parse(self):
31 | with codecs.open(self.filename, 'r' ) as f:
32 | lines = ''.join(f.readlines())
33 | self.queries = [x.rstrip().split() for x in lines.split('\n')[:-1]]
34 |
35 | def get_queries(self):
36 | return self.queries
37 |
38 | if __name__ == '__main__':
39 | qp = QueryParser('./data/queries.txt')
40 | print qp.get_queries()
--------------------------------------------------------------------------------
/matcher/BM-25/query.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | from invdx import build_data_structures
5 | from rank import score_BM25
6 | import operator
7 |
8 |
9 | class QueryProcessor:
10 | def __init__(self, queries, corpus):
11 | self.queries = queries
12 | self.index, self.dlt = build_data_structures(corpus)
13 |
14 | def run(self):
15 | results = []
16 | for query in self.queries:
17 | results.append(self.run_query(query))
18 | #results.append(self.run_query(self.queries))
19 | return results
20 |
21 | def run_query(self, query):
22 | query_result = dict()
23 | for term in query:
24 | if term in self.index:
25 | doc_dict = self.index[term]
26 | for docid, freq in doc_dict.iteritems():
27 | score = score_BM25(n=len(doc_dict), f=freq, qf=1, r=0, N=len(self.dlt),
28 | dl=self.dlt.get_length(docid), avdl=self.dlt.get_average_length())
29 | if docid in query_result:
30 | query_result[docid] += score
31 | else:
32 | query_result[docid] = score
33 | return query_result
--------------------------------------------------------------------------------
/matcher/BM-25/rank.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | from math import log
5 |
6 | k1 = 1.2
7 | k2 = 100
8 | b = 0.75
9 | R = 0.0
10 |
11 | def score_BM25(n,f, qf, r, N, dl, avdl):
12 | K = compute_K(dl, avdl)
13 | first = log(((r + 0.5)/(R - r + 0.5)) / ((n - r + 0.5)/(N - n - R + r + 0.5)))
14 | second = ((k1 + 1) * f) / (K + f)
15 | third = ((k2 + 1) * qf) / (k2 + qf)
16 | return first * second * third
17 |
18 | def compute_K(dl, avdl):
19 | return k1 * ((1-b) + b * (float(dl)/float(avdl)))
--------------------------------------------------------------------------------
/matcher/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StephenLee2016/simple-chatbot/348d4b81a7406d2ab0e04b137e5b9f146281f01a/matcher/__init__.py
--------------------------------------------------------------------------------
/matcher/aimlMatcher.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 |
5 | from matcher.rulesMapper import get_rules
6 |
7 |
8 | def add_rules():
9 | mybot = get_rules()
10 | return mybot
11 |
12 | def match(inputs_seg, mybot):
13 | return mybot.respond(inputs_seg)
14 |
--------------------------------------------------------------------------------
/matcher/bm25Matcher.py:
--------------------------------------------------------------------------------
1 | # -*- coding;utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | import math
5 |
6 |
7 | # TO-DO: 下一步将bm-25将入进来
8 | class bestMatchingMatcher():
9 | pass
--------------------------------------------------------------------------------
/matcher/levenshteinMatcher.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | def levenstein_ratio(s1, s2):
5 | # 这里用两个字符串的编辑距离比
6 | # 用ratio可以将距离归一化
7 | m, n = len(s1), len(s2)
8 | colsize, matrix = m + 1, []
9 | for i in range((m + 1) * (n + 1)):
10 | matrix.append(0)
11 | for i in range(colsize):
12 | matrix[i] = i
13 | for i in range(n + 1):
14 | matrix[i * colsize] = i
15 | for i in range(n + 1)[1:n + 1]:
16 | for j in range(m + 1)[1:m + 1]:
17 | cost = 0
18 | if s1[j - 1] == s2[i - 1]:
19 | cost = 0
20 | else:
21 | cost = 2
22 | minValue = matrix[(i - 1) * colsize + j] + 1
23 | if minValue > matrix[i * colsize + j - 1] + 1:
24 | minValue = matrix[i * colsize + j - 1] + 1
25 | if minValue > matrix[(i - 1) * colsize + j - 1] + cost:
26 | minValue = matrix[(i - 1) * colsize + j - 1] + cost
27 | matrix[i * colsize + j] = minValue
28 | return (m + n - matrix[n * colsize + m])/float(m + n)
--------------------------------------------------------------------------------
/matcher/rules/Common_conversation.aiml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | *
5 |
6 |
7 | #NoMatchingTemplate:
8 |
9 |
10 |
11 |
12 | 找不到答案
13 |
14 |
15 | 不知道啊
16 | 纳尼???
17 | 这我就不知道了
18 | 。。。不知道额
19 | 唔... 京巴还没有学会如何回答...
20 |
21 |
22 |
23 |
24 |
25 |
26 | 无
27 |
28 |
29 | 嗯?你想说啥?
30 | 你想说啥呀?
31 | 你到底想说什么?
32 |
33 |
34 |
35 |
36 |
37 | 你好
38 |
39 |
40 | 您好,我是帅气的京巴,请多指教。
41 | 您好啊,京巴很高兴为您服务~
42 | Hi~
43 | 哈喽,您好
44 | Hello~
45 |
46 |
47 |
48 |
49 | HI你好
50 | HI * 你好
51 | HELLO 你好
52 | HELLO * 你好
53 | * 你好 你好
54 | 您好 * 你好
55 |
56 |
57 | 你好 *
58 |
59 |
60 |
61 | 你好
62 | 你好
63 | 问候
64 | 夸奖
65 | 夸奖
66 | 夸奖
67 | 夸奖
68 | 夸奖
69 | 夸奖
70 | 夸奖
71 | 夸奖
72 | 夸奖
73 | 夸奖
74 | 夸奖
75 | 夸奖
76 | 夸奖
77 | 夸奖
78 | 夸奖
79 | 夸奖
80 |
81 |
82 |
83 |
84 |
85 | 夸奖
86 |
87 |
88 | 嘿嘿,过奖了。
89 | 嗨嗨,他们都说我 ʅ(‾◡◝)ʃ
90 | 谢谢,京巴背后有一群辛勤的老师在教导我!
91 | 哈哈
92 |
93 |
94 |
95 |
96 |
97 | 问候
98 |
99 |
100 | 还不错,多谢关心~
101 | 很好 ʅ(‾◡◝)ʃ
102 | 非常不错,希望你也天天好心情哦~
103 | Nice
104 |
105 |
106 |
107 |
108 |
109 | 晚安
110 |
111 |
112 | 晚安
113 | Sleep tight~
114 | 晚安,祝你梦到妹纸~
115 |
116 |
117 |
118 |
119 | 晚安 *晚安
120 | * 晚安晚安
121 |
122 |
123 | 句子长度过长
124 |
125 |
126 | 信息量有点大,容我想想
127 | 信息量有点大
128 | 容我想想,信息量有点大
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/matcher/rules/OrdinaryQuestion.aiml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | * 的 * 是
5 |
6 |
7 |
8 |
9 |
10 | #searchbaike::
11 |
12 |
13 |
14 |
15 | * 的 * 是 *
16 |
17 |
18 |
19 |
20 |
21 | 的 是
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/matcher/rules/bad.aiml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 你 个 *
6 |
7 |
8 |
9 | 愚蠢
10 |
11 |
12 |
13 | 愚蠢
14 |
15 |
16 |
17 |
18 |
19 | 愚蠢
20 |
21 |
22 | 你以为你自己很聪明?
23 | 再说一句试试?
24 | 算你聪明行了吧
25 | 造我那个比较聪明,找他去。
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/matcher/rules/bye.aiml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 再见
5 |
6 |
7 | 88
8 | 拜拜
9 | 再见
10 | 慢走不送~
11 | good bye
12 | bye~
13 |
14 |
15 |
16 |
17 | 再见 *再见
18 | * 再见再见
19 | 88再见
20 | * 拜拜再见
21 | 拜拜 *再见
22 | 拜拜再见
23 |
24 |
25 | 好的
26 |
27 |
28 | 感谢您的咨询,希望您对我的服务满意~
29 | 有什么问题都可以问我哦~
30 | 希望对京巴的服务满意~
31 |
32 |
33 |
34 |
35 | 嗯嗯 *好的
36 | * 好的好的
37 | 嗯 *好的
38 | * 好吧好的
39 | 嗯好的
40 | 哦好的
41 | 好的 *好的
42 |
43 |
--------------------------------------------------------------------------------
/matcher/rules/personname.aiml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | * 是 谁
5 |
6 |
7 |
8 |
9 | #searchperson:
10 |
11 |
12 |
13 |
14 |
15 | * 的 * 是 谁
16 |
17 |
18 |
19 |
20 |
21 | #searchperson::
22 |
23 |
24 |
25 |
26 | * 的 * 是 谁 *
27 |
28 |
29 |
30 |
31 |
32 | 的 是 谁
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/matcher/rules/tools.aiml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 查 时间
5 |
6 |
7 |
8 |
9 | 今天 几号查 时间
10 | 现在 几点 *查 时间
11 | 现在 几点查 时间
12 |
13 |
14 | * 查 * 到 * 的 *
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | #查询=::
24 |
25 |
26 |
27 |
28 | * 查一下 * 到 * 的 *
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | 查 到 的
37 |
38 |
39 |
40 |
41 |
42 | 天气
43 |
44 | 天气戳这里:http://www.weather.com.cn/weather/101020100.shtml
45 |
46 |
47 | 今天天气 *天气
48 | 今天天气天气
49 | 今天 * 天气天气
50 | * 天气 *天气
51 |
52 |
--------------------------------------------------------------------------------
/matcher/rulesMapper.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | import os, sys
5 | import aiml
6 |
7 |
8 | def add_rules():
9 | rule_path = os.getcwd()
10 | mybot = aiml.Kernel()
11 |
12 | # 加载aiml规则模板
13 | mybot.learn(rule_path + '/matcher/rules/Common_conversation.aiml')
14 | mybot.learn(rule_path + '/matcher/rules/bye.aiml')
15 | mybot.learn(rule_path + '/matcher/rules/tuling.aiml')
16 | #mybot.learn(rule_path + '/matcher/rules/tools.aiml')
17 | #mybot.learn(rule_path + '/matcher/rules/bad.aiml')
18 | #mybot.learn(rule_path + '/matcher/rules/funny.aiml')
19 | #mybot.learn(rule_path + '/matcher/rules/OrdinaryQuestion.aiml')
20 |
21 | #mybot.learn(rule_path + '/matcher/rules/persionname.aiml')
22 |
23 | return mybot
24 |
25 | def get_rules():
26 | mybot = add_rules()
27 | return mybot
--------------------------------------------------------------------------------
/matcher/vectorMatcher.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | __author__ = 'jrlimingyang@jd.com'
3 |
4 | import os
5 | import gensim
6 | import jieba
7 | import numpy as np
8 | from sklearn.metrics.pairwise import cosine_similarity
9 | import logging
10 | logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
11 |
12 | def load_w2vModel():
13 | '''
14 | 加载 pre-trained 词向量模型
15 | 用来将句子向量化
16 | '''
17 | assert os.path.exists('./model/all.zh.text.vector')
18 | logging.info(u'开始加载 pre-trained 向量模型...')
19 | vec_model = gensim.models.KeyedVectors.load_word2vec_format('./model/all.zh.text.vector')
20 | logging.info(u'模型加载完毕')
21 | return vec_model
22 |
23 | def input2vec(inputs_str, vec_model):
24 | '''
25 | 用户输入转化为向量表示
26 | '''
27 | sent_vec = np.zeros((1,200))
28 |
29 | vocab_num = 0
30 | for word in inputs_str.split(' '):
31 | try:
32 | vocab_num += 1
33 | sent_vec += vec_model[word]
34 | except Exception:
35 | pass
36 | return sent_vec / float(vocab_num)
37 |
38 | def match(inputs_str, sent_vec, vec_model):
39 | '''
40 | 句子向量化的处理方式就是简单的加权平均
41 | 可以用其他的方式继续优化
42 | '''
43 | input_vec = input2vec(inputs_str, vec_model)
44 | cosine = cosine_similarity(input_vec, sent_vec.iloc[:, 2::])[0]
45 |
46 | return cosine
--------------------------------------------------------------------------------
/stopwords/chinese_sw.txt:
--------------------------------------------------------------------------------
1 | 啊
2 | 阿
3 | 哎
4 | 哎呀
5 | 哎喲
6 | 哎呦
7 | 唉
8 | 俺
9 | 有點
10 | 有点
11 | 一直
12 | 俺們
13 | 按
14 | 按照
15 | 吧
16 | 吧噠
17 | 吧嗒
18 | 把
19 | 罷了
20 | 罢了
21 | 被
22 | 本
23 | 本著
24 | 比
25 | 比方
26 | 比如
27 | 鄙人
28 | 彼
29 | 彼此
30 | 最近
31 | 老是
32 | 邊
33 | 边
34 | 別
35 | 別的
36 | 別說
37 | 别说
38 | 並
39 | 并
40 | 並且
41 | 并且
42 | 不比
43 | 不成
44 | 不單
45 | 不单
46 | 不但
47 | 不獨
48 | 不独
49 | 不管
50 | 不光
51 | 不過
52 | 不过
53 | 不僅
54 | 不仅
55 | 不拘
56 | 不論
57 | 不论
58 | 不怕
59 | 不然
60 | 不如
61 | 不特
62 | 不惟
63 | 不問
64 | 不问
65 | 不只
66 | 朝
67 | 朝著
68 | 趁
69 | 趁著
70 | 趁着
71 | 乘
72 | 衝
73 | 除
74 | 除此之外
75 | 除非
76 | 除了
77 | 此
78 | 此間
79 | 此间
80 | 此外
81 | 從
82 | 从
83 | 從而
84 | 从而
85 | 打
86 | 待
87 | 但
88 | 但是
89 | 當
90 | 当
91 | 當著
92 | 当着
93 | 得
94 | 的
95 | 的話
96 | 的话
97 | 等
98 | 等等
99 | 地
100 | 第
101 | 叮咚
102 | 對
103 | 对
104 | 對於
105 | 对于
106 | 多
107 | 多少
108 | 而
109 | 而況
110 | 而且
111 | 而是
112 | 而外
113 | 而言
114 | 而已
115 | 爾後
116 | 尔后
117 | 而后
118 | 反過來
119 | 反过来
120 | 反過來說
121 | 反过来说
122 | 反之
123 | 非但
124 | 非徒
125 | 否則
126 | 否则
127 | 嘎
128 | 嘎登
129 | 咯噔
130 | 該
131 | 该
132 | 趕
133 | 赶
134 | 個
135 | 个
136 | 各
137 | 各個
138 | 各个
139 | 各位
140 | 各種
141 | 各种
142 | 各自
143 | 給
144 | 给
145 | 根據
146 | 根据
147 | 跟
148 | 故
149 | 故此
150 | 固然
151 | 關於
152 | 关于
153 | 管
154 | 歸
155 | 归
156 | 果然
157 | 果真
158 | 過
159 | 过
160 | 哈
161 | 哈哈
162 | 呵
163 | 和
164 | 何
165 | 何處
166 | 何处
167 | 何況
168 | 何况
169 | 何時
170 | 何时
171 | 嘿
172 | 哼
173 | 哼唷
174 | 呼哧
175 | 乎
176 | 嘩
177 | 還是
178 | 还是
179 | 還有
180 | 还有
181 | 換句話說
182 | 换句话说
183 | 換言之
184 | 换言之
185 | 或
186 | 或是
187 | 或者
188 | 極了
189 | 极了
190 | 及
191 | 及其
192 | 及至
193 | 即
194 | 即便
195 | 即或
196 | 即令
197 | 即若
198 | 即使
199 | 幾
200 | 几
201 | 幾時
202 | 几时
203 | 己
204 | 既
205 | 既然
206 | 既是
207 | 繼而
208 | 继而
209 | 加之
210 | 假如
211 | 假若
212 | 假使
213 | 鑑於
214 | 终于
215 | 將
216 | 将
217 | 較
218 | 较
219 | 較之
220 | 较之
221 | 叫
222 | 接著
223 | 結果
224 | 结果
225 | 借
226 | 緊接著
227 | 紧接着
228 | 進而
229 | 进而
230 | 盡
231 | 儘管
232 | 尽管
233 | 經
234 | 经
235 | 經過
236 | 经过
237 | 就
238 | 就是
239 | 就是說
240 | 據
241 | 据
242 | 具體地說
243 | 具体地说
244 | 具體說來
245 | 具体说来
246 | 開始
247 | 开始
248 | 開外
249 | 开外
250 | 靠
251 | 咳
252 | 可
253 | 可見
254 | 可见
255 | 可是
256 | 可以
257 | 況且
258 | 况且
259 | 啦
260 | 來
261 | 来
262 | 來著
263 | 来着
264 | 离
265 | 例如
266 | 哩
267 | 连
268 | 连同
269 | 两者
270 | 了
271 | 临
272 | 另
273 | 另外
274 | 另一方面
275 | 论
276 | 嘛
277 | 吗
278 | 慢说
279 | 漫说
280 | 冒
281 | 么
282 | 每
283 | 每当
284 | 们
285 | 莫若
286 | 某
287 | 某个
288 | 某些
289 | 拿
290 | 哪
291 | 哪边
292 | 哪儿
293 | 哪个
294 | 哪里
295 | 哪年
296 | 哪怕
297 | 哪天
298 | 哪些
299 | 哪样
300 | 那
301 | 那边
302 | 那儿
303 | 那个
304 | 那会见
305 | 那里
306 | 那么
307 | 那么些
308 | 那么样
309 | 那时
310 | 那些
311 | 那样
312 | 乃
313 | 乃至
314 | 呢
315 | 能
316 | 你
317 | 你們
318 | 您
319 | 宁
320 | 宁可
321 | 宁肯
322 | 宁愿
323 | 哦
324 | 啪嗒
325 | 旁人
326 | 呸
327 | 凭借
328 | 凭
329 | 其
330 | 其次
331 | 其二
332 | 其他
333 | 其它
334 | 其一
335 | 其余
336 | 其中
337 | 起
338 | 起见
339 | 非但
340 | 恰恰相反
341 | 前后
342 | 前者
343 | 且
344 | 然而
345 | 然后
346 | 然则
347 | 让
348 | 人家
349 | 任
350 | 任何
351 | 任凭
352 | 如
353 | 如此
354 | 如果
355 | 如何
356 | 如其
357 | 如若
358 | 如上所述
359 | 若
360 | 若非
361 | 若是
362 | 啥
363 | 上下
364 | 尚且
365 | 设若
366 | 设使
367 | 甚而
368 | 甚么
369 | 甚至
370 | 省得
371 | 时候
372 | 什么
373 | 什么样
374 | 使得
375 | 是
376 | 是的
377 | 首先
378 | 谁
379 | 谁知
380 | 顺
381 | 顺著
382 | 似的
383 | 虽
384 | 虽然
385 | 虽说
386 | 虽则
387 | 随
388 | 随著
389 | 所
390 | 所以
391 | 他
392 | 他们
393 | 他人
394 | 它
395 | 它们
396 | 她
397 | 她们
398 | 倘
399 | 倘或
400 | 倘然
401 | 倘若
402 | 倘使
403 | 騰
404 | 替
405 | 通过
406 | 同
407 | 同时
408 | 哇
409 | 萬一
410 | 往
411 | 望
412 | 为
413 | 为何
414 | 为了
415 | 为什么
416 | 为着
417 | 喂
418 | 嗡嗡
419 | 我
420 | 我们
421 | 呜
422 | 呜呼
423 | 无论
424 | 毋宁
425 | 嘻
426 | 嚇
427 | 相对而言
428 | 像
429 | 向
430 | 向着
431 | 嘘
432 | 呀
433 | 焉
434 | 沿
435 | 沿著
436 | 要
437 | 要不
438 | 要不然
439 | 要不是
440 | 要么
441 | 要是
442 | 也
443 | 也罢
444 | 也好
445 | 一
446 | 一般
447 | 一旦
448 | 一方面
449 | 一来
450 | 一切
451 | 一样
452 | 一则
453 | 依
454 | 依照
455 | 矣
456 | 以
457 | 以便
458 | 以及
459 | 以免
460 | 以至
461 | 以至于
462 | 以致
463 | 抑或
464 | 因
465 | 因此
466 | 因而
467 | 因为
468 | 呦
469 | 用
470 | 由
471 | 由此可见
472 | 由于
473 | 有
474 | 有的
475 | 有关
476 | 有些
477 | 又
478 | 于
479 | 于是
480 | 于是乎
481 | 与
482 | 与此同时
483 | 与否
484 | 与其
485 | 越是
486 | 云云
487 | 哉
488 | 再说
489 | 再者
490 | 在
491 | 在下
492 | 咱
493 | 咱们
494 | 则
495 | 怎
496 | 怎么
497 | 怎么办
498 | 怎么样
499 | 怎样
500 | 咋
501 | 照
502 | 照着
503 | 者
504 | 这
505 | 这边
506 | 这儿
507 | 这个
508 | 这会儿
509 | 这就是说
510 | 这里
511 | 这么
512 | 这么点儿
513 | 这么些
514 | 这么样
515 | 这时
516 | 这些
517 | 这样
518 | 正如
519 | 吱
520 | 之
521 | 之类
522 | 之所以
523 | 之一
524 | 只是
525 | 只限
526 | 只要
527 | 只有
528 | 至
529 | 至于
530 | 诸位
531 | 著
532 | 著呢
533 | 自
534 | 自从
535 | 自个儿
536 | 自各儿
537 | 自己
538 | 自家
539 | 自身
540 | 综上所述
541 | 总的来看
542 | 总的来说
543 | 总而言之
544 | 总之
545 | 纵
546 | 纵令
547 | 纵然
548 | 纵使
549 | 遵照
550 | 作为
551 | 兮
552 | 呃
553 | 呗
554 | 咚
555 | 咦
556 | 喏
557 | 啐
558 | 喔唷
559 | 嗬
560 | 嗯
561 | 噯
562 | ~
563 | !
564 | .
565 | :
566 | "
567 | '
568 | (
569 | )
570 | *
571 | A
572 | 白
573 | 社会主义
574 | --
575 | ..
576 | >>
577 | [
578 | ]
579 | <
580 | >
581 | /
582 | \
583 | |
584 | -
585 | _
586 | +
587 | =
588 | &
589 | ^
590 | %
591 | #
592 | @
593 | `
594 | ;
595 | $
596 | (
597 | )
598 | ——
599 | —
600 | ¥
601 | ·
602 | ...
603 | '
604 | '
605 | 〉
606 | 〈
607 | …
608 |
609 | 0
610 | 1
611 | 2
612 | 3
613 | 4
614 | 5
615 | 6
616 | 7
617 | 8
618 | 9
619 | 0
620 | 1
621 | 2
622 | 3
623 | 4
624 | 5
625 | 6
626 | 7
627 | 8
628 | 9
629 | 二
630 | 三
631 | 四
632 | 五
633 | 六
634 | 七
635 | 八
636 | 九
637 | 零
638 | >
639 | <
640 | @
641 | #
642 | $
643 | %
644 | ︿
645 | &
646 | *
647 | +
648 | ~
649 | |
650 | [
651 | ]
652 | 「
653 | 」
654 | 『
655 | 』
656 | 【
657 | 】
658 | {
659 | }
660 | 啊哈
661 | 啊呀
662 | 啊呦
663 | 哎呦
664 | 我艹
665 | 卧槽
666 | 窝草
667 | 我屮艸芔茻
668 | 艹
669 | 草泥马
670 | 挨次
671 | 挨个
672 | 挨家挨户
673 | 挨门挨户
674 | 挨门逐户
675 | 挨着
676 | 按理
677 | 按期
678 | 按时
679 | 按说
680 | 暗地里
681 | 暗中
682 | 暗自
683 | 昂然
684 | 八成
685 | 白白
686 | 半
687 | 梆
688 | 保管
689 | 保险
690 | 饱
691 | 背地里
692 | 背靠背
693 | 倍感
694 | 倍加
695 | 本人
696 | 本身
697 | 甭
698 | 比起
699 | 比如说
700 | 比照
701 | 毕竟
702 | 必
703 | 必定
704 | 必将
705 | 必須
706 | 便
707 | 別人
708 | 并非
709 | 并肩
710 | 并沒
711 | 并沒有
712 | 并排
713 | 并无
714 | 勃然
715 | 不
716 | 不必
717 | 不常
718 | 不大
719 | 不但...而且
720 | 不得
721 | 不得不
722 | 不得了
723 | 不得已
724 | 不迭
725 | 不定
726 | 不对
727 | 不妨
728 | 不管怎样
729 | 不会
730 | 不仅...而且
731 | 不仅仅
732 | 不仅仅是
733 | 不经意
734 | 不可开交
735 | 不可抗拒
736 | 不力
737 | 不了
738 | 不料
739 | 不满
740 | 不免
741 | 不能不
742 | 不起
743 | 不巧
744 | 不然的话
745 | 不日
746 | 不少
747 | 不胜
748 | 不时
749 | 不是
750 | 不同
751 | 不能
752 | 不要
753 | 不外
754 | 不外乎
755 | 不下
756 | 不限
757 | 不消
758 | 不已
759 | 不亦乐乎
760 | 不由得
761 | 不再
762 | 不择手段
763 | 不怎么
764 | 不曾
765 | 不知不觉
766 | 不止
767 | 不止一次
768 | 不至于
769 | 才
770 | 才能
771 | 策略地
772 | 差不多
773 | 差一点
774 | 常
775 | 常常
776 | 常言道
777 | 常言说
778 | 常言说得好
779 | 长此下去
780 | 长话短说
781 | 长期以来
782 | 长线
783 | 敞开儿
784 | 彻夜
785 | 陈年
786 | 趁便
787 | 趁机
788 | 趁热
789 | 趁势
790 | 趁早
791 | 成年
792 | 成年累月
793 | 成心
794 | 乘机
795 | 乘胜
796 | 乘势
797 | 乘隙
798 | 乘虛
799 | 诚然
800 | 迟早
801 | 充分
802 | 充其极
803 | 充其量
804 | 抽冷子
805 | 臭
806 | 初
807 | 出
808 | 出来
809 | 出去
810 | 除此
811 | 除此而外
812 | 除此以外
813 | 除开
814 | 除去
815 | 除卻
816 | 除外
817 | 处处
818 | 川流不息
819 | 传
820 | 传说
821 | 传闻
822 | 串行
823 | 纯
824 | 纯粹
825 | 此后
826 | 此中
827 | 次第
828 | 匆匆
829 | 从不
830 | 从此
831 | 从此以后
832 | 从古到今
833 | 从古至今
834 | 从今以后
835 | 从来
836 | 从轻
837 | 从速
838 | 从头
839 | 从未
840 | 从无到有
841 | 从小
842 | 从新
843 | 从严
844 | 从优
845 | 从早到晚
846 | 从中
847 | 从重
848 | 湊巧
849 | 粗
850 | 存心
851 | 达旦
852 | 打从
853 | 打开天窗说亮话
854 | 大
855 | 大不了
856 | 大大
857 | 大抵
858 | 大都
859 | 大多
860 | 大凡
861 | 大概
862 | 大家
863 | 大举
864 | 大略
865 | 大面儿上
866 | 大事
867 | 大体
868 | 大体上
869 | 大约
870 | 大张旗鼓
871 | 大致
872 | 呆呆地
873 | 带
874 | 殆
875 | 待到
876 | 单
877 | 单纯
878 | 单单
879 | 但愿
880 | 弹指之间
881 | 当场
882 | 当儿
883 | 当即
884 | 当口儿
885 | 当然
886 | 当庭
887 | 当头
888 | 当下
889 | 当真
890 | 当中
891 | 倒不如
892 | 倒不如说
893 | 倒是
894 | 到处
895 | 到底
896 | 到了儿
897 | 到目前为止
898 | 到头
899 | 到头來
900 | 得起
901 | 得天独厚
902 | 的确
903 | 等到
904 | 叮当
905 | 顶多
906 | 定
907 | 动不动
908 | 动辄
909 | 陡然
910 | 都
911 | 独
912 | 独自
913 | 断然
914 | 顿时
915 | 多次
916 | 多多
917 | 多多少少
918 | 多多益善
919 | 多亏
920 | 多年來
921 | 多年前
922 | 而后
923 | 而论
924 | 而又
925 | 尔等
926 | 二话不说
927 | 二话沒说
928 | 反倒
929 | 反倒是
930 | 反而
931 | 反手
932 | 反之亦然
933 | 反之则
934 | 方
935 | 方才
936 | 方能
937 | 放量
938 | 非常
939 | 非得
940 | 分期
941 | 分期分批
942 | 分头
943 | 奋勇
944 | 愤然
945 | 风雨无阻
946 | 逢
947 | 弗
948 | 甫
949 | 嘎嘎
950 | 该当
951 | 概
952 | 赶快
953 | 赶早不赶晚
954 | 敢
955 | 敢情
956 | 敢于
957 | 刚
958 | 刚才
959 | 刚好
960 | 刚巧
961 | 高低
962 | 格外
963 | 隔日
964 | 隔夜
965 | 個人
966 | 各式
967 | 更
968 | 更加
969 | 更进一步
970 | 更为
971 | 公然
972 | 共
973 | 共总
974 | 够瞧的
975 | 姑且
976 | 古来
977 | 故而
978 | 故意
979 | 固
980 | 怪
981 | 怪不得
982 | 惯常
983 | 光
984 | 光是
985 | 归根到底
986 | 归根结底
987 | 过于
988 | 毫不
989 | 毫无
990 | 毫无保留地
991 | 毫无例外
992 | 好在
993 | 何必
994 | 何当
995 | 何妨
996 | 何苦
997 | 何乐而不为
998 | 何须
999 | 何止
1000 | 很
1001 | 很多
1002 | 很少
1003 | 轟然
1004 | 后来
1005 | 呼啦
1006 | 忽地
1007 | 忽然
1008 | 互
1009 | 互相
1010 | 哗啦
1011 | 话说
1012 | 还
1013 | 恍然
1014 | 会
1015 | 豁然
1016 | 活
1017 | 伙同
1018 | 或多或少
1019 | 或许
1020 | 基本
1021 | 基本上
1022 | 基于
1023 | 极
1024 | 极大
1025 | 极度
1026 | 极端
1027 | 极力
1028 | 极其
1029 | 极为
1030 | 急匆匆
1031 | 即将
1032 | 即刻
1033 | 即是说
1034 | 几度
1035 | 几番
1036 | 几乎
1037 | 几经
1038 | 既...又
1039 | 加上
1040 | 加以
1041 | 间或
1042 | 简而言之
1043 | 简言之
1044 | 简直
1045 | 见
1046 | 将才
1047 | 将近
1048 | 将要
1049 | 交口
1050 | 较比
1051 | 较为
1052 | 接连不断
1053 | 接下来
1054 | 皆可
1055 | 截然
1056 | 截至
1057 | 藉以
1058 | 藉此
1059 | 藉以
1060 | 区时
1061 | 仅
1062 | 仅仅
1063 | 进来
1064 | 进去
1065 | 近
1066 | 近几年来
1067 | 近来
1068 | 近年来
1069 | 尽管如此
1070 | 尽可能
1071 | 尽快
1072 | 尽量
1073 | 尽然
1074 | 尽如人意
1075 | 尽心竭力
1076 | 尽心尽力
1077 | 尽早
1078 | 精光
1079 | 经常
1080 | 竟
1081 | 竟然
1082 | 究竟
1083 | 就此
1084 | 就地
1085 | 就算
1086 | 居然
1087 | 局外
1088 | 举凡
1089 | 据称
1090 | 据此
1091 | 据实
1092 | 据说
1093 | 据我所知
1094 | 据悉
1095 | 具体来说
1096 | 绝不
1097 | 绝非
1098 | 绝
1099 | 绝不
1100 | 绝顶
1101 | 絕對
1102 | 絕非
1103 | 均
1104 | 喀
1105 | 看
1106 | 看來
1107 | 看起來
1108 | 看上去
1109 | 看樣子
1110 | 可好
1111 | 可能
1112 | 恐怕
1113 | 快
1114 | 快要
1115 | 來不及
1116 | 來得及
1117 | 來講
1118 | 來看
1119 | 攔腰
1120 | 牢牢
1121 | 老
1122 | 老大
1123 | 老老實實
1124 | 老是
1125 | 累次
1126 | 累年
1127 | 理當
1128 | 理該
1129 | 理應
1130 | 歷
1131 | 立
1132 | 立地
1133 | 立刻
1134 | 立馬
1135 | 立時
1136 | 聯袂
1137 | 連連
1138 | 連日
1139 | 連日來
1140 | 連聲
1141 | 連袂
1142 | 臨到
1143 | 另方面
1144 | 另行
1145 | 另一個
1146 | 路經
1147 | 屢
1148 | 屢次
1149 | 屢次三番
1150 | 屢屢
1151 | 縷縷
1152 | 率爾
1153 | 率然
1154 | 略
1155 | 略加
1156 | 略微
1157 | 略為
1158 | 論說
1159 | 馬上
1160 | 蠻
1161 | 滿
1162 | 沒
1163 | 沒有
1164 | 每逢
1165 | 每每
1166 | 每時每刻
1167 | 猛然
1168 | 猛然間
1169 | 莫
1170 | 莫不
1171 | 莫非
1172 | 莫如
1173 | 默默地
1174 | 默然
1175 | 吶
1176 | 那末
1177 | 奈
1178 | 難道
1179 | 難得
1180 | 難怪
1181 | 難說
1182 | 內
1183 | 年復一年
1184 | 凝神
1185 | 偶而
1186 | 偶爾
1187 | 怕
1188 | 砰
1189 | 碰巧
1190 | 譬如
1191 | 偏偏
1192 | 乒
1193 | 平素
1194 | 頗
1195 | 迫於
1196 | 撲通
1197 | 其後
1198 | 其實
1199 | 奇
1200 | 齊
1201 | 起初
1202 | 起來
1203 | 起首
1204 | 起頭
1205 | 起先
1206 | 豈
1207 | 豈非
1208 | 豈止
1209 | 迄
1210 | 恰逢
1211 | 恰好
1212 | 恰恰
1213 | 恰巧
1214 | 恰如
1215 | 恰似
1216 | 千
1217 | 千万
1218 | 千万千万
1219 | 切
1220 | 切不可
1221 | 切莫
1222 | 切切
1223 | 切勿
1224 | 亲口
1225 | 亲身
1226 | 亲手
1227 | 亲眼
1228 | 亲自
1229 | 顷
1230 | 顷刻
1231 | 顷刻间
1232 | 顷刻之间
1233 | 请勿
1234 | 穷年累月
1235 | 取道
1236 | 权时
1237 | 全都
1238 | 全力
1239 | 全年
1240 | 全然
1241 | 全身心
1242 | 然
1243 | 人人
1244 | 仍
1245 | 仍旧
1246 | 仍然
1247 | 日复一日
1248 | 日见
1249 | 日渐
1250 | 日益
1251 | 日臻
1252 | 如常
1253 | 如此等等
1254 | 如次
1255 | 如今
1256 | 如期
1257 | 如前所述
1258 | 如上
1259 | 如下
1260 | 汝
1261 | 三番两次
1262 | 三番五次
1263 | 三天两头
1264 | 瑟瑟
1265 | 沙沙
1266 | 上
1267 | 上来
1268 | 上去
1269 | 帮
1270 | 好像
1271 | 几个
1272 | 想要
1273 | 觉得
1274 | 直到
1275 |
--------------------------------------------------------------------------------
/stopwords/specialMarks.txt:
--------------------------------------------------------------------------------
1 | ,
2 | ?
3 | 、
4 | 。
5 | “
6 | ”
7 | 《
8 | .
9 | 》
10 | !
11 | ,
12 | ,
13 | :
14 | ;
15 | ?
16 | ■
17 | □
18 | /
19 | %
20 | \
21 | >
22 | ﹏
23 | <
24 |  ̄
25 | ★
26 | ☆
27 | !
28 | ?
29 | ○
30 | ′
31 | ⊙
32 | `
33 | o
34 | ~
35 | =
36 | '
37 | (
38 | *
39 | )
40 |
--------------------------------------------------------------------------------
/stopwords/stopwords.txt:
--------------------------------------------------------------------------------
1 | !
2 | @
3 | %
4 | #
5 | ^
6 | &
7 | *
8 | (
9 | )
10 | -
11 | _
12 | =
13 | +
14 | \
15 | |
16 | /
17 | ?
18 | <
19 | >
20 | ,
21 | .
22 | !
23 | ,
24 | 。
25 | ?
26 | 、
27 | 《
28 | 》
29 | ……
30 |
--------------------------------------------------------------------------------
/train_w2v.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | # __author__ = 'jrlimingyang'
3 |
4 | import logging
5 | import os.path
6 | import sys
7 | import multiprocessing
8 |
9 | from gensim.corpora import WikiCorpus
10 | from gensim.models import Word2Vec
11 | from gensim.models.word2vec import LineSentence
12 |
13 |
14 |
15 | def train(corpus_path):
16 | path = './'
17 | program = os.path.basename(path + 'train_w2v.py')
18 | logger = logging.getLogger(program)
19 |
20 | logging.basicConfig(format='%(asctime)s: %(levelname)s: %(message)s')
21 | logging.root.setLevel(level=logging.INFO)
22 | inp, outp1, outp2 = corpus_path, path + 'model/all.zh.text.model', path + 'model/all.zh.text.vector'
23 | model = Word2Vec(LineSentence(inp), size=200, window=5, min_count=2,
24 | workers=multiprocessing.cpu_count())
25 | model.save(outp1)
26 | model.wv.save_word2vec_format(outp2, binary=False)
27 |
28 | return model
29 |
30 |
--------------------------------------------------------------------------------
/userdict/user_dict.csv:
--------------------------------------------------------------------------------
1 | _RBT_NAME_
--------------------------------------------------------------------------------