0

我正在做一个比较各种分类算法有效性的项目,但我陷入了一个令人沮丧的点。数据可以在这里找到:http: //archive.ics.uci.edu/ml/datasets/Adult分类问题是根据人口普查数据,一个人的年收入是否超过 5 万。

两个示例条目如下:

45, Private, 98092, HS-grad, 9, 已婚-公民-配偶, 销售, 丈夫, 白色, 男性, 0, 0, 60, 美国, <=50K

50, Self-emp-not-inc, 386397, 单身汉, 13, 已婚公民, 销售, 丈夫, 白人, 男性, 0, 0, 60, 美国, <=50K

我熟悉使用欧几里得距离来计算向量之间的差异,但我不确定如何混合使用连续和离散属性。是否有任何有效的方法可以以有意义的方式表示两个向量之间的差异?我很难弄清楚第三个属性(由提取数据集的人根据因素计算的权重,因此相似的权重应该具有相似的属性)之类的值有多大,以及它之间的差异可以保留意义来自男性或女性等离散特征,如果我正确理解该方法,则欧几里得距离仅为 1。我确信可以删除某些类别,但我不想删除那些会显着影响分类的东西。我'

4

3 回答 3

1

当然,您可以通过多种方式扩展欧几里得距离。最简单的扩展将是以下规则:

如果匹配,则该坐标中的距离 = 0,否则为 1

挑战在于使距离的概念与 k-NN 跟进“相关”。在某些情况下(例如教育),我认为最好将教育(离散变量)映射为连续变量,例如教育年限。因此,您需要编写一个函数,例如将“HS-grad”映射到 12,将“Bachelors”映射到 16,诸如此类。

除此之外,直接使用 k-NN 是行不通的,因为多个不同维度之间的“距离”的概念没有得到很好的定义。我认为你最好放弃其中一些维度或以不同的方式加权它们。我不知道您的数据集中的第三个数字(例如 98092)是什么意思,但是如果您使用朴素的欧几里得距离,与年龄等其他维度相比,这将是非常过分的。

我不是机器学习专家,但我个人很想在降维数据集上启动 k-NN,您只需选择一些广泛的人口统计数据(例如年龄、教育程度、婚姻状况)并忽略更棘手/“更嘈杂”的类别.

于 2013-11-25T21:02:28.163 回答
0

您需要将分类变量编码为 n 个二进制变量中的 1 个(变量的 n 个选项,并且在这些变量中只有一个是活动的)。然后标准化你的特征——对于每个特征,减去它的平均值并除以标准差。或者归一化到 0-1 的范围内。它并不完美,但这至少会使尺寸具有可比性。

于 2013-11-26T10:01:53.377 回答
0

为每个数据点创建单独的地图并使用地图转换为双精度值。

def createMap(data: RDD[String]) : Map[String,Double] = {  
 var mapData:Map[String,Double] = Map()
 var counter = 0.0
 data.collect().foreach{ item => 
  counter = counter +1
  mapData += (item -> counter)
 }
 mapData
}

def getLablelValue(input: String): Int = input match {
 case "<=50K" => 0
 case ">50K" => 1
}


val census = sc.textFile("/user/cloudera/census_data.txt")
val orgTypeRdd  = census.map(line => line.split(", ")(1)).distinct
val gradeTypeRdd = census.map(line => line.split(", ")(3)).distinct
val marStatusRdd = census.map(line => line.split(", ")(5)).distinct
val jobTypeRdd = census.map(line => line.split(", ")(6)).distinct
val familyStatusRdd = census.map(line => line.split(", ")(7)).distinct
val raceTypeRdd = census.map(line => line.split(", ")(8)).distinct
val genderTypeRdd = census.map(line => line.split(", ")(9)).distinct
val countryRdd = census.map(line => line.split(", ")(13)).distinct
val salaryRange = census.map(line => line.split(", ")(14)).distinct

val orgTypeMap = createMap(orgTypeRdd)
val gradeTypeMap = createMap(gradeTypeRdd)
val marStatusMap = createMap(marStatusRdd)
val jobTypeMap = createMap(jobTypeRdd)
val familyStatusMap = createMap(familyStatusRdd)
val raceTypeMap = createMap(raceTypeRdd)
val genderTypeMap = createMap(genderTypeRdd)
val countryMap = createMap(countryRdd)
val salaryRangeMap = createMap(salaryRange)


val featureVector = census.map{line => 
  val fields = line.split(", ")
 LabeledPoint(getLablelValue(fields(14).toString) , Vectors.dense(fields(0).toDouble,  orgTypeMap(fields(1).toString) , fields(2).toDouble , gradeTypeMap(fields(3).toString) , fields(4).toDouble , marStatusMap(fields(5).toString), jobTypeMap(fields(6).toString), familyStatusMap(fields(7).toString),raceTypeMap(fields(8).toString),genderTypeMap (fields(9).toString), fields(10).toDouble , fields(11).toDouble , fields(12).toDouble,countryMap(fields(13).toString) , salaryRangeMap(fields(14).toString)))
}
于 2016-07-21T07:01:51.413 回答