我有一个数据库,里面存储了不同群体的人在搜索时使用的关键词。类似于这样:
group1person1: x, y, zgroup1person2: x, z, d...group2person1: z, d, l...
等等
我想看看哪些关键词最能代表某个特定群体。我试图做的是像OkCupid在他们的博客中做的那样: http://blog.okcupid.com/index.php/the-real-stuff-white-people-like/
谁能推荐适合此任务的算法、术语或建议?
(我将使用Python来完成这项工作)
先谢谢了!
回答:
你的问题基本上描述了ID3算法的核心用例。
ID3的输出是一个分类器,具有二叉树结构(ID3、C4.5等通常被称为决策树)。维基百科关于决策树学习的条目实际上对ID3有了一个不错的总结(在算法层面)。
ID3中常用的两个度量标准,用于确定给定节点的数据应如何分割的度量标准称为信息熵。(另一个较少使用的度量标准是Gini不纯度。)ID3算法只是一个递归下降解析器,它测试所有变量/值的组合,并在给出最低加权平均熵的组合上分割节点。
直观上,信息熵试图识别出能够“最佳”分割数据的变量(列)和该变量中的值。“最佳分割”与我们的直觉是一致的。这比用文字描述要容易展示得多。考虑这个数据集:
身高 体重 年龄 每周90分钟有氧运动? 完成5英里跑步? 155 45 31 是 真 160 51 33 否 假 168 52 28 否 假 155 61 25 是 真 169 57 52 是 真 172 81 35 否 假 164 70 23 是 假
如果数据按第4列(该人每周是否进行至少90分钟的有氧运动?)分割,那么结果的两个类别标签组看起来像这样:
是组:[真, 真, 真, 假]
否组:[假, 假, 假]
两个组之间的异质性几乎但不完全是完美的。因此,很明显,第4列是分割此数据的“最佳”变量。
ID3算法中用于确定最佳分割的度量标准只是这种直觉的数学形式化。
这不是一个完美的(数学上精确的)类比,但大致上,你可以认为信息熵与分类变量(离散值)相关,就像方差与连续变量(浮点数)相关一样。换句话说——信息熵(大概)表达了离散数据的方差(或标准偏差)。
这是一个计算熵的Python函数(使用NumPy):
def entropy(arr1) : import numpy as NP ue = NP.unique(x) p, entropy = 0., 0. for itm in ue : ndx = arr1 == itm p += NP.size(x[ndx]) / float(x.size) entropy -= p * NP.log2(p) return entropy
上面的熵函数只是将这两个表达式结合并简化为代码:
p(i) = 频率(结果) = 计数(结果) / 计数(总行数)熵 = p(i) x log2(p(i))的总和
完美的异质性具有熵=0,因此最“区分”的变量/值是当你根据该变量和值分割数据时,加权平均熵最低的那个。熵值接近1的几乎完全是“混合”或接近随机的。
# 模拟一个具有三个类别标签(0, 1, 2)的数据集# 对于你的问题,类别标签是关键词,# 所以只需将每个唯一关键词映射到一个整数值(例如,{ 'keyword1' : 0, 'keyword2' : 1}>>> x = NP.random.randint(0, 3, 20)>>> x array([1, 0, 0, 0, 1, 1, 2, 1, 1, 1, 2, 2, 0, 2, 0, 1, 1, 1, 1, 1])>>> print("{0:.3f}".format(entropy(x))) 0.758
总之,对于你的特定问题,要确定最“区分”的关键词,计算两个类别标签列表的熵,然后计算它们的加权平均值(按每个列表中的项目数加权)。导致加权平均熵最低的分割的关键词就是你要找的。