Очистка данных и преобразование переменных в R с использованием данных Открытого чемпионата Австралии по теннису по мужскому туру с 2000 по 2018 год.
Сегодня день 4 и знаменует собой продолжение моего учебного курса # 29dayпроект по науке о данных и тому, что я узнал в науке о данных. Это учебное руководство по очистке и предварительной обработке данных теннисного турнира Открытого чемпионата Австралии по теннису с 2000 по 2019 год, чтобы предсказать, кто может выиграть с помощью R. Вчера мы объединили несколько файлов CSV и разделили данные, за которыми вы можете следить здесь из Сообщение блога.
Что такое методология CRISP-DM?
Если вы посещаете курс аналитики данных в General Assembly, посещаете курс науки о данных в своем университете по алгоритмам анализа данных, выбираете факультатив по информационным технологиям по интересам, изучаете онлайн-курс или можете работать над проектом интеллектуального анализа данных для своего профессора. вы познакомитесь с принципами интеллектуального анализа данных CRISP-DM.
CRISP-DM - это межотраслевой процесс интеллектуального анализа данных. Это также предписанный рабочий процесс аналитики, который я изучил на Генеральной ассамблее в Сиднее, и эти принципы используются в проектах по анализу данных, когда вы консультируетесь с правительством.
Это рабочий процесс методологии CRISP-DM, который поможет вам решить проблемы анализа данных и науки о данных. Вы можете просмотреть каждый из шагов из Smart Vision Europe 2018.
Деловое понимание
Это не бизнес-проблема, но цель постановки задачи заключалась в том, чтобы предсказать победителя финала Открытого чемпионата Австралии по теннису в этом году на основе данных с 2000 по 2018 год.
Понимание данных
Ранее мы получили словарь данных и исследовали данные, анализируя общую структуру данных.
Вот словарь данных переменных:
ATP = Tournament number (men) WTA = Tournament number (women) Location = Venue of tournament Tournament = Name of tounament (including sponsor if relevant) Data = Date of match (note: prior to 2003 the date shown for all matches played in a single tournament is the start date) Series = Name of ATP tennis series (Grand Slam, Masters, International or International Gold) Tier = Tier (tournament ranking) of WTA tennis series. Court = Type of court (outdoors or indoors) Surface = Type of surface (clay, hard, carpet or grass) Round = Round of match Best of = Maximum number of sets playable in match Winner = Match winner Loser = Match loser WRank = ATP Entry ranking of the match winner as of the start of the tournament LRank = ATP Entry ranking of the match loser as of the start of the tournament WPts = ATP Entry points of the match winner as of the start of the tournament LPts = ATP Entry points of the match loser as of the start of the tournament W1 = Number of games won in 1st set by match winner L1 = Number of games won in 1st set by match loser W2 = Number of games won in 2nd set by match winner L2 = Number of games won in 2nd set by match loser W3 = Number of games won in 3rd set by match winner L3 = Number of games won in 3rd set by match loser W4 = Number of games won in 4th set by match winner L4 = Number of games won in 4th set by match loser W5 = Number of games won in 5th set by match winner L5 = Number of games won in 5th set by match loser Wsets = Number of sets won by match winner Lsets = Number of sets won by match loser Comment = Comment on the match (Completed, won through retirement of loser, or via Walkover)
Подготовка данных - очистка данных
Данные были очищены путем кодирования категориальных переменных, преобразования переменных и обнаружения пропущенных значений. Мы уже объединили исходные данные, и фрейм данных «aus_open.csv» считывается в R с использованием StringAsfactors = FALSE, чтобы гарантировать, что все переменные не считываются автоматически как фактор.
################################### # Pre-Processing the Training Data ################################### # Exported aust_open.csv file was exported and a new column was created in Excel to extract the year from the data with non-standardised formatting a <- read.csv("aus_open.csv",stringsAsFactors = FALSE,header = TRUE)
Исследовательский анализ данных
Используя пакет dplyr Хэдли Уикхема, я исследовал структуру данных с помощью функции glimpse ().
############################# # Exploratory Data Analysis ############################# glimpse(a) # view the structure of the training data
Описательная статистика
Результат описательной статистики представлен ниже, сводка всех числовых переменных и пропущенных значений.
summary(a) # descriptive statistics ATP Location Tournament Date Min. :6 Length:2413 Length:2413 Length:2413 1st Qu.:6 Class :character Class :character Class :character Median :6 Mode :character Mode :character Mode :character Mean :6 3rd Qu.:6 Max. :6 Year Series Court Surface Min. :2000 Length:2413 Length:2413 Length:2413 1st Qu.:2004 Class :character Class :character Class :character Median :2009 Mode :character Mode :character Mode :character Mean :2009 3rd Qu.:2014 Max. :2018 Round Best.of Winner Loser Length:2413 Min. :5 Length:2413 Length:2413 Class :character 1st Qu.:5 Class :character Class :character Mode :character Median :5 Mode :character Mode :character Mean :5 3rd Qu.:5 Max. :5 WRank LRank W1 L1 Min. : 1.00 Length:2413 Min. : 0 Length:2413 1st Qu.: 10.00 Class :character 1st Qu.: 7 Class :character Median : 28.00 Mode :character Median : 860 Mode :character Mean : 46.97 Mean : 1863 3rd Qu.: 65.00 3rd Qu.: 2145 Max. :768.00 Max. :16790 NA's :128 W2 L2 W3 L3 Min. :0.000 Min. :0.000 Min. :0.000 Min. :0.000 1st Qu.:6.000 1st Qu.:3.000 1st Qu.:6.000 1st Qu.:2.000 Median :6.000 Median :4.000 Median :6.000 Median :4.000 Mean :5.687 Mean :4.027 Mean :5.743 Mean :3.903 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.:6.000 Max. :7.000 Max. :7.000 Max. :7.000 Max. :7.000 NA's :10 NA's :10 NA's :33 NA's :33 W4 L4 W5 L5 Min. :0.000 Min. :0.000 Min. : 0.000 Min. : 0.000 1st Qu.:6.000 1st Qu.:2.000 1st Qu.: 6.000 1st Qu.: 2.000 Median :6.000 Median :4.000 Median : 6.000 Median : 4.000 Mean :5.753 Mean :3.734 Mean : 5.883 Mean : 3.813 3rd Qu.:6.000 3rd Qu.:6.000 3rd Qu.: 6.000 3rd Qu.: 6.000 Max. :7.000 Max. :7.000 Max. :21.000 Max. :19.000 NA's :346 NA's :346 NA's :1440 NA's :1440 Wsets Lsets Comment Min. : 0.000 Min. : 0.0 Length:2413 1st Qu.: 3.000 1st Qu.: 0.0 Class :character Median : 3.000 Median : 1.0 Mode :character Mean : 4.192 Mean : 1.7 3rd Qu.: 6.000 3rd Qu.: 2.0 Max. :22.000 Max. :20.0 NA's :1444 NA's :1444
Преобразование и кодирование категориальных переменных
Судя по приведенной выше структуре, некоторые атрибуты данных не были приведены в свой правильный тип данных. Это моя любимая часть - возможность преобразовать переменные! Вот так…
# Transform character variables into numeric variables a$W1 <- as.numeric(a$W1) a$L1 <- as.numeric(a$L1) a$WRank <- as.numeric(a$WRank) a$LRank <- as.numeric(a$LRank) ########################################################## # encoding categorical features ########################################################## # Convert categorical variables into factors to represent their levels a$Location <- factor(a$Location) a$Tournament <- factor(a$Tournament) a$Series <- factor(a$Series) a$Court <- factor(a$Court) a$Surface <- factor(a$Surface) a$Best.of <- factor(a$Best.of) a$Round <- factor(a$Round) a$Winner <- factor(a$Winner) a$Loser <- factor(a$Loser) a$Comment <- factor(a$Comment) glimpse(a) # check that structure of categorical variables have converted with levels
# Создание фиктивных переменных для категориальных переменных с более чем 2 уровнями
library(dummies) Round <- dummy(a$Round) Best.of <- dummy(a$Best.of) Winner <- dummy(a$Winner) Loser <- dummy(a$Loser) Comment <- dummy(a$Comment) head(a) # check that the values are been converted to dummy variables str(a)
Обобщите описательную статистику и проверьте структуру преобразованных переменных.
# Descriptive statistics summary(a) # View the structure of the transformed variables the 'dplyr' way > glimpse(a) Observations: 2,413 Variables: 27 $ ATP <int> 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, ... $ Location <fct> Melbourne, Melbourne, Melbourne, Melbourne, Melbourne,... $ Tournament <fct> Australian Open, Australian Open, Australian Open, Aus... $ Date <chr> "1/17/00", "1/17/00", "1/17/00", "1/17/00", "1/17/00",... $ Year <int> 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, ... $ Series <fct> Grand Slam, Grand Slam, Grand Slam, Grand Slam, Grand ... $ Court <fct> Outdoor, Outdoor, Outdoor, Outdoor, Outdoor, Outdoor, ... $ Surface <fct> Hard, Hard, Hard, Hard, Hard, Hard, Hard, Hard, Hard, ... $ Round <fct> 1st Round, 1st Round, 1st Round, 1st Round, 1st Round,... $ Best.of <fct> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, ... $ Winner <fct> Agassi A., Alami K., Arazi H., Behrend T., Bjorkman J.... $ Loser <fct> Puerta M., Manta L., Alonso J., Meligeni F., Stoltenbe... $ WRank <dbl> 1, 35, 41, 106, 76, 151, 39, 54, 30, 64, 98, 29, 34, 6... $ LRank <dbl> 112, 107, 111, 28, 81, 57, 22, 66, 51, 155, 119, 257, ... $ W1 <dbl> 6, 6, 6, 6, 6, 7, 3, 7, 7, 7, 6, 6, 6, 6, 6, 7, 6, 6, ... $ L1 <dbl> 2, 4, 3, 2, 7, 6, 6, 6, 6, 6, 4, 7, 7, 4, 3, 6, 4, 3, ... $ W2 <int> 6, 7, 7, 4, 6, 6, 6, 6, 6, 5, 6, 7, 6, 6, 6, 6, 7, 6, ... $ L2 <int> 2, 6, 6, 6, 4, 1, 1, 4, 4, 7, 4, 6, 3, 4, 3, 3, 6, 3, ... $ W3 <int> 6, 7, 6, 6, 6, 6, 6, NA, 6, 6, 7, 1, 7, 7, 4, 7, 4, 6,... $ L3 <int> 3, 5, 2, 7, 4, 4, 4, NA, 4, 3, 6, 6, 5, 6, 6, 6, 6, 2,... $ W4 <int> NA, NA, NA, 6, 0, NA, 7, NA, NA, 7, NA, 6, 6, NA, 7, N... $ L4 <int> NA, NA, NA, 3, 6, NA, 6, NA, NA, 5, NA, 3, 1, NA, 6, N... $ W5 <int> NA, NA, NA, 6, 6, NA, NA, NA, NA, NA, NA, 6, NA, NA, N... $ L5 <int> NA, NA, NA, 0, 4, NA, NA, NA, NA, NA, NA, 1, NA, NA, N... $ Wsets <int> 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ... $ Lsets <int> 0, 0, 0, 2, 2, 0, 1, 0, 0, 1, 0, 2, 1, 0, 1, 0, 2, 0, ... $ Comment <fct> Completed, Completed, Completed, Completed, Completed,...
Обнаружение недостающих значений
Мы попробуем несколько методов обнаружения пропущенных значений, таких как подсчет количества пропущенных значений в столбце, сумма и взятие среднего.
# Sum the number of missing values > sum(is.na(a)) [1] 6810 # average of the missing values in each column > mean(is.na(a)) [1] 0.1045264 # Count the number of missing values per column > colSums(is.na(a)) ATP Location Tournament Date Year Series Court 0 0 0 0 0 0 0 Surface Round Best.of Winner Loser WRank LRank 0 0 0 0 0 0 5 W1 L1 W2 L2 W3 L3 W4 128 131 10 10 33 33 346 L4 W5 L5 Wsets Lsets Comment 346 1440 1440 1444 1444 0
Получить процент пропущенных значений
При обнаружении пропущенных значений приемлемым порогом для каждого столбца является 5%. Выходные данные подтверждают, что столбцы: L4, W4, L5, W5, Wsets и Lsets имеют пропущенные значения более 5% и могут быть удалены или вменены.
sapply(a, function(df){ sum(is.na(df) ==TRUE)/length(df); }) ATP Location Tournament Date Year Series 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 Court Surface Round Best.of Winner Loser 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 0.000000000 WRank LRank W1 L1 W2 L2 0.000000000 0.002072109 0.053046001 0.054289266 0.004144219 0.004144219 W3 L3 W4 L4 W5 L5 0.013675922 0.013675922 0.143389971 0.143389971 0.596767509 0.596767509 Wsets Lsets Comment 0.598425197 0.598425197 0.000000000
Мы установили пакет Amelia через install.packages («Amelia») в консоль, чтобы помочь с построением карты для визуализации отсутствующих значений. На карте мы видим, что отсутствующие значения обнаруживаются в следующих столбцах:
- Lset - набор неудачников
- Wsets - Победитель сет
- П5 - Победитель пятого сета
- L5 - Проигравший в пятом сете
- L4 - Проигравший в четвертом сете
- П4 - Победитель четвертого сета
Почему я не удалил все недостающие значения?
Я пробовал это, но последняя строка кода помогла мне создать вектор для удаления NA, но она также удалила более 50% моих обучающих данных, так что это не помогло!
View (a) # просмотреть отсутствующие значения
complete.cases (a) # просмотреть отсутствующие значения
which (complete.cases (a)) # просмотреть, какая строка имеет полные значения строк, которые находятся в
which (! complete.cases (a)) # посмотреть, какая строка имеет 'full' NA 'значения строки l
na_vec ‹- which (complete.cases (a))
na_vec‹ - which (! complete.cases (a)) # создает вектор для значений NA
вектор [-na_vec] # с удаленными строками NA.
Как вменить недостающие данные? - числовые переменные
Вмененные данные были нанесены на график, чтобы понять распределение исходных данных. Приемы вменения, которым я следовал, были от автора Миши Элис из его блога. Вот шаги:
# Impute missing values with "pmm" - predicted mean matching. m=5 imputed data sets is default imputed_Data <- mice(a.mis, m=5, maxit = 50, method = 'pmm', seed = 500) summary(imputed_Data) # inspect that missing data has been imputed imputed_Data$imp$Lsets # check imputed method imputed_Data$meth # Plot the imputed data and inspect the distribution xyplot(imputed_Data,WRank ~ W1+L1+W2+L2+W3+L3+W4+L4+L5+W5+LRank,pch=18,cex=1)
Исследовательский анализ данных
ggplot - График плотности числовых переменных
Я использовал ggplot для проверки числовых атрибутов, у которых пропущено менее 5% значений, для визуализации с помощью графиков плотности.
p1 <- ggplot(a, aes(x=a$Year)) + geom_histogram() + ggtitle(" Histogram of Year") p1 p2 <- ggplot(a, aes(x=a$WRank)) + geom_histogram()+ ggtitle(" Histogram of Winner's Ranking") p2 p3 <- ggplot(a, aes(x=a$LRank)) + geom_histogram()+ ggtitle(" Histogram of Loser's Ranking") p3 p4 <- ggplot(a, aes(x=a$W1)) + geom_histogram()+ ggtitle(" Histogram of Winner in the first set") p4 p5 <- ggplot(a, aes(x=a$L1)) + geom_histogram()+ ggtitle(" Histogram of Loser in the first set") p5 p6 <- ggplot(a, aes(x=a$W2)) + geom_histogram()+ ggtitle(" Histogram of Winner in the second set") p6 p7 <- ggplot(a, aes(x=a$L2)) + geom_histogram()+ ggtitle(" Histogram of Loser in the second set") p7 p8 <- ggplot(a, aes(x=a$W3)) + geom_histogram()+ ggtitle(" Histogram of Winner in the third set") p8 p9 <- ggplot(a, aes(x=a$L3)) + geom_histogram()+ ggtitle(" Histogram of Loser in the third set") p9
Визуализируйте категориальные переменные, которые были закодированы фиктивным или горячим кодированием
p16 <- plot(x = a$Comment, main = "Distribution of Comment", xlab = "Comment", ylab = "count") p16 p17 <- plot(x= a$Winner,main = "Distribution of Winner", xlab = "Winner", ylab = "count") p17 p18 <- plot( x = a$Loser, main = "Distribution of Loser", xlab = "Loser", ylab = "Count") p18 p19 <- plot( x = a$Best.of, main = "Distribution of Best.of", xlab = "Best Of", ylab = "Count") p19 p20 <- plot( x = a$Round, main = "Distribution of Tennis Round", xlab = "Round", ylab = "Count") p20
Это график плотности вмененных числовых данных:
график плотности (вмененные_данные)
Обозначения: пурпурный цвет (условные данные) и синий (наблюдаемые данные).
# View the data as individual points stripplot(imputed_Data, pch = 20, cex = 1.2)
R-скрипт для этой предварительной обработки и EDA опубликован здесь, на Github.
Сценарий R Markdown также сохраняется в Github и может быть просмотрен как файл html с помощью команды Knit to Html, это особенно полезно в веб-браузере для построения всех атрибутов данных.
** Примечание для себя:
1. При использовании R Markdown вставьте код R под `` {r cars}, как показано на снимке экрана ниже, чтобы быть точным, это строка 23:
2. Во-вторых, я вставил вторую часть кода R, относящуюся к диаграммам и графикам, под разделом `` {r pressure, echo = FALSE}, и код вставлен в строку 214 .
После того, как мы визуализировали данные в R, мы хотим использовать другие аналитические инструменты, такие как Tableau, для исследования и визуализации данных Открытого чемпионата Австралии по теннису.
Удачного кодирования, поскольку мы продолжаем следующий пост с Tableau в части 3!