赞
踩
SVM(Support Vector Machine)指的是支持向量机,是常见的一种判别方法。在机器学习领域,是一个有监督的学习模型,可以用来进行分类研究。
SVM二分类的基本思想是在特征空间中寻找间隔最大的分离超平面使数据得到高效的二分类,有三种情况:
svm本身是一个追求类别超平面间支持向量距离最大化的二分类器,本实验的目标是对于三种不同类型文本构造分类器,属于多分类问题。主要是通过组合多个二分类器来实现多分类器的构造,多分类通常有一对多,一对一,多对多等。实验中采取的是one-versus-rest一对多方法,简称OVR SVMs。训练步骤如下:
实验语料为三个类型的文档。分别是:从百度新闻搜集的奥运会报道10篇,从延边大学研究生院官网搜集的研究生通知10篇,从微信公众号搜集的机器学习类文章30篇。
主要思路:
1.加载实验数据:(3个类别50篇文章)
2.分词,去停用词:(载入哈工大停用词表,如果文中词语在停用词表则不存储)
3.按照类别的不同,三种文本标签分别标注为0,1,2
4.返回值:分词后的50篇文章,50个类别标签
# TODO: 初始化LinearSVC模型,并利用模型的fit函数来做训练并打印在训练和测试数据上的准确率,使用模型的默认参数。 clf = LinearSVC() svm = CalibratedClassifierCV(clf) # 文本处理 --> 生成训练集 测试集 词频集 def text_processor(text_path, test_size=0.2): folder_list = os.listdir(text_path) data_list = [] # 每个元素均为一篇文章 class_list = [] # 对应于每篇文章的类别 # 一个循环读取一个类别的文件夹 for folder in folder_list: new_folder_path = os.path.join(text_path, folder) # 类别列表 #files = random.sample(os.listdir(new_folder_path),10) files = os.listdir(new_folder_path) # 一个循环读取一篇文章 for file in files: #print(file) with open(os.path.join(new_folder_path, file), 'r', encoding='UTF-8') as fp: raw = fp.read() word_cut = jieba.cut(raw, cut_all=True) # 精确模式切分文章 word_list = list(word_cut) # 一篇文章一个 word_list data_list.append(word_list) if folder == "机器学习": class_list.append(0) elif folder == "奥运咨讯": class_list.append(1) else : class_list.append(2) data_class_list = list(zip(data_list, class_list)) random.shuffle(data_class_list) # 打乱顺序 index = int(len(data_class_list) * test_size) + 1 # 训测比为 8:2 train_list = data_class_list[index:] test_list = data_class_list[:index] train_data_list, train_class_list = zip(*train_list) # (word_list_one[],...), (体育,...) test_data_list, test_class_list = zip(*test_list) # 统计词频 all_words_dict{"key_word_one":100, "key_word_two":200, ...} all_words_dict = {} for word_list in train_data_list: for word in word_list: if all_words_dict.get(word) != None: all_words_dict[word] += 1 else: all_words_dict[word] = 1 all_words_tuple_list = sorted(all_words_dict.items(), key=lambda f: f[1], reverse=True) # 按值降序排序 all_words_list = list(list(zip(*all_words_tuple_list))[0]) # all_words_list[word_one, word_two, ...] #print("测试文本真实标签:",test_class_list) return all_words_list, train_data_list, test_data_list, train_class_list, test_class_list
all_words_list是所有单词的词典,用于统计词频。train_data_list, test_data_list是训练集和测试集词典, train_class_list, test_class_list是训练集和测试集标签。
主要思路:
1.选择训练集中出现的词频进行排序,频率最高的前10个词,作为特征词
2.在训练集和测试集中,判断这些特征词是否出现过,出现过记为1,没出现过记为0
3.将训练集和测试集文档表示为有01组成的长度为10的向量
# 选取特征词 def words_dict(all_words_list, deleteN, stopwords_set=set()): feature_words = [] n = 1 for t in range(deleteN, len(all_words_list), 1): if n > 10: # 维度最大10 break # 非数字 非停用词 长度 1-4 之间 if not all_words_list[t].isdigit() and all_words_list[t] not in stopwords_set and 1 < len( all_words_list[t]) < 3: feature_words.append(all_words_list[t]) n += 1 print("机器学习文本特征:",feature_words) return feature_words from sklearn.feature_extraction.text import TfidfVectorizer # 导入sklearn库 # 文本特征 def text_features(train_data_list, test_data_list, feature_words): def text_feature_(text, feature_words): text_words = set(text) features = [1 if word in text_words else 0 for word in feature_words] return features train_feature_list = [text_feature_(text, feature_words) for text in train_data_list] test_feature_list = [text_feature_(text, feature_words) for text in test_data_list] print("测试文档词频向量:",test_feature_list,"\n") return train_feature_list, test_feature_list
返回值 train_feature_list, test_feature_list是由长度为10的0,1组成的特征向量,每个向量表示一篇文档。
def text_classifier(train_feature_list, test_feature_list, train_class_list, test_class_list):
classifier = svm.fit(train_feature_list, train_class_list)
y_pred = classifier.predict(test_feature_list)
y_true = test_class_list
print("测试文本真实标签:", y_true)
print("测试文本预测标签:", y_pred)
C = confusion_matrix(y_true, y_pred)
print("混淆矩阵:\n",C, end='\n')

选取10个最高频词作为特征词,根据特征词是否在测试文本中出现,标记为0或1。这样就将所有的文档根据特征词是否出现表示为了特征向量。

测试文档的测试标签全部等于测试文档的真实标签,svm准确度为1.混淆矩阵如图。
这是由于机器学习所选出现的高频特征词专业性较强,与奥运咨询和通知类文本有较大的区分度。因而取得了很好的分类效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。