<jupyter_start><jupyter_text>**Análise dos dados da Google Play Store**![alt text](https://drive.google.com/uc?id=1YLGpuCftOiytiBp2GuvrHI0tF5p8axl_) A Play Store é a loja de aplicativos do Google, é através dela que os usuários de celulares com sistema operacional Android conseguem baixar apps como WhatsApp, Facebook, Spotify, Netflix e vários outros para seus dispositivos. Apesar do uso ser gratuito, ela também conta com ofertas de aplicativos e serviços pagos. **Objetivo**Os dados dos aplicativos da Play Store têm um enorme potencial para levar as empresas que desenvolvem essas aplicações ao sucesso.O objetivo deste projeto é analisar esses dados com o intuito de ajudar os desenvolvedores a entender que tipo de aplicativo provavelmente atrairá mais usuários.   **Obtenção dos Dados**Os dados usados nessa análise são referentes ao ano de 2018 e foram obtidos a partir do site [Kaggle.com](https://www.kaggle.com/lava18/google-play-store-apps)<jupyter_code># Importando os pacotes necessários
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from wordcloud import WordCloud
# Lendo o arquivo:
df_app = pd.read_csv('/content/drive/My Drive/Curso_Dataquest/googleplaystore.csv')<jupyter_output><empty_output><jupyter_text>**Análise dos Dados**Esta etapa tem por objetivo criar uma consciência situacional inicial e permitir um entendimento de como os dados estão estruturados.  **Dicionário das variáveis*** App - Nome do aplicativo* Category - Categoria à qual o aplicativo pertence* Rating - classificação do aplicativo * Reviews - Número de avaliações de usuários do aplicativo* Size - Tamanho do aplicativo* Installs - Número de downloads / instalações de usuário para o aplicativo * Type - Pago ou Gratuito* Price - preço* Content Rating - Faixa etária em que o aplicativo é direcionado - Crianças / maiores de 21 anos / Adulto* Genres - Um aplicativo pode pertencer a vários gêneros (além da categoria principal). Por exemplo, um jogo musical familiar pertence aos gêneros Música, Jogo, Família.* Last Updated - Data em que o aplicativo foi atualizado pela última vez na Play Store* Current Ver - Versão atual do aplicativo disponível na Play Store* Android Ver - Versão mínima exigida do Android Vamos dar uma olhada nas primeiras linhas do Dataframe.<jupyter_code># Primeiras 5 linhas:
df_app.head()<jupyter_output><empty_output><jupyter_text>**Quantos linhas e quantas colunas o nosso conjunto de dados possui? Quais os tipos das variáveis?**<jupyter_code># Tamanho do Dataframe:
print(f'Número de linhas: {len(df_app.index)}')
print(f'Número de colunas: {len(df_app.columns)}\n')

# Identificando o tipo de cada variável:
display(df_app.dtypes)<jupyter_output>Número de linhas: 10841
Número de colunas: 13<jupyter_text>**Limpeza e transformação dos dados** Precisamos garantir que os dados que estamos analisando sejam precisos, caso contrário, os resultados de nossa análise estarão errados.<jupyter_code># Corrigindo o nome das colunas:
df_app.columns = df_app.columns.str.replace(' ', '_')

# Visualizando os dados novamente:
df_app.head()<jupyter_output><empty_output><jupyter_text>Vou iniciar a análise verificando se há registos duplicados no Dataframe, pois não nos interessa analisar o mesmo aplicativo mais de uma vez.<jupyter_code># Verificando valores duplicados:
if any(df_app.App.duplicated()) is True:
   print(f'Existe valores duplicados na coluna "App"? {True}')
else:
   print(f'Existe valores duplicados na coluna "App"? {False}')<jupyter_output>Existe valores duplicados na coluna "App"? True<jupyter_text>Bom, infelizmente temos registros duplicados, portanto, precisamos remover essas entradas duplicadas e manter apenas uma entrada por aplicativo. Uma coisa que poderíamos fazer é remover as linhas duplicadas aleatoriamente, mas vamos encontrar uma maneira melhor. Quanto maior o número de "Reviews", mais recentes devem ser os dados. Em vez de remover duplicatas aleatoriamente, manteremos apenas a linha com o maior número de avaliações e removeremos as outras entradas. Não sabemos a ordem dos registros e se não ordenarmos podemos correr o risco de eliminar um aplicativo que tem uma avaliação alta. Para ordenar pelo número de "Reviews" precisamos mudar seu tipo de dado para numérico. Quando tentei fazer a transformação recebi o seguinte erro **"ValueError: invalid literal for int() with base 10: '3.0M'"**.Vamos identificar quais linhas têm esse problema:<jupyter_code># Identificando registro:
df_app[~df_app.Reviews.str.isnumeric()]<jupyter_output><empty_output><jupyter_text>Apenas um dos registros possue esse problema além disso os registros das outras colunas estão inconsistentes, na coluna "Category" por exemplo essa linha possui um valor de 1.9, então vou remover essa linha e transformar o tipo do dado.<jupyter_code># Removendo o registro:
df_app.drop(df_app.index[10472], inplace=True)
# Convertendo o tipo dos dados:
df_app.Reviews = pd.to_numeric(df_app.Reviews)<jupyter_output><empty_output><jupyter_text>Agora vou remover os valores duplicados mantendo os registros que tem a avaliação mais alta.<jupyter_code># Removendo os aplicativos duplicados:
df_app = df_app.sort_values(by='Reviews', ascending=False).drop_duplicates('App', keep='first')

# Reorganizando os indices:
df_app = df_app.reset_index(drop=True)
df_app.head()<jupyter_output><empty_output><jupyter_text>Vamos analisar mais a fundo cada um dos atributos. *Size*<jupyter_code># Valores únicos:
display(df_app.Size.unique())<jupyter_output><empty_output><jupyter_text>O tamanho do aplicativo está no formato "string". Precisamos convertê-lo em um valor numérico. Se o tamanho estiver acompanhado da string "k" (exemplo:"512k"), que representa o tamanho do aplicativo em kilobytes, o "k" deve ser removido e o tamanho deve ser convertido em um equivalente a 'megabytes'. Depois removemos a string "M", mudamos a string "Varies with device" para NaN e por último transformamos o tipo de dado para numérico.<jupyter_code># Limpeza da coluna:
df_app.Size = df_app.Size.map(lambda x: str (round ((float (x.rstrip ('k')) / 1024), 1)) if x [-1] == 'k' else x) 
df_app.Size = df_app.Size.map(lambda x: x.rstrip ('M'))
df_app.Size = df_app.Size.map(lambda x: np.nan if x.startswith ('Varies') else x) 
df_app.Size = df_app.Size.astype(float)
# Preenchendo os registros nulos:
df_app.Size.fillna(df_app.groupby('Category')['Size'].transform('mean'),inplace = True)<jupyter_output><empty_output><jupyter_text>*Installs*<jupyter_code>df_app.Installs.value_counts()<jupyter_output><empty_output><jupyter_text>Os números de instalação não parecem precisos o suficiente, podemos ver que a maioria dos valores é (100+, 1.000+, 5.000+ etc.).Não sabemos se um aplicativo com mais de 100.000 instalações possui 100.000 instalações, 200.000 ou 350.000. Posteriormente vamos tentar descobrir quais gêneros de aplicativos atraem mais usuários e para esse propósito não iremos precisar de uma precisão perfeita em relação ao número de usuários.Vamos deixar os números como estão, o que significa que iremos considerar que um aplicativo com mais de 100.000 instalações possui 100.000 instalações e um aplicativo com mais de 1.000.000 instalações possui 1.000.000 instalações e assim por diante. Para realizar esses cálculos, no entanto, vamos precisar converter cada valor de instalação que está como string para número. Isso significa que precisamos remover as vírgulas e os demais caracteres, caso contrário, a conversão falhará e causará um erro.<jupyter_code># Limpando os dados e convertendo os valores:
df_app.Installs = df_app.Installs.apply(lambda x: x.strip('+'))
df_app.Installs= df_app.Installs.apply(lambda x: x.replace(',',''))
df_app.Installs = pd.to_numeric(df_app.Installs)
df_app.Installs.value_counts()<jupyter_output><empty_output><jupyter_text>*Price*<jupyter_code># Valores únicos da coluna "Price"
df_app.Price.unique()<jupyter_output><empty_output><jupyter_text>O preço está no formato de "string". Primeiro precisamos remover o cifrão   para depois convertê-lo em formato numérico.<jupyter_code># Removendo o símbolo monetário e transformando o tipo de dado:
df_app.Price=df_app.Price.apply(lambda x: x.replace('$','') if '$' in str(x) else x)
df_app.Price = pd.to_numeric(df_app.Price)<jupyter_output><empty_output><jupyter_text>*Content_Rating*<jupyter_code># Valores únicos da coluna:
df_app.Content_Rating.unique()<jupyter_output><empty_output><jupyter_text>**'Unrated'** quer dizer sem classificação, não foi informado para que tipo de público esse app foi disponibilizado, vamos identificar quais são esses aplicativos:-<jupyter_code># Identificando os aplicativos:
df_app.loc[(df_app.Content_Rating == "Unrated")]<jupyter_output><empty_output><jupyter_text>Vamos remover essas duas linhas<jupyter_code># Removendo as linhas:
df_app.drop(df_app.index[[4714,8977]], inplace=True)<jupyter_output><empty_output><jupyter_text>*Genres*<jupyter_code>df_app.Genres.unique()<jupyter_output><empty_output><jupyter_text>Os dados estão no formato Categoria; Subcategoria. Vamos dividi-los e extrair apenas a categoria principal.<jupyter_code># Extraindo a categoria principal:
df_app.Genres = df_app.Genres.str.split(';').str[0]
df_app.Genres.unique()<jupyter_output><empty_output><jupyter_text>Observe que entre as categorias temos "Music & Audio" e "Music", que na verdade são a mesma coisa, vamos corrigir isso.<jupyter_code># Corrigindo o nome da categoria.
df_app.Genres.replace(['Music & Audio'], 'Music',inplace =True)
df_app.Genres.unique()<jupyter_output><empty_output><jupyter_text>*Last_Update* Vamos mudar o tipo de dado dessa coluna de string para date. Depois criar uma nova coluna chamada "Last_Updated_Days" que conterá a diferença entre a data da última atualização e hoje, assim podemos analisar quanto tempo (em dias) faz que esse aplicativo foi atualizado.<jupyter_code># Convertendo a data de string para date.
from datetime import datetime,date
temp = pd.to_datetime(df_app.Last_Updated)
# Criando a nova coluna:
df_app['Last_Updated_Days'] = temp.apply(lambda x:date.today()-datetime.date(x))
df_app.head()<jupyter_output><empty_output><jupyter_text>*Android_Ver*<jupyter_code>df_app.Android_Ver.unique()<jupyter_output><empty_output><jupyter_text>A maioria dos valores tem um valor inferior e um valor superior (ou seja, um intervalo), mas o que nos interessa é saber a versão miníma que um dispositivo deve ter para que esse aplicativo funcione.<jupyter_code># Extraindo a versão miníma:
df_app.Android_Ver = df_app.Android_Ver.apply(lambda x:str(x).split(' and ')[0].split(' - ')[0])
df_app.Android_Ver = df_app.Android_Ver.replace('4.4W','4.4')
df_app.Android_Ver.unique()<jupyter_output><empty_output><jupyter_text>A coluna "Current_ver" não será usada em nossa análise.<jupyter_code># Dropando as colunas irrelevantes:
def remove_features(lista_features):
    ''' Função que remove as colunas irrelevantes '''
    for i in lista_features:
        df_app.drop(i,axis=1,inplace=True)
remove_features(['Current_Ver'])<jupyter_output><empty_output><jupyter_text>**Qual a porcentagem de valores ausentes no dataset?**Vamos analisar se a quantidade de valores nulos são siginificativos comparados ao total de entradas.<jupyter_code># Visualizando os valores faltantes:
def missing_value(dataset):
  ''' Função que mostra a porcentagem e o total de valores faltantes de cada coluna, ordenando do maior para o menor '''
  total = dataset.isnull().sum().sort_values(ascending=False)
  percent = dataset.isnull().sum()/dataset.isnull().count().sort_values(ascending=False)
  missing_data = pd.concat([total, percent], axis=1, sort=False, keys=['total', 'percent'])
  missing_data[missing_data['percent']!=0]
  return missing_data
missing_value(df_app)<jupyter_output><empty_output><jupyter_text>A coluna **"Rating"** representa a classificação que o úsuario deu para o aplicativo, essa coluna tem cerca de 15% de valores faltantes, vamos entender melhor como essa classificação é feita. **O que é classificar um app?**Na Play Store (loja de aplicativo da google), classificar um app significa deixar a sua nota de avaliação na página de dowloand do aplicativo com ou sem comentário, a base não possui uma coluna com os comentários.Não é obrigatório deixar uma classificação para o app mas isso ajuda e motiva os desenvolvedores. **Como essa classificação é feita?**Basta clicar nas estrelas que você pretende deixar.![alt text](https://drive.google.com/uc?id=11_EhqLg7QWcK2I0OTRCHYWGTtZKTNDkU)★☆☆☆☆ – Avaliação muito fracaO usuário não gostou da aplicação, contêm um número exagerado de propagandas e a aplicação não foi bem desenvolvida.★★☆☆☆ – Avaliação fracaAinda que seja uma avaliação fraca, o usuário pode ter gostado de alguma funcionalidade do app.★★★☆☆ – Avaliação razoávelO usuário considera que esse aplicativo cumpriu com a sua finalidade, mas precisa melhorar em alguns aspectos, como no desing por exemplo.★★★★☆ – Avaliação boaUm app com 4 estrelas já é considerado muito bom, cumpre o que promete e foi bem desenvolvido.★★★★★ – Avaliação ótimaO usuário considera que esse app foi bem desenvolvido, tem um bom design, ótima navegação e suas funcionalidades são boas. Depois que entendemos como essa avaliação é feita, vamos remover os valores faltantes, como eles não possuem uma classificação podemos concluir que esses aplicativos não são atraentes para os usuários.A coluna "Type" só tem um valor faltante que também será removido.<jupyter_code># Removendo os valores faltantes.
df_app.dropna(axis = 0, how ='any', inplace = True)
# Verificando se os valores foram preenchidos corretamente
missing_value(df_app)<jupyter_output><empty_output><jupyter_text>**Análise Exploratória dos Dados (EDA)** **Quais são as categorias que tem o maior número de aplicativos?**<jupyter_code>plt.figure(figsize=(15,7))
fig = sns.countplot(x=df_app.Category, palette="hls")
plt.xlabel('Categoria')
plt.ylabel('Quantidade')
plt.title('Total de aplicativos por categoria', size=20)
fig.set_xticklabels(fig.get_xticklabels(),rotation=90)
plt.show(fig)<jupyter_output><empty_output><jupyter_text>**Family**, **Game** e **Tools** são as categorias com mais aplicativos.<jupyter_code># Wordcloud com a representação das categorias.
wordcloud = WordCloud(max_font_size=350, collocations=False,width=1920, height=1080, background_color="black").generate(' '.join(df_app.Category))
plt.figure(figsize=(12,8))
plt.imshow(wordcloud, interpolation="bilinear")
plt.axis("off")
plt.tight_layout(pad=0)
plt.show()<jupyter_output><empty_output><jupyter_text>**Os aplicativos são direcionados para quais faixa etárias?**<jupyter_code>plt.figure(figsize=(15,7))
fig = sns.countplot(x=df_app.Content_Rating, palette="hls")
plt.xlabel('Faixa etária')
plt.ylabel('Quantidade')
plt.title('Distribuição da faixa etária', size=20)
fig.set_xticklabels(fig.get_xticklabels(),rotation=90)
plt.show(fig)<jupyter_output><empty_output><jupyter_text>A maioria dos aplicativos está disponível para todos os públicos. **Qual o maior volume de downloads?**<jupyter_code>plt.figure(figsize=(15,7))
fig = sns.countplot(x=df_app.Installs, palette="hls")
plt.xlabel('Número de downloads')
plt.ylabel('Quantidade')
plt.title('Distribuição dos downloads', size=20)
fig.set_xticklabels(fig.get_xticklabels(),rotation=90)
plt.show(fig)<jupyter_output><empty_output><jupyter_text>Muitos aplicativos tiveram cerca de 1 milhão de downloads. **Quais são os 15 aplicativos com o maior número de downloads?**<jupyter_code>plt.figure(figsize=(12,8))
ax=sns.barplot(y='App',x='Installs',data=df_app.head(15))
plt.show()
# Os 15 aplicativos com mais downloads:
df_app.sort_values(by="Installs", ascending=False)[["App", "Installs", "Rating"]].head(15)<jupyter_output><empty_output><jupyter_text>**Quais são os 15 aplicativos com as maiores avaliações?**<jupyter_code>plt.figure(figsize=(12,8))
ax=sns.barplot(y='App',x='Reviews',data=df_app.head(15))
plt.show()

# Os 15 aplicativos com mais avaliações:
df_app.sort_values(by="Reviews", ascending=False)[["App", "Reviews", "Rating"]].head(15)<jupyter_output><empty_output><jupyter_text>As maiores avaliações são para os aplicativos de rede social, o campeão é o Facebook. ![alt text](https://drive.google.com/uc?id=1xN_yspozJbvMn_dXIEP4uWEEmadJz_dB) **A loja tem mais aplicativos pagos ou gratuitos?**<jupyter_code>plt.figure(figsize=(10,8))
fig = sns.countplot(x=df_app.Type,  palette="hls")
plt.xlabel('Tipo')
plt.ylabel('Quantidade')
plt.title('App Free X App Paid', size=20)
fig.set_xticklabels(fig.get_xticklabels(),rotation=90)
plt.show(fig)<jupyter_output><empty_output><jupyter_text>A maioria dos aplicativos da Play Store são gratuitos. **Entre os aplicativos pagos quais são os preços mais frequentes?**<jupyter_code>plt.figure(figsize=(15,7))
price_app = df_app[df_app.Price != 0.0]
price_plot = sns.countplot(price_app.Price, palette = "hls")
plt.xlabel('Preço')
plt.ylabel('Quantidade')
plt.title('Número de aplicativos por preço',size = 20)
price_plot.set_xticklabels(price_plot.get_xticklabels(), rotation=90, ha="right")
plt.show(fig)<jupyter_output><empty_output><jupyter_text>Filtramos somente os aplicativos pagos para poder observar a sua distribuição. Há um número elevado de aplicativos que custam 0.99 e 3.02 dólares.  **Quais são as classificações mais frequentes?**<jupyter_code>plt.figure(figsize=(15,7))
ratings = sns.countplot(x="Rating",data=df_app, palette = "hls")
ratings.set_xticklabels(ratings.get_xticklabels(), rotation=90, ha="right")
plt.xlabel('Classificação')
plt.ylabel('Quantidade')
plt.title('Distribuição da classificação',size = 20)
plt.show(fig)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0994321408290744, 'fraction_numerical': 0.012436115843270869, 'mean_word_length': 6.837561192701379, 'pattern_counts': {'":': 0, '<': 139, '<?xml version=': 0, '>': 139, 'https://': 4, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '35', 'dir': 'jupyter-structured-clean-dedup', 'id': '592743', 'license': 'MIT', 'n_tokens_mistral': 6516, 'n_tokens_neox': 6180, 'n_words': 1789, 'path': 'Google_Play.ipynb', 'repo_name': 'eduardo-almeida/Data-Science', 'size': '17610'}