这一期比赛可以说是刚好对上我胃口,总算和是和机器学习沾上边了。我的这个方法是采用的是贝叶斯方法,效果达到85.5%,这里给出来分享一下,其他训练方法的朋友也可以交流一下。
先说一点题外话:
之前写的“小样本理论”已经在近期完善了(在连续几个月的时间里,我一想这个问题脑袋就一片浆糊),但是我想在了解一下其他人在该方面的处理方法后再来吹牛,因此这里这么久都没有写后半部分。在这次的文本分类中我用了这一“理论”基础,对统计概率进行重新优化。过段时间分享一个奇异值分解的的方法。
分词是否重要:
对于文本分类来说,很多人或许都以为“分词”很重要;但是当我第一眼看到文本分类的时候,就猜到从理论上来说这完全是扯淡。因此我的这一方法中语句的切分方法从分词的正确性上来说也完全是扯淡的,但是考虑到我的正确率还行,请你相信分词并不太重要。(当然也非常希望有朋友采用当前比较牛的分词算法分完词后,用我的训练结果分类试试,如果能高出两到三个点不要忘记分享之;我一直都没有真正验证过)
训练过程:
训练过程主要分为两步:
第一步:把所有文章中出现的2~4的片段都统计一遍,同时统计这些片段在各个分类出现的次数。
第二部:估计所有的2~4的片段的分类概率意见(其中只有一次的意见被去掉了)。其中概率已经求了log对数,把后面的乘法变为加法避免精度损失造成各种问题。
第一个比较简单,我就不说了,第二个我暂时还不想说,也不说了。不过两个的输出结果我都会共享出来。
分类过程:
把上面所有的片段都当做一个词,采用逆向最大匹配方法进行分词(注意:这里虽然分词了,但由于字典中的词并不能保证正确性,所以单纯从分词合法性上来说分词结果往往是错的)。把所有词的意见累加起来。 取其中概率最大类别。至此结束。为撑场面我把分类程序的源码贴在下面。
# -*- coding: utf-8 -*-
# created by axuanwu 2015.1.25
# key word: hash count
import numpy as np
import math
def getseed(str1):
"""
:param str1: 词条的utf8形式
:return: 词条的hash指纹 256的位随机数
"""
h = 0
for x in str1:
if ord(x) > 256:
h <<= 12
h += ord(x)
else:
h <<= 6
h += ord(x)
while (h >> 256) > 0:
h = (h & (2 ** 256 - 1)) ^ (h >> 256) # 数字不能太大
return h
class MCard():
def __init__(self):
self.M_num = 8
self.N_max = 16777216
self.nummax2 = 24
self.MCARD = [0]
self.Opath = ""
self.index = [0] * 8
self.__keys = ['first_NULL']
self.i_key = 1 # 新增元素增加在位置 i_key 处
self.index2 = [0] * 8
def get_keys(self, iii=-1):
if iii == -1:
return self.__keys[1:]
else:
return self.__keys[iii]
def flush_key(self, iii):
self.__keys[iii] = "" # 去掉keys的值
def getindex(self, str1, for_up=False):
# 获取 词条的 8个随机位置
seed = getseed(str1)
for n in range(0, self.M_num):
a = 0
k = (n + 1)
seed1 = seed
if (seed >> 64) < 0:
seed1 = seed * (n + 15048796327)