我得根据一些旅馆的名字把它们归为同一类。我正在使用levenshtein进行分组,但是我已经尝试了多少,有些酒店被排除在他们应该属于的类别之外,或者被归入另一个类别。
例如:所有这些酒店都应属于同一类别:
=============================
最佳西方柏西河高切
最佳西式大肠杆菌
最佳西方勃艮第公爵
最佳西方民谣歌剧
法兰西欧洲最佳酒店
悉尼歌剧院最佳西方酒店
巴黎卢浮宫最佳西方歌剧院
纽维尔最佳西方酒店
=============================
我有一个包含所有酒店名称的列表(大约1000行)。我也有他们应该如何分组。
你知道如何优化我的环境,使它更适合我的情况吗?
$inserted = false;
foreach($hotelList as $key => $value){
if (levenshtein($key, $hotelName, 2, 5, 1) <= abs(strlen($key) - strlen($hotelName))){
array_push($hotelList[$key], trim($line));
$inserted = true;
}
}
// if no match was found add another entry
if (!$inserted){
$hotelList[$hotelName] = array(
trim($line)
);
}
最佳答案
我会认真思考的首先,像这样的分组或“集群”数据是一个相当大的主题,我不会特别深入讨论,但也许会把事情指向一个理想的方向。
你做了一件很好的事情,把Levenshtein标准化为字符串的长度,这是完全正确的,因为你避免了在很多情况下字符串的长度会过度决定相似性的问题。
但是算法并没有解决这个问题。首先,我们要比较单词。”Bent Eastern French Hotels”显然与“Best Western French Hotels”大不相同,但它的得分要比“Best Western Paris Bed and Breakfasts”高。这里要理解的直觉是,你的标记不应该是字符,而应该是单词。
我喜欢苏芮的回答,但我不确定一开始的假设。取而代之的是,让我们从一个通常被称为“bag of words”的又好又简单的东西开始。然后我们实现了一个hashing技巧,这将允许您根据最少使用的单词包含最多信息的直觉来识别关键短语。
如果你订阅了一个想法,那就是酒店品牌的名字就在一开始的时候,你总是可以在接近绳子的开始时歪曲。问题是,你的团队最终很可能成为“法国”和“最佳/西方”(但不是“酒店”-为什么?)是的。
你想让你的结果更准确吗?
从这里开始,我们将不得不采取一些严肃的算法-享受冲浪许多堆栈溢出的主题我的直觉是,我敢打赌很多酒店的名字根本没有商标,所以你也需要不同的类别。我的直觉也是,酒店名称中重复出现的单词数量将相对较少——有些单词将是酒店名称中的常见成员。这些事实将是上述问题的症结所在在这种情况下,有一个非常流行的(如果是这样的话)技术叫做k-means,一个有趣的介绍就是扩展了一个类似于this(非常勇敢地用php编写)的算法,将您选择的n个关键字短语作为集群的n维,然后将集群中心点的大多数组件作为分类标记。(比如说,这将消除“法国”,因为“法国”的点击量将均匀地分布在n维空间中)。
对于一些看起来像是小问题的事情来说,这可能有点太难接受了,但我想强调的是,如果你的数据没有结构化,那么做正确的事情真的没有任何捷径。