2013-11-25 1 views
0

Я делаю проект, сравнивающий эффективность различных алгоритмов классификации, но я застрял в расстройстве. Данные можно найти здесь: http://archive.ics.uci.edu/ml/datasets/Adult Проблема классификации заключается в том, составляет ли человек более 50 тыс. В год на основе данных переписи.Расчет расстояния вектора для классификации со смешанными признаками

Два примера записи следующим образом:

45, Private, 98092, HS-ГРАД, 9, женатые-CIV-супруга, Менеджер по продажам, муж, белый, Мужчина, 0, 0, 60, United-государства , < = 50K

50, Self-эй-не-вкл, 386397, бакалавры, 13, женат-стро-супруг, Продажи, Муж, белый, мужчина, 0, 0, 60, United-States, < = 50K

Я знаком с использованием евклидова расстояния, чтобы рассчитать разницу между векторами, но я не уверен, как работать с сочетанием непрерывных и дискретных атрибутов. Существуют ли эффективные методы для представления разницы между двумя векторами значимым образом? Мне тяжело обволакивать, как большие значения, такие как третий атрибут (вес, рассчитанный людьми, которые извлекли набор данных, основанный на факторах, так что аналогичные веса должны иметь схожие атрибуты), а различия между ними могут сохранять значение от дискретных признаков, таких как мужчина или женщина, который является только евклидовым расстоянием 1, если я правильно понимаю метод. Я уверен, что некоторые категории могут быть удалены, но я не хочу, чтобы что-то, что факторы в классификации значительно. Сначала я занимаюсь k-NN, как только получаю это, потом байесовский классификатор и, наконец, модель дерева решений, например C4.5 или ID3, если у меня есть время.

ответ

1

Несомненно, вы можете продлить евклидовое расстояние любым путём. Самое простое расширение будет следующее правило:

расстояние = 0 в этой координате, если есть совпадение, 1 в противном случае

вызов будет делать понятие расстояния «соответствующей» для к-NN наблюдения. В некоторых случаях (например, образование) я считаю, что лучше всего перевести образование (дискретную переменную) в непрерывную переменную, например, на годы образования. Поэтому вам нужно написать функцию, которая отображает, например. «HS-grad» до 12, «Bachelors» до 16, что-то вроде этого.

Помимо этого, использование k-NN напрямую не будет работать, потому что идея «расстояния» между несколькими неоднозначными измерениями не определена. Я думаю, вам лучше сбросить некоторые из этих размеров или похудеть. Я не знаю, что означает третий номер в вашем наборе данных (например, 98092), но если вы используете наивное евклидово расстояние, это будет чрезвычайно сильно взвешенным по сравнению с другими измерениями, такими как возраст.

Я не специалист по компьютерному обучению, но лично у меня возникло бы желание начать k-NN по уменьшенному набору данных размерности, где вы просто выбираете какую-то широкую демографию (например, возраст, образование, семейное положение) и игнорируете сложнее/«более шумные» категории.

+0

Да, я определенно думал о том, чтобы отбросить эту категорию, потому что проблема, которую вы заметили с третьим номером, такая же, как я. Я просто задавался вопросом, есть ли способ превратить его или другие категории в значимую, но не чрезмерно эффективную ценность. Я рассмотрел уменьшение размеров, но мне, вероятно, придется поэкспериментировать, чтобы увидеть, какие из них имеют смысл, а какие нет. – Baldier

+0

+1 для этого: «использование k-NN напрямую не будет работать, потому что идея« расстояния »между несколькими диссоциальными измерениями не определена» :) – bendaizer

0

Вам необходимо закодировать свои категориальные переменные как двоичные переменные из 1-из-n (n вариантов для переменной, и из этих переменных один и только один активен). Затем стандартизируйте свои функции --- для каждой функции вычтите ее среднее значение и разделите на стандартное отклонение. Или нормализуйтесь в диапазоне 0-1. Это не идеально, но это, по крайней мере, сделает размеры сопоставимыми.

+0

Я не слышал о стандартном отклонении процесса , Я обязательно посмотрю на это. Благодарю. – Baldier

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))) 
}