Advertisement
Guest User

Titanic 78 %

a guest
Oct 14th, 2019
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Julia 8.39 KB | None | 0 0
  1. # Вспомогательные функции для вывода
  2.  
  3. "Печать заголовка раздела"
  4. function startSection(title)
  5.     border = repeat("=", length(title))
  6.     println()
  7.     println(border)
  8.     println(title)
  9.     println(border)
  10. end
  11.  
  12. "Печать первых строк датасета"
  13. function printHeads(train, test)
  14.     println()
  15.     println("Тренировочные данные")
  16.     println(train[1:3, :])
  17.     println()
  18.     println("Тестовые данные")
  19.     println(test[1:3, :])
  20. end
  21.  
  22. startSection("Загрузка данных")
  23.  
  24. # Документация по DataFrames: https://juliadata.github.io/DataFrames.jl/stable/
  25. using DataFrames
  26. using CSV
  27. using Statistics
  28.  
  29. # Загрузка наборов данных из файлов
  30. train = CSV.read("input/train.csv", copycols=true)
  31. test = CSV.read("input/test.csv", copycols=true)
  32.  
  33. # Вывод размеров датасетов
  34. println("train shape: ", size(train), ", test shape: ", size(test))
  35.  
  36. printHeads(train, test)
  37.  
  38. #--------------------------------------------------------------------------------
  39.  
  40. startSection("Статистика по полам")
  41.  
  42. # Обращение к столбцам
  43. #col = :Embarked
  44. col = :Sex
  45.  
  46. # Объединение двух сгруппированных датасетов
  47. # (by --- функция группировки, nrow считает количество строк в группе)
  48. stat = hcat(by(train, col, nrow), by(test, col, nrow)[!, 2], makeunique = true)
  49. # Переименование столбцов
  50. names!(stat, [col, :train, :test])
  51. # Добавление столбцов :p1 и :p2 с данными в процентах
  52. insertcols!(stat, 3, :p1=>stat[!, :train]/size(train)[1]*100)
  53. insertcols!(stat, 5, :p2=>stat[!, :test]/size(test)[1]*100)
  54.  
  55. println(stat)
  56.  
  57. startSection("Статистика по выжившим в классах обслуживания")
  58.  
  59. col = :Pclass
  60. target = :Survived
  61. println(sort(aggregate(train[:, [col, target]], col, mean), col))
  62.  
  63. #--------------------------------------------------------------------------------
  64.  
  65. startSection("Обработка отсутствующих значений")
  66.  
  67. println("Статистика по количеству отсутствующих значений в датасетах")
  68. println(vcat(mapcols(x -> sum(ismissing.(x)), train),
  69.              mapcols(x -> sum(ismissing.(x)), test), cols=:union))
  70.  
  71. "Заполнение отсутствующих значений медианными"
  72. function fill_missing_by_median!(df, col)
  73.     recode!(df[!, col], missing => median(skipmissing(df[!, col])))
  74. end
  75.  
  76. for df in [train, test]
  77.     fill_missing_by_median!(df, :Age)
  78.     fill_missing_by_median!(df, :Fare)
  79.     recode!(df[!, :Embarked], missing => "S")
  80.     recode!(df[!,:Cabin], missing => "X")
  81. end
  82.  
  83. println()
  84. println("Статистика по количеству отсутствующих значений в датасетах (после обработки)")
  85. println(vcat(mapcols(x -> sum(ismissing.(x)), train),
  86.              mapcols(x -> sum(ismissing.(x)), test), cols=:union))
  87.  
  88. # Изменение типов столбцов (ранее там допускались Missing, но теперь их нет)
  89. for df in [train, test]
  90.     df[!, :Age] = convert.(Float64, df[!, :Age])
  91.     df[!, :Fare] = convert.(Float64, df[!, :Fare])
  92. end
  93.  
  94. printHeads(train, test)
  95.  
  96. #--------------------------------------------------------------------------------
  97.  
  98. startSection("Преобразование и удаление нечисловых данных")
  99.  
  100. function computeFare(str)
  101.     c = str[1]
  102.     if occursin(c, "ADET") # M
  103.         return 2
  104.     elseif occursin(c, "BC") # H
  105.         return 3
  106.     elseif occursin(c, "FG") # L
  107.         return 1
  108.     else
  109.         return 0
  110.     end
  111. end
  112.  
  113. computeSex(str) =
  114.     if str == "male"
  115.         return 1
  116.     else
  117.         return 2
  118.     end
  119.  
  120. for df in [train, test]
  121.     # Преобразуем :Embarked в целое число
  122.     recode!(df[!, :Embarked], df[!, :Embarked], "S" => "0", "C" => "1", "Q" => "2")
  123.  
  124.     # Точка после имени функции называется "broadcasting".
  125.     # В результате функция применяется к каждому элементу массива
  126.     df[!, :Embarked] = parse.(Int, df[!, :Embarked])
  127.  
  128.     # Преобразуем :Sex в целое число
  129.     df[!, :Sex] = computeSex.(df[!, :Sex])
  130.  
  131.     # Преобразуем :Cabin в целое число
  132.     df[!, :Cabin] = computeFare.(df[!, :Cabin])
  133.  
  134.     # Удаляем столбцы :Name и :Ticket
  135.     select!(df, Not([:Name, :Ticket]))
  136. end
  137.  
  138. printHeads(train, test)
  139.  
  140. #--------------------------------------------------------------------------------
  141.  
  142. startSection("Переход от датафреймов к массивам")
  143.  
  144. # Создаём обычные массивы
  145. y = Array(train[!, :Survived])
  146. X = Matrix(select(train, Not([:Survived, :PassengerId, :Cabin])))
  147.  
  148. # Запоминаем названия столбцов в X
  149. X_names = string.(names(select(train, Not([:Survived, :PassengerId, :Cabin]))))
  150.  
  151. #--------------------------------------------------------------------------------
  152.  
  153. startSection("Логистическая регрессия")
  154.  
  155. # Документация: https://scikitlearnjl.readthedocs.io/en/latest/
  156. using ScikitLearn
  157. using ScikitLearn.CrossValidation: train_test_split
  158.  
  159. # Разбиваем тренировочные данные на "новые" тренировочные и тестовые
  160. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2019)
  161.  
  162. @sk_import preprocessing: StandardScaler
  163.  
  164. scaler = StandardScaler()
  165. X_train_scaled = scaler.fit_transform(X_train)
  166. X_test_scaled = scaler.transform(X_test)
  167.  
  168. @sk_import linear_model: LogisticRegression
  169.  
  170. # Создание и обучение модели
  171. lr = LogisticRegression(random_state=15, solver="sag", max_iter=2500).fit(X_train_scaled, y_train)
  172.  
  173. # Предсказываем выживаемость
  174. y_pred = lr.predict(X_test_scaled)
  175.  
  176. @sk_import metrics: accuracy_score
  177.  
  178. "Вывод значения точности предсказания"
  179. function printAccuracy(prefix, y_test, y_pred)
  180.     println("accuracy_", prefix, " = ", accuracy_score(y_test, y_pred))
  181. end
  182.  
  183. printAccuracy("lr", y_test, y_pred)
  184.  
  185. #--------------------------------------------------------------------------------
  186.  
  187. startSection("Применение градиентного бустинга")
  188.  
  189. # Документация: https://xgboost.readthedocs.io/en/latest/index.html
  190. using XGBoost
  191.  
  192. # Создание и обучение модели
  193. num_round = 20
  194. bst = xgboost(X_train, num_round, label = y_train,
  195.               eta = 0.5, max_depth = 2, objective = "binary:logistic")
  196.  
  197. # Предсказываем вероятности выживаемости
  198. preds_proba = XGBoost.predict(bst, X_test)
  199.  
  200. # Вычисляем 0 или 1 (выживаемость) округлением значений вероятностей
  201. preds_class = round.(preds_proba)
  202.  
  203. printAccuracy("xgb", y_test, preds_class)
  204.  
  205. #--------------------------------------------------------------------------------
  206.  
  207. startSection("Определение оказывающих наибольшее влияние параметров")
  208.  
  209. print(importance(bst, X_names))
  210.  
  211. #--------------------------------------------------------------------------------
  212.  
  213. startSection("Запуск моделей на исходных тестовых данных и подготовка результатов для Kaggle")
  214.  
  215. function prepareSubmission(fname, test, y_pred)
  216.     subm = DataFrame(PassengerID = test[:, :PassengerId], Survived = Int.(y_pred))
  217.     CSV.write(fname, subm)
  218.     println("Файл ", fname, " создан")
  219. end
  220.  
  221. # Преобразуем тестовые данные в матрицу и избавляемся от Missing в типе
  222. full_test = convert.(Float64, Matrix(select(test, Not([:PassengerId, :Cabin]))))
  223.  
  224. # Пользуемся логистической регрессией
  225. y_pred = lr.predict(full_test)
  226. prepareSubmission("titanic_submission_lr.csv", test, y_pred)
  227.  
  228. # Пользуемся градиентным бустингом
  229. y_pred = round.(XGBoost.predict(bst, full_test))
  230. prepareSubmission("titanic_submission_xgb.csv",
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement