<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Arquivo de Projetos - Data Universe</title>
	<atom:link href="https://datauniverse.com.br/tag/projetos/feed/" rel="self" type="application/rss+xml" />
	<link>https://datauniverse.com.br/tag/projetos/</link>
	<description>Conteúdos sobre as áreas de Data Science, Data Analytics, Estatística e Probabilidade, Inteligência Artificial e Machine Learning.</description>
	<lastBuildDate>Thu, 18 Sep 2025 13:51:09 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://datauniverse.com.br/wp-content/uploads/2026/01/cropped-data-universe-logo-icon-32x32.png</url>
	<title>Arquivo de Projetos - Data Universe</title>
	<link>https://datauniverse.com.br/tag/projetos/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Game Theory: Prisioner&#8217;s Dilemma utilizando Deep Q-Learning (DQN) Tensorflow.Keras</title>
		<link>https://datauniverse.com.br/game-theory-prisioners-dilemma-utilizando-tensorflow-keras/</link>
					<comments>https://datauniverse.com.br/game-theory-prisioners-dilemma-utilizando-tensorflow-keras/#respond</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Wed, 30 Oct 2024 20:03:36 +0000</pubDate>
				<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://dataisle.co/?p=2552</guid>

					<description><![CDATA[<p>A Teoria dos Jogos (Game Theory) é um campo da matemática e da economia que estuda como indivíduos ou grupos tomam decisões estratégicas em cenários onde suas escolhas afetam uns aos outros. Esses &#8220;jogos&#8221; envolvem situações onde o resultado de cada jogador depende das ações dos outros, e a teoria busca entender as melhores estratégias [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/game-theory-prisioners-dilemma-utilizando-tensorflow-keras/">Game Theory: Prisioner&#8217;s Dilemma utilizando Deep Q-Learning (DQN) Tensorflow.Keras</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow" open><summary>Detalhes do projeto</summary>
<ul class="wp-block-list">
<li><strong>Link do projeto no Github:</strong> <a href="https://github.com/cerqueiralex/project-personal-prisioners-dilemma" target="_blank" rel="noreferrer noopener">https://github.com/cerqueiralex/project-personal-prisioners-dilemma</a></li>



<li><strong>Tecnologias:</strong> Python, Tensorflow, Random, Deep Q-Learning (DQN)</li>



<li><strong>Categorias:</strong> Data Science, Machine Learning</li>
</ul>
</details>



<p>A Teoria dos Jogos (Game Theory) é um campo da matemática e da economia que estuda como indivíduos ou grupos tomam decisões estratégicas em cenários onde suas escolhas afetam uns aos outros. </p>



<p>Esses &#8220;jogos&#8221; envolvem situações onde o resultado de cada jogador depende das ações dos outros, e a teoria busca entender as melhores estratégias para cada participante. </p>



<p>É amplamente aplicada em economia, psicologia, ciência política e até mesmo em biologia evolutiva para entender desde competições de mercado até comportamentos sociais.</p>



<h3 class="wp-block-heading">O Dilema dos Prisioneiros</h3>



<p>O <strong>Dilema dos Prisioneiros</strong> é um dos exemplos mais conhecidos da Teoria dos Jogos. Nele, dois suspeitos de um crime são presos e mantidos separados. Cada um tem duas opções: confessar ou não confessar o crime. As possíveis consequências são as seguintes:</p>



<ul class="wp-block-list">
<li>Se ambos não confessarem, cada um pega uma pena leve (digamos, 1 ano).</li>



<li>Se um confessar e o outro não confessar, o que confessou fica livre, enquanto o que não confessou recebe a pena máxima (10 anos).</li>



<li>Se ambos confessarem, cada um recebe uma pena moderada (5 anos).</li>
</ul>



<p>Os prisioneiros não conseguem se comunicar e precisam tomar suas decisões sem saber o que o outro vai escolher. </p>



<p>Isso cria um dilema: embora a melhor estratégia conjunta seja ambos não confessarem (levando a penas mínimas para ambos), o medo de que o outro possa confessar leva cada prisioneiro a considerar confessar como uma opção mais segura, pois, se o outro confessar, ao menos evitará a pena máxima.</p>



<p>Esse dilema gira em torno de um tema extremamente importante dentro da nossa sociedade: Confiança!</p>



<h3 class="wp-block-heading">Relação entre Teoria dos Jogos e o Dilema dos Prisioneiros</h3>



<p>O Dilema dos Prisioneiros demonstra um conceito importante na Teoria dos Jogos chamado equilíbrio de Nash. Esse equilíbrio ocorre quando, em uma situação com múltiplos jogadores, ninguém pode melhorar seu resultado mudando de estratégia, desde que os outros jogadores mantenham suas escolhas. </p>



<p>No dilema, o equilíbrio de Nash é que ambos confessem, pois, dado que um prisioneiro está confessando, o outro não ganha nada ao ficar em silêncio.</p>



<p>Esse exemplo ajuda a ilustrar uma verdade fundamental na Teoria dos Jogos: os interesses individuais e os interesses coletivos nem sempre estão alinhados. </p>



<p>Situações como o Dilema dos Prisioneiros são comuns em mercados, política e comportamento social, onde decisões baseadas apenas no próprio interesse individual podem levar a resultados subótimos para todos.</p>



<h2 class="wp-block-heading">Primeiro experimento: Testando partidas aleatórias</h2>



<p>Antes de fazer um treinamento de modelo, resolvi testar como seria o comportamento de escolhas aleatórias.</p>



<p>Para isso foi construido esse código onde cada prisioneiro, aleatóriamente escolhe entre cooperar &#8220;cooperate&#8221; ou trair &#8220;betray&#8221;.</p>



<pre class="wp-block-code"><code>import random
import matplotlib.pyplot as plt  # Importando a biblioteca para gráficos

# Definir número de rodadas
rounds = 1000

# Pontuação acumulada para cada prisioneiro
score_prisoner1 = 0
score_prisoner2 = 0

# Listas para armazenar as pontuações acumuladas ao longo das rodadas
scores_prisoner1 = &#91;]
scores_prisoner2 = &#91;]

# Função para simular uma rodada do dilema dos prisioneiros
def play_round():
    # Cada prisioneiro escolhe aleatoriamente entre "cooperar" ou "trair"
    choice1 = random.choice(&#91;"cooperate", "betray"])
    choice2 = random.choice(&#91;"cooperate", "betray"])

    if choice1 == "cooperate" and choice2 == "cooperate":
        return 3, 3, choice1, choice2  # Ambos cooperam
    elif choice1 == "betray" and choice2 == "betray":
        return 1, 1, choice1, choice2  # Ambos traem
    elif choice1 == "cooperate" and choice2 == "betray":
        return 0, 5, choice1, choice2  # Prisioneiro 1 coopera, Prisioneiro 2 trai
    else:
        return 5, 0, choice1, choice2  # Prisioneiro 1 trai, Prisioneiro 2 coopera

# Executa os rounds, acumula pontuação e exibe cada rodada
for round_num in range(1, rounds + 1):
    points1, points2, choice1, choice2 = play_round()
    score_prisoner1 += points1
    score_prisoner2 += points2

    # Armazenar pontuações acumuladas
    scores_prisoner1.append(score_prisoner1)
    scores_prisoner2.append(score_prisoner2)

    # Exibir resultados da rodada
    print(f"Rodada {round_num}:")
    print(f"  Prisioneiro 1 escolheu: {choice1} | Pontos nesta rodada: {points1}")
    print(f"  Prisioneiro 2 escolheu: {choice2} | Pontos nesta rodada: {points2}")
    print(f"  Pontuação acumulada - Prisioneiro 1: {score_prisoner1}, Prisioneiro 2: {score_prisoner2}")
    print("-" * 40)

# Resultados finais
print("Resultado Final:")
print(f"Pontuação final do Prisioneiro 1: {score_prisoner1}")
print(f"Pontuação final do Prisioneiro 2: {score_prisoner2}")

# Gerar gráfico da pontuação acumulada ao longo dos rounds
plt.figure(figsize=(12, 6))
plt.plot(scores_prisoner1, label="Prisioneiro 1", color='red')
plt.plot(scores_prisoner2, label="Prisioneiro 2", color='blue')
plt.title("Evolução da Pontuação Acumulada dos Prisioneiros")
plt.xlabel("Rodadas")
plt.ylabel("Pontuação Acumulada")
plt.legend()
plt.grid()
plt.show()</code></pre>



<p>Esse é o resultado de 5 partidas aleatórias, onde ocorreram 2 vitórias para o prisioneiro 2 e 3 vitórias para o prisioneiro 1:</p>



<p><img decoding="async" src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXebUqBcZ_8_sDuw4EPufRHKeLOqdLJLLpUYeNdSTIctB_Rxyy2uUIRJZYZVuGrh_UeHxW1invRqe98Wyq5OrK7qcMHMMly57Cw5CP3ZykGzC9serhbw-ocW7xuN-9veXjZlpc36maQjLNGVbx9-0CDU880?key=OLLPDFBT4KpuCuEfGbCoYyTD" width="345" height="111"></p>



<p><img decoding="async" src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXeoWU0fTXn8OKSnUYM3DRDrCh1NlJj8XaoAeRSLqbUbtloM893WRJ8wHXtTFsVHg-3DSiUboyLKoqlAKTG0Vazu6ipURYKQ2UBMBwtS4uF119t6alD8YK_sd39xLV8nQCvIZB7tWSXMSRxroctj8BGSwVQ?key=OLLPDFBT4KpuCuEfGbCoYyTD" width="345" height="107"></p>



<p><img decoding="async" src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXc32iRMG7uOnOGWP0Ne0tOWncdM5bVgDZMG3is2FQxD32HjpZw1PBd9SJpxdVGUOQMfLrIjBMQgabMi01AzJzhR07easAuBwGBrheyrlEh0_OW846xQZuHxcnVwPRn85VT-Xc42eVVjGRMaOoGAVt6V0YmS?key=OLLPDFBT4KpuCuEfGbCoYyTD" width="345" height="108"></p>



<p><img loading="lazy" decoding="async" src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcGnI1shLnFlxF4ixkiJkjNwq_f03__jZlJyfOgywaJXfu6PPSPM63I1zFqqW0AtW9AJ30xyVKiEIBdLsNjSp7oE2RwFj2FdN5Pk99g9Psf2jBuC9ofAqSN1Ckw91H4V1cQ20VgIu-AiLEiYk5095D29QIR?key=OLLPDFBT4KpuCuEfGbCoYyTD" width="345" height="109"></p>



<p><img loading="lazy" decoding="async" src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXdEY56HcSsZKHtWn8Uradh2SBCA_5jGNEOTcWPlbZI5AuydgvmRxAr_KQm_x-B9n3jky1or0USj-IZllOLW82KWTcN15WWIqruZ5-iICkjIEgP33iD-ZS_MPBUmOuvVyPOW4d-tZM5YjDRIO--R-hA4XoSh?key=OLLPDFBT4KpuCuEfGbCoYyTD" width="345" height="108"></p>



<p>Olhando para o gráfico abaixo, é possível observar que no comportamento aleatório, o acúmulo das pontuações está sempre muito próximo, o que é esperado.</p>



<p>Pela projeção de 1000 rodadas, é possível verificar que não é uma boa estratégia e que a chance de vitória é sempre de 50%, mas esse gráfico é interessante para compreender as próximas etapas.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1014" height="547" src="https://datauniverse.com.br/wp-content/uploads/2024/10/image-3.png" alt="" class="wp-image-2557" srcset="https://datauniverse.com.br/wp-content/uploads/2024/10/image-3.png 1014w, https://datauniverse.com.br/wp-content/uploads/2024/10/image-3-300x162.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/10/image-3-768x414.png 768w" sizes="(max-width: 1014px) 100vw, 1014px" /></figure>



<h2 class="wp-block-heading">Desenvolvendo o código em Python utilizando tensorflow.keras</h2>



<p>A lógica que foi desenvolvida acontece de forma que somente o primeiro prisioneiro irá receber o treinamento de aprendizado por reforço com Q-Learning enquanto que o segundo prisioneiro sempre irá tomar decisões aleatórias.</p>



<p>A ideia é que o primeiro prisioneiro aprenda a melhorar sua estratégia conforme ele aprende com as decisões do segundo.</p>



<p>Para implementar o Q-Learning usando TensorFlow (TF), vamos usar uma rede neural para aproximar a função Q. Esse método é conhecido como Deep Q-Learning (DQN) e é útil para problemas com espaço de estado grande ou contínuo, onde o uso de uma tabela Q tradicional seria inviável.</p>



<p>Neste exemplo do Dilema dos Prisioneiros, vamos configurar uma rede neural simples para estimar a Q-valor para cada ação (&#8220;cooperar&#8221; ou &#8220;trair&#8221;) com base na última ação do outro prisioneiro. Essa rede será treinada usando a biblioteca TensorFlow.</p>



<p>Para a Construção do Modelo Q, usamos uma rede neural de três camadas (duas ocultas e uma de saída) para prever o valor Q para cada ação. A entrada é o estado atual, que inclui a última ação do Prisioneiro 2 representada como um vetor one-hot.</p>



<pre class="wp-block-code"><code># Parâmetros do aprendizado
learning_rate = 0.01
discount_factor = 0.9
exploration_rate = 1.0
exploration_decay = 0.01
min_exploration_rate = 0.01
rounds = 1000

# Pontuação acumulada para cada prisioneiro
score_prisoner1 = 0
score_prisoner2 = 0

# Contadores de escolhas para cada prisioneiro
choices_count = {
    "prisoner1": {"cooperate": 0, "betray": 0},
    "prisoner2": {"cooperate": 0, "betray": 0}
}

# Definir ações
actions = &#91;"cooperate", "betray"]

# Converter ações para índices
action_to_index = {action: i for i, action in enumerate(actions)}

# Construir a rede neural para aproximar a função Q
def build_model(input_size, output_size):
    model = Sequential(&#91;
        Dense(24, input_dim=input_size, activation="relu"),
        Dense(24, activation="relu"),
        Dense(output_size, activation="linear")
    ])
    model.compile(optimizer=Adam(learning_rate=learning_rate), loss="mse")
    return model

# Modelo Q para o Prisioneiro 1
model = build_model(input_size=2, output_size=len(actions))

# Função para simular uma rodada do dilema dos prisioneiros
def play_round(prisoner1_choice, prisoner2_choice):
    if prisoner1_choice == "cooperate" and prisoner2_choice == "cooperate":
        return 3, 3  # Ambos cooperam
    elif prisoner1_choice == "betray" and prisoner2_choice == "betray":
        return 1, 1  # Ambos traem
    elif prisoner1_choice == "cooperate" and prisoner2_choice == "betray":
        return 0, 5  # Prisioneiro 1 coopera, Prisioneiro 2 trai
    else:
        return 5, 0  # Prisioneiro 1 trai, Prisioneiro 2 coopera

# Função para escolher a ação do Prisioneiro 1
def choose_action(state):
    if np.random.rand() &lt; exploration_rate:
        # Exploração: escolhe uma ação aleatória
        return random.choice(actions)
    else:
        # Exploração: escolhe a ação com maior valor Q estimado
        q_values = model.predict(state)
        return actions&#91;np.argmax(q_values&#91;0])]

# Executa os rounds
last_prisoner2_choice = random.choice(actions)

for round_num in range(1, rounds + 1):
    # Estado atual (última ação do Prisioneiro 2 em one-hot encoding)
    state = np.array(&#91;&#91;1 if last_prisoner2_choice == action else 0 for action in actions]])

    # Escolher a ação do Prisioneiro 1
    prisoner1_choice = choose_action(state)
    prisoner2_choice = random.choice(actions)

    # Contabilizar as escolhas
    choices_count&#91;"prisoner1"]&#91;prisoner1_choice] += 1
    choices_count&#91;"prisoner2"]&#91;prisoner2_choice] += 1

    # Jogar a rodada e obter a recompensa
    points1, points2 = play_round(prisoner1_choice, prisoner2_choice)
    score_prisoner1 += points1
    score_prisoner2 += points2

    # Próximo estado
    next_state = np.array(&#91;&#91;1 if prisoner2_choice == action else 0 for action in actions]])

    # Atualização do Q-valor
    target = points1 + discount_factor * np.max(model.predict(next_state)&#91;0])
    target_f = model.predict(state)
    target_f&#91;0]&#91;action_to_index&#91;prisoner1_choice]] = target

    # Treinar o modelo
    model.fit(state, target_f, epochs=1, verbose=0)

    # Atualizar a última escolha do Prisioneiro 2 para a próxima rodada
    last_prisoner2_choice = prisoner2_choice

    # Decaimento da taxa de exploração
    exploration_rate = max(min_exploration_rate, exploration_rate * exploration_decay)</code></pre>



<p><strong>Escolha de Ação</strong>: </p>



<p>A função choose_action usa uma política ε-greedy para escolher uma ação com base na previsão do modelo Q. Durante o treinamento, o agente explora mais, e com o tempo passa a explorar menos à medida que aprende.</p>



<p><strong>Atualização do Q-valor e Treinamento do Modelo</strong>: </p>



<p>Após cada rodada, calculamos o alvo para a ação escolhida, que é o valor de recompensa somado ao valor Q máximo esperado para o próximo estado. Esse valor é então usado para ajustar o modelo.</p>



<p><strong>Decaimento da Taxa de Exploração</strong>: </p>



<p>Após cada rodada, a taxa de exploração diminui, incentivando o agente a explorar menos conforme aprende.</p>



<p>Este modelo aproxima o comportamento de um agente Q-Learning com aprendizado por reforço, mas utiliza uma rede neural para aprender Q-valores ao invés de uma tabela Q.</p>



<h2 class="wp-block-heading">Motivos para o Decaimento da Taxa de Exploração</h2>



<p>A taxa de exploração no aprendizado por reforço decai com o tempo para permitir que o agente aprenda a <strong>explorar menos</strong> conforme ele acumula conhecimento do ambiente e <strong>explorar mais as ações que têm maior potencial de recompensa</strong>.</p>



<p>Se a taxa de exploração subisse com o tempo, o agente continuaria a tomar ações de forma aleatória mesmo quando ele já tivesse uma estratégia razoavelmente boa, o que impediria que ele convergisse para uma política estável.</p>



<p><strong>Exploração Inicial</strong>:</p>



<p>No início do treinamento, o agente tem pouca ou nenhuma informação sobre quais ações são melhores. Uma alta taxa de exploração (ε) permite que o agente experimente várias ações, conheça o ambiente e construa uma base inicial de conhecimento.</p>



<p><strong>Exploração x Exploração</strong>:</p>



<p>Conforme o treinamento avança, o agente já terá <strong>acumulado experiência</strong> e <strong>aprendido quais ações tendem a dar melhores recompensas</strong>. Se a taxa de exploração permanecer alta, o agente continuará a tomar decisões aleatórias, reduzindo a efetividade do aprendizado.</p>



<p>Diminuindo a exploração, o agente passa a <strong>confiar mais em seu aprendizado (exploração)</strong> e a escolher as ações que parecem mais promissoras com base nos valores Q já aprendidos.</p>



<p><strong>Convergência para uma Política Ótima</strong>:</p>



<p>O objetivo é que, ao final do treinamento, o agente seja capaz de seguir uma <strong>política ótima</strong>, ou seja, uma estratégia onde ele maximiza suas recompensas.</p>



<p>Um ε próximo de zero é desejável ao fim do treinamento, pois indica que o agente seguirá a política que ele acredita ser ótima, baseada nas recompensas que ele acumulou ao longo do tempo.</p>



<h3 class="wp-block-heading">Primeiros Rounds</h3>



<p>Nos primeiros rounds é possível observar que com uma taxa de exploração alta, o primeiro prisioneiro fica bem atrás do segundo nas pontuações e isso acontece até mais ou menos a rodada 50 onde el começa a aprender os padrões: </p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="439" height="704" src="https://datauniverse.com.br/wp-content/uploads/2024/10/image.png" alt="" class="wp-image-2554" srcset="https://datauniverse.com.br/wp-content/uploads/2024/10/image.png 439w, https://datauniverse.com.br/wp-content/uploads/2024/10/image-187x300.png 187w" sizes="(max-width: 439px) 100vw, 439px" /></figure>



<h3 class="wp-block-heading">Resultados do treinamento com 1000 rounds</h3>



<p>Ao final do treinamento com 1000 rodadas o prisioneiro 1 consegue aprender que quanto mais ele escolher a opção de betray, mais ele aumenta as chances de ganhar.</p>



<p>Mesmo realizando diversos testes, o comportamento do aprendizado é o mesmo! Sempre que o prisioneiro 1 aprende que betray é a melhor estratégia por volta da rodada 50, ele começa a ganhar e disparar na pontuação.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="289" height="154" src="https://datauniverse.com.br/wp-content/uploads/2024/10/image-2.png" alt="" class="wp-image-2556"/></figure>



<p>Ao final conseguimos visualizar a curva de aprendizado do prisioneiro 1</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1014" height="547" src="https://datauniverse.com.br/wp-content/uploads/2024/10/image-1.png" alt="" class="wp-image-2555" srcset="https://datauniverse.com.br/wp-content/uploads/2024/10/image-1.png 1014w, https://datauniverse.com.br/wp-content/uploads/2024/10/image-1-300x162.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/10/image-1-768x414.png 768w" sizes="(max-width: 1014px) 100vw, 1014px" /></figure>



<h2 class="wp-block-heading">Porque sempre escolher a opção de betray é matematicamente a estratégia predominante?</h2>



<p>Escolher a opção de &#8220;betray&#8221; (trair) no Dilema dos Prisioneiros é matematicamente vantajoso devido à análise de recompensas associadas a cada combinação de decisões dos prisioneiros. Vamos detalhar essa análise.</p>



<h3 class="wp-block-heading">Cenário do Dilema dos Prisioneiros</h3>



<p>Considere duas opções para cada prisioneiro: <strong>cooperate</strong> (cooperar) ou <strong>betray</strong> (trair). A tabela a seguir mostra as recompensas associadas a cada combinação de decisões:</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Prisioneiro 1</th><th>Prisioneiro 2</th><th>Pontuação P1</th><th>Pontuação P2</th></tr></thead><tbody><tr><td>Cooperate</td><td>Cooperate</td><td>3</td><td>3</td></tr><tr><td>Cooperate</td><td>Betray</td><td>0</td><td>5</td></tr><tr><td>Betray</td><td>Cooperate</td><td>5</td><td>0</td></tr><tr><td>Betray</td><td>Betray</td><td>1</td><td>1</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">Análise das Estratégias</h3>



<ol class="wp-block-list">
<li><strong>Se ambos cooperam</strong>:
<ul class="wp-block-list">
<li>Ambos recebem 3 pontos. Este é o cenário ótimo para ambos, mas requer confiança.</li>
</ul>
</li>



<li><strong>Se o Prisioneiro 1 coopera e o Prisioneiro 2 trai</strong>:
<ul class="wp-block-list">
<li>O Prisioneiro 1 recebe 0 pontos, enquanto o Prisioneiro 2 recebe 5 pontos.</li>



<li><strong>Perda máxima</strong> para o Prisioneiro 1, se ele confiar.</li>
</ul>
</li>



<li><strong>Se o Prisioneiro 1 trai e o Prisioneiro 2 coopera</strong>:
<ul class="wp-block-list">
<li>O Prisioneiro 1 recebe 5 pontos e o Prisioneiro 2 recebe 0 pontos.</li>



<li><strong>Máxima recompensa</strong> para o Prisioneiro 1, se o outro confiar.</li>
</ul>
</li>



<li><strong>Se ambos traem</strong>:
<ul class="wp-block-list">
<li>Ambos recebem 1 ponto. Este é um resultado pior do que ambos cooperarem, mas melhor do que a situação em que um coopera e o outro trai.</li>
</ul>
</li>
</ol>



<h3 class="wp-block-heading">Estratégia Dominante</h3>



<p>Matematicamente, a escolha de trair se torna a <strong>estratégia dominante</strong> para o Prisioneiro 1:</p>



<ul class="wp-block-list">
<li><strong>Se o Prisioneiro 2 escolher cooperar</strong>:
<ul class="wp-block-list">
<li>Trair (5 pontos) é melhor do que cooperar (3 pontos).</li>
</ul>
</li>



<li><strong>Se o Prisioneiro 2 escolher trair</strong>:
<ul class="wp-block-list">
<li>Trair (1 ponto) é melhor do que cooperar (0 pontos).</li>
</ul>
</li>
</ul>



<p>Portanto, independentemente da escolha do Prisioneiro 2, a opção de trair sempre resulta em uma pontuação igual ou maior para o Prisioneiro 1. Essa análise leva à conclusão de que trair é a estratégia mais vantajosa.</p>



<ul class="wp-block-list">
<li><strong>Teorema da Estratégia Dominante</strong>: A escolha de &#8220;betray&#8221; é a melhor estratégia para o Prisioneiro 1, pois maximiza a pontuação em relação à escolha do outro jogador, independentemente da ação que ele escolha.</li>



<li><strong>Resultados a Longo Prazo</strong>: Se o Prisioneiro 1 sempre trair, ele garante uma pontuação consistente e evita a possibilidade de perda máxima que ocorre quando coopera e o outro trai.</li>
</ul>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1014" height="547" src="https://datauniverse.com.br/wp-content/uploads/2024/10/image-4.png" alt="" class="wp-image-2558" srcset="https://datauniverse.com.br/wp-content/uploads/2024/10/image-4.png 1014w, https://datauniverse.com.br/wp-content/uploads/2024/10/image-4-300x162.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/10/image-4-768x414.png 768w" sizes="(max-width: 1014px) 100vw, 1014px" /></figure>



<p>Assim, a escolha de sempre trair (betray) é matematicamente fundamentada, pois, ao longo de várias iterações do jogo, essa estratégia levará a um desempenho superior, especialmente quando considerada a incerteza sobre as ações do oponente.</p>



<h2 class="wp-block-heading">Conclusão</h2>



<p>O que é mais curioso de ser observado de acordo com esse dilema e dadas suas condições, é que o aprendizado de máquina, simula de forma matemática, muitas das decisões individuais que são tomadas na sociedade e a estratégia dominante de sempre escolher a opção de trair ilustra a lógica do &#8220;racional egoísmo&#8221;, onde indivíduos optam por maximizar seus próprios benefícios em detrimento dos outros, resultando em um comportamento que pode minar a confiança nas relações interpessoais. </p>



<p>O dilema dos prisioneiros exemplifica a tensão entre interesses individuais e coletivos, refletindo como a escolha de trair ou cooperar pode se manifestar em interações sociais cotidianas. </p>



<p>Essa ideia é algo que vemos na sociedade, em situações como negociações, amizades ou até na política, onde a desconfiança pode levar a escolhas que, embora benéficas a curto prazo para um indivíduo, criam um ambiente de desconfiança generalizada.</p>



<p>Assim, a prevalência da traição como estratégia pode dificultar a formação de laços de confiança, essenciais para a colaboração e a construção de uma comunidade coesa, mostrando que a cooperação, embora menos intuitiva em um contexto competitivo, pode ser crucial para o bem-estar coletivo e a prosperidade a longo prazo.</p>



<p>Nele, a escolha de trair sempre parece a opção mais segura, mostrando que, muitas vezes, a gente pensa primeiro em si mesmo do que em quem está do lado. </p>



<h2 class="wp-block-heading">Referências</h2>



<ul class="wp-block-list">
<li><a href="https://en.wikipedia.org/wiki/Game_theory">https://en.wikipedia.org/wiki/Game_theory</a></li>



<li><a href="https://en.wikipedia.org/wiki/Prisoner%27s_dilemma">https://en.wikipedia.org/wiki/Prisoner%27s_dilemma</a></li>



<li><a href="https://medium.com/@shruti.dhumne/deep-q-network-dqn-90e1a8799871">https://medium.com/@shruti.dhumne/deep-q-network-dqn-90e1a8799871</a></li>
</ul>
<p>O post <a href="https://datauniverse.com.br/game-theory-prisioners-dilemma-utilizando-tensorflow-keras/">Game Theory: Prisioner&#8217;s Dilemma utilizando Deep Q-Learning (DQN) Tensorflow.Keras</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/game-theory-prisioners-dilemma-utilizando-tensorflow-keras/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Descubra quem não te segue de volta no Instagram! Automação com Python e Pandas</title>
		<link>https://datauniverse.com.br/descubra-quem-nao-te-segue-de-volta-no-instagram-automacao-com-python-e-pandas/</link>
					<comments>https://datauniverse.com.br/descubra-quem-nao-te-segue-de-volta-no-instagram-automacao-com-python-e-pandas/#respond</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Sat, 24 Aug 2024 22:27:10 +0000</pubDate>
				<category><![CDATA[Artigo]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://dataisle.co/?p=2499</guid>

					<description><![CDATA[<p>Neste vídeo ensino passo a passo como exportar os dados de seguidores do Instagram para o Python. Em seguida, mostro como tratar esses dados com a biblioteca Pandas, permitindo que você descubra facilmente quais usuários que você segue não estão mais te seguindo de volta. É uma ótima oportunidade para aprender a automatizar essa análise [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/descubra-quem-nao-te-segue-de-volta-no-instagram-automacao-com-python-e-pandas/">Descubra quem não te segue de volta no Instagram! Automação com Python e Pandas</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Neste vídeo ensino passo a passo como exportar os dados de seguidores do Instagram para o Python. </p>



<p>Em seguida, mostro como tratar esses dados com a biblioteca Pandas, permitindo que você descubra facilmente quais usuários que você segue não estão mais te seguindo de volta. </p>



<p>É uma ótima oportunidade para aprender a automatizar essa análise e otimizar sua presença nas redes sociais com técnicas de ciência de dados.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Descubra quem não te segue de volta no Instagram! Automação com Python e Pandas" width="1290" height="726" src="https://www.youtube.com/embed/V6D5Sdv2Na4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>Hashtags: <a href="https://www.youtube.com/hashtag/python">#Python</a> <a href="https://www.youtube.com/hashtag/pandas">#Pandas</a> <a href="https://www.youtube.com/hashtag/instagram">#Instagram</a> <a href="https://www.youtube.com/hashtag/dataanalysis">#DataAnalysis</a> <a href="https://www.youtube.com/hashtag/socialmediaanalytics">#SocialMediaAnalytics</a> <a href="https://www.youtube.com/hashtag/datascience">#DataScience</a> <a href="https://www.youtube.com/hashtag/instagramfollowers">#InstagramFollowers</a> <a href="https://www.youtube.com/hashtag/codingtutorial">#CodingTutorial</a> <a href="https://www.youtube.com/hashtag/datacleaning">#DataCleaning</a></p>
<p>O post <a href="https://datauniverse.com.br/descubra-quem-nao-te-segue-de-volta-no-instagram-automacao-com-python-e-pandas/">Descubra quem não te segue de volta no Instagram! Automação com Python e Pandas</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/descubra-quem-nao-te-segue-de-volta-no-instagram-automacao-com-python-e-pandas/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>GA4 + Google Bigquery: Integrar dados do GA4 com o Big Query + Looker</title>
		<link>https://datauniverse.com.br/ga4-google-bigquery-integrar-dados-do-ga4-com-o-big-query-looker/</link>
					<comments>https://datauniverse.com.br/ga4-google-bigquery-integrar-dados-do-ga4-com-o-big-query-looker/#respond</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Fri, 23 Aug 2024 02:12:22 +0000</pubDate>
				<category><![CDATA[Data Engineering]]></category>
		<category><![CDATA[Google Analytics]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://dataisle.co/?p=2496</guid>

					<description><![CDATA[<p>Neste vídeo, guio você pelo processo completo de migração de dados do Google Analytics 4 para o BigQuery, seguido pela integração desses dados com um relatório no Looker Studio. Com instruções detalhadas e exemplos práticos, você aprenderá como configurar a exportação de dados, criar uma conexão robusta no BigQuery e, finalmente, transformar esses dados em [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/ga4-google-bigquery-integrar-dados-do-ga4-com-o-big-query-looker/">GA4 + Google Bigquery: Integrar dados do GA4 com o Big Query + Looker</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Neste vídeo, guio você pelo processo completo de migração de dados do Google Analytics 4 para o BigQuery, seguido pela integração desses dados com um relatório no Looker Studio. </p>



<p>Com instruções detalhadas e exemplos práticos, você aprenderá como configurar a exportação de dados, criar uma conexão robusta no BigQuery e, finalmente, transformar esses dados em insights visuais poderosos usando o Looker Studio. </p>



<p>Ideal para profissionais que buscam otimizar a análise de dados e aprimorar a tomada de decisões com ferramentas avançadas do Google.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="GA4 + Google Bigquery: Integrar dados do GA4 com o Big Query + Looker" width="1290" height="726" src="https://www.youtube.com/embed/L7N9Jqq8e-k?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>
<p>O post <a href="https://datauniverse.com.br/ga4-google-bigquery-integrar-dados-do-ga4-com-o-big-query-looker/">GA4 + Google Bigquery: Integrar dados do GA4 com o Big Query + Looker</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/ga4-google-bigquery-integrar-dados-do-ga4-com-o-big-query-looker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Calculadora de Teste-Z no Google Sheets para um grupo de duas amostras aleatórias</title>
		<link>https://datauniverse.com.br/calculadora-de-teste-z-no-google-sheets-para-um-grupo-de-duas-amostras-aleatorias/</link>
					<comments>https://datauniverse.com.br/calculadora-de-teste-z-no-google-sheets-para-um-grupo-de-duas-amostras-aleatorias/#respond</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Sat, 29 Jun 2024 20:48:57 +0000</pubDate>
				<category><![CDATA[Estatística]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://dataisle.co/?p=2344</guid>

					<description><![CDATA[<p>O teste Z é um teste estatístico usado para determinar se há uma diferença significativa entre a média de uma amostra e a média de uma população, ou entre as médias de duas amostras, quando a variância populacional é conhecida. Ele é baseado na distribuição normal padrão. Acesse este artigo para entender tudo sobre a [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/calculadora-de-teste-z-no-google-sheets-para-um-grupo-de-duas-amostras-aleatorias/">Calculadora de Teste-Z no Google Sheets para um grupo de duas amostras aleatórias</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>O <strong>teste Z</strong> é um teste estatístico usado para determinar se há uma diferença significativa entre a média de uma amostra e a média de uma população, ou entre as médias de duas amostras, quando a variância populacional é conhecida. Ele é baseado na distribuição normal padrão.</p>



<p>Acesse <a href="https://datauniverse.com.br/teste-de-hipoteses/">este artigo</a> para entender tudo sobre a teoria e prática de como utilizar a calculadora: <a href="https://datauniverse.com.br/teste-de-hipoteses/">https://datauniverse.com.br/teste-de-hipoteses/</a></p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1019" height="705" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-3.png" alt="" class="wp-image-2345" srcset="https://datauniverse.com.br/wp-content/uploads/2024/06/image-3.png 1019w, https://datauniverse.com.br/wp-content/uploads/2024/06/image-3-300x208.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/06/image-3-768x531.png 768w" sizes="(max-width: 1019px) 100vw, 1019px" /></figure>



<div class="wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-a89b3969 wp-block-buttons-is-layout-flex">
<div class="wp-block-button"><a class="wp-block-button__link has-text-align-center wp-element-button" href="https://docs.google.com/spreadsheets/d/1fqEo9cV8_hj4quDSBtzDYApWapca9q4Wd7HLgJ7-1sQ/copy" target="_blank" rel="noreferrer noopener nofollow">Acessar Calculadora</a></div>
</div>



<p>Link para acessar a calculadora: <a href="https://docs.google.com/spreadsheets/d/1fqEo9cV8_hj4quDSBtzDYApWapca9q4Wd7HLgJ7-1sQ/copy" target="_blank" rel="noreferrer noopener">https://docs.google.com/spreadsheets/d/1fqEo9cV8_hj4quDSBtzDYApWapca9q4Wd7HLgJ7-1sQ/copy</a></p>



<h2 class="wp-block-heading">Como usar:</h2>



<p>Basta preencher as duas colunas de observações das amostras manualmente com os próprios dados ou atualizar os dados aleatóriamente marcando e desmarcando a caixa:</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="299" height="159" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-15.png" alt="" class="wp-image-2361"/></figure>



<h3 class="wp-block-heading">Gráficos de distribuição</h3>



<p>Os gráficos de distribuição, ajudam a visualizar o formato da distribuição dos dados das observações das amostras A e B.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="244" src="https://datauniverse.com.br/wp-content/uploads/2024/07/image-1024x244.png" alt="" class="wp-image-2376" srcset="https://datauniverse.com.br/wp-content/uploads/2024/07/image-1024x244.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/07/image-300x71.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/07/image-768x183.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/07/image.png 1135w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Uma <strong>distribuição estatística</strong> é uma função que descreve a frequência com que diferentes valores ocorrem em um conjunto de dados. Representa a maneira como os dados são distribuídos ao longo de um intervalo, e pode ser apresentada de várias formas, como distribuições normais, binomiais, uniformes, entre outras.</p>



<p>Ao analisar um gráfico de dispersão, você pode tomar decisões informadas sobre a natureza da relação entre variáveis, identificar anomalias e planejar próximas etapas na análise de dados.</p>



<h2 class="wp-block-heading">Para que serve:</h2>



<p>O teste Z é útil para:</p>



<ol class="wp-block-list">
<li>Comparar a média de uma amostra com uma média populacional conhecida.</li>



<li>Comparar as médias de duas amostras independentes.</li>



<li>Verificar hipóteses sobre proporções em amostras grandes.</li>
</ol>



<h2 class="wp-block-heading">Como funciona:</h2>



<p>O teste Z segue os seguintes passos:</p>



<ol class="wp-block-list">
<li><strong>Formulação das Hipóteses</strong>:</li>
</ol>



<ul class="wp-block-list">
<li><strong>Hipótese Nula (H₀)</strong>: Afirma que não há diferença (por exemplo, a média da amostra é igual à média populacional).</li>



<li><strong>Hipótese Alternativa (Hₐ)</strong>: Afirma que há uma diferença (por exemplo, a média da amostra é diferente da média populacional).</li>
</ul>



<ol class="wp-block-list">
<li><strong>Cálculo da Estatística Z</strong>:</li>
</ol>



<p><strong>Para uma amostra única:</strong><br></p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="136" height="68" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-4.png" alt="" class="wp-image-2350"/></figure>



<p><strong>Onde:</strong></p>



<figure class="wp-block-table"><table><tbody><tr><td><img decoding="async" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-5.png" alt=""></td><td> é a média da amostra</td></tr><tr><td><img decoding="async" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-6.png" alt=""></td><td>é a média populacional</td></tr><tr><td><img decoding="async" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-7.png" alt=""></td><td>é o desvio padrão populacional</td></tr><tr><td><img decoding="async" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-8.png" alt=""></td><td>é o tamanho da amostra</td></tr></tbody></table></figure>



<ul class="wp-block-list">
<li></li>
</ul>



<p>Para duas amostras:</p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="288" height="100" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-9.png" alt="" class="wp-image-2355"/></figure>



<p><br><strong>Onde:</strong></p>



<figure class="wp-block-table"><table><tbody><tr><td><img decoding="async" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-10.png" alt=""></td><td> são as médias das amostras</td></tr><tr><td><img decoding="async" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-11.png" alt=""></td><td>são as médias populacionais</td></tr><tr><td><img decoding="async" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-14.png" alt=""></td><td>são os desvios padrão populacionais</td></tr><tr><td><img decoding="async" src="https://datauniverse.com.br/wp-content/uploads/2024/06/image-13.png" alt=""></td><td>são os tamanhos das amostras</td></tr></tbody></table></figure>



<ol class="wp-block-list">
<li><strong>Determinação do P-valor</strong>:</li>
</ol>



<ul class="wp-block-list">
<li>O P-valor é a probabilidade de obter um valor Z tão extremo ou mais extremo que o valor observado, assumindo que a hipótese nula é verdadeira.</li>



<li>Para um teste bicaudal, calcula-se a probabilidade nas duas extremidades da distribuição normal.</li>
</ul>



<ol class="wp-block-list">
<li><strong>Comparação com o Nível de Significância (α)</strong>:</li>
</ol>



<ul class="wp-block-list">
<li>Se o P-valor é menor que α (por exemplo, 0,05), rejeita-se a hipótese nula.</li>



<li>Se o P-valor é maior que α, não se rejeita a hipótese nula.</li>
</ul>



<h2 class="wp-block-heading">Exemplos de aplicação:</h2>



<ul class="wp-block-list">
<li>Verificar se a média de altura dos estudantes de uma escola é diferente da média nacional.</li>



<li>Comparar a eficácia de dois medicamentos com base em amostras de pacientes.</li>
</ul>



<p>O teste Z é particularmente adequado quando o tamanho da amostra é grande (geralmente (n &gt; 30)) e a variância populacional é conhecida. Se a variância populacional não é conhecida e a amostra é pequena, utiliza-se geralmente o teste t de Student.</p>



<h2 class="wp-block-heading">Parâmetros estatísticos</h2>



<ol class="wp-block-list">
<li><strong>Hipótese Nula (H₀)</strong>: É a hipótese inicial que assume que não há efeito ou diferença significativa entre os grupos ou condições em estudo. Geralmente, é a hipótese que se tenta refutar ou rejeitar.</li>



<li><strong>Hipótese Alternativa (Hₐ)</strong>: É a hipótese que contrasta com a hipótese nula. Sugere que há um efeito significativo ou diferença entre os grupos ou condições em estudo. Aceitar Hₐ implica rejeitar H₀.</li>



<li><strong>Number of Tails</strong>: Refere-se ao tipo de teste estatístico baseado na hipótese alternativa. Pode ser:
<ul class="wp-block-list">
<li>Unicaudal (one-tailed): Testa se um parâmetro é maior ou menor que um valor específico.</li>



<li>Bicaudal (two-tailed): Testa se um parâmetro é diferente (maior ou menor) de um valor específico.</li>
</ul>
</li>



<li><strong>Z Statistic (Z-score)</strong>: É uma medida que descreve a posição de uma amostra em relação à média de uma distribuição normal padrão, medida em desvios padrão. Um Z-score indica quantos desvios padrão um valor está acima ou abaixo da média.</li>



<li><strong>P-value (two-tails)</strong>: É a probabilidade de observar um valor extremo ou mais extremo do que o observado, assumindo que a hipótese nula é verdadeira. Em um teste bicaudal, considera as extremidades de ambas as caudas da distribuição.</li>



<li><strong>Intervalo de Confiança (1-α)</strong>: É um intervalo estimado a partir dos dados da amostra, dentro do qual se espera que o parâmetro populacional verdadeiro esteja, com um nível de confiança de (1-α)%. Por exemplo, um intervalo de confiança de 95% significa que temos 95% de certeza de que o parâmetro verdadeiro está dentro desse intervalo.</li>



<li><strong>Significância Desejada (α)</strong>: É o nível de significância pré-definido para um teste estatístico, representando a probabilidade de cometer um erro do Tipo I (rejeitar a hipótese nula quando ela é verdadeira). Comumente, α é 0,05 ou 5%.</li>



<li><strong>Variância Conhecida (σ)</strong>: Refere-se à variância da população que é conhecida ou assumida conhecida, usada em testes estatísticos como o teste Z.</li>



<li><strong>Desvio Padrão da Amostra (σ)</strong>: É uma medida de dispersão que indica o quanto os valores de uma amostra variam em relação à média da amostra.</li>



<li><strong>Média (X̄)</strong>: É a soma de todos os valores da amostra dividida pelo número de observações. Representa a média aritmética dos dados da amostra.</li>



<li><strong>Observações (n)</strong>: Refere-se ao número total de dados ou pontos de amostra coletados em um estudo.</li>



<li><strong>Diferença de Média Hipotetizada</strong>: É a diferença entre as médias populacionais que se espera ou se assume existir sob a hipótese alternativa.</li>



<li><strong>Soma Total de Observações na Amostra</strong>: Refere-se à soma de todos os valores observados na amostra.</li>



<li><strong>Diferença entre as Amostras</strong>: Refere-se à diferença observada entre as médias ou proporções de duas ou mais amostras.</li>



<li><strong>Decisão Estatística a ser Tomada quando Hₐ é Falsa, Aceitar H₀</strong>: Significa que, com base nos resultados do teste estatístico, não há evidência suficiente para rejeitar a hipótese nula, então aceitamos H₀ como verdadeira (ou não rejeitamos H₀).</li>
</ol>



<p>Esses parâmetros são essenciais para conduzir e interpretar testes estatísticos, ajudando a determinar a significância dos resultados de pesquisas e experimentos.</p>
<p>O post <a href="https://datauniverse.com.br/calculadora-de-teste-z-no-google-sheets-para-um-grupo-de-duas-amostras-aleatorias/">Calculadora de Teste-Z no Google Sheets para um grupo de duas amostras aleatórias</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/calculadora-de-teste-z-no-google-sheets-para-um-grupo-de-duas-amostras-aleatorias/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Processamento de dados em lote com PySpark e Docker</title>
		<link>https://datauniverse.com.br/processamento-de-dados-em-lote-com-pyspark-e-docker/</link>
					<comments>https://datauniverse.com.br/processamento-de-dados-em-lote-com-pyspark-e-docker/#respond</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Thu, 28 Mar 2024 11:27:10 +0000</pubDate>
				<category><![CDATA[Data Engineering]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://dataisle.co/?p=2193</guid>

					<description><![CDATA[<p>Neste projeto, compartilharei o passo a passo de um projeto de processamento de dados em lote que utilizei em meu portfolio. O objetivo era transformar um arquivo JSON em um banco SQLite, utilizando PySpark e Docker. 1. Configurando o ambiente com Docker Compose Comecei criando um cluster PySpark em Docker com três containers: um master, [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/processamento-de-dados-em-lote-com-pyspark-e-docker/">Processamento de dados em lote com PySpark e Docker</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow" open><summary>Detalhes do projeto</summary>
<ul class="wp-block-list">
<li><strong>Link do projeto no Github:</strong> <a href="https://github.com/cerqueiralex/etl-pyspark-sqlite-docker/" target="_blank" rel="noreferrer noopener">https://github.com/cerqueiralex/etl-pyspark-sqlite-docker/</a></li>



<li><strong>Tecnologias:</strong> Python, PySpark, SQLite</li>



<li><strong>Categorias:</strong> Data Engineering, ETL</li>
</ul>
</details>



<p>Neste projeto, compartilharei o passo a passo de um projeto de processamento de dados em lote que utilizei em meu portfolio. O objetivo era transformar um arquivo JSON em um banco SQLite, utilizando PySpark e Docker.</p>



<figure class="wp-block-image"><a href="https://camo.githubusercontent.com/2be86e6ffa7921293dab3dc5e613ede05b5039d175ddd9f3e2d7eefc2b92942b/68747470733a2f2f692e696d6775722e636f6d2f3155766f526a642e706e67" target="_blank" rel="noreferrer noopener"><img decoding="async" src="https://camo.githubusercontent.com/2be86e6ffa7921293dab3dc5e613ede05b5039d175ddd9f3e2d7eefc2b92942b/68747470733a2f2f692e696d6775722e636f6d2f3155766f526a642e706e67" alt=""/></a></figure>



<p><strong>1. Configurando o ambiente com Docker Compose</strong></p>



<p>Comecei criando um cluster PySpark em Docker com três containers: um master, dois workers e um history para armazenar <a href="https://datauniverse.com.br/logs-logging/">logs</a>. Utilizei o Docker Compose para facilitar a configuração e o gerenciamento do cluster.</p>



<figure class="wp-block-image"><a href="https://camo.githubusercontent.com/4e3a38d0b1c9d373b467662c2e232dbbbbbe3b9979c3c7daf99b6d6af5b774c9/68747470733a2f2f692e696d6775722e636f6d2f756f6d663768742e706e67" target="_blank" rel="noreferrer noopener"><img decoding="async" src="https://camo.githubusercontent.com/4e3a38d0b1c9d373b467662c2e232dbbbbbe3b9979c3c7daf99b6d6af5b774c9/68747470733a2f2f692e696d6775722e636f6d2f756f6d663768742e706e67" alt=""/></a></figure>



<p><strong>2. Gerando a base de dados SQLite</strong></p>



<p>Em seguida, desenvolvi dois scripts Python:</p>



<ul class="wp-block-list">
<li><strong>Gerador de dados:</strong>&nbsp;Este script gerou um arquivo JSON com dados fictícios, simulando um cenário real.</li>



<li><strong>Criador da base de dados:</strong>&nbsp;Este script criou a base de dados SQLite e definiu a conexão com o arquivo JSON gerado.</li>
</ul>



<p><strong>3. Implementando o job ETL com PySpark</strong></p>



<p>O job ETL foi escrito em PySpark e implementado no container master do cluster. As principais etapas do job foram:</p>



<ul class="wp-block-list">
<li><strong>Leitura do arquivo JSON:</strong>&nbsp;O arquivo JSON gerado no passo 2 foi lido como um DataFrame do Spark.</li>



<li><strong>Definição do schema:</strong>&nbsp;Um schema foi definido para garantir a consistência dos dados na base SQLite.</li>



<li><strong>Tratamento de dados:</strong>&nbsp;O campo de e-mail foi tratado para remover caracteres inválidos e garantir a padronização.</li>



<li><strong>Gravação na base SQLite:</strong>&nbsp;O DataFrame final foi gravado na base SQLite criada no passo 2.</li>
</ul>



<p><strong>4. Executando o job ETL</strong></p>



<p>O job ETL foi executado no container master do cluster através do comando&nbsp;<code>spark-submit</code>. O processo de execução foi monitorado no console do container.</p>



<p><strong>5. Resultados e Considerações</strong></p>



<p>O job ETL foi executado com sucesso, transformando o arquivo JSON em um banco SQLite. A utilização do PySpark e do Docker proporcionou um ambiente escalável e eficiente para o processamento de dados.</p>



<p><strong>Pontos importantes do projeto:</strong></p>



<ul class="wp-block-list">
<li><strong>Utilização do Docker Compose para facilitar a configuração do cluster PySpark.</strong></li>



<li><strong>Desenvolvimento de scripts Python para gerar a base de dados SQLite e o arquivo JSON.</strong></li>



<li><strong>Implementação do job ETL em PySpark com leitura de dados, definição de schema, tratamento de dados e gravação na base SQLite.</strong></li>



<li><strong>Execução do job ETL no container master do cluster e monitoramento do processo.</strong></li>
</ul>



<p><strong>Conclusão:</strong></p>



<p>Este projeto demonstra como o PySpark e o Docker podem ser utilizados para realizar o processamento de dados em lote de forma eficiente e escalável. A utilização de containers facilita a configuração do ambiente e o deploy do job em diferentes plataformas.</p>



<p><strong>Este projeto foi realizado para fins de estudo e demonstração de habilidades. O código-fonte e os dados utilizados estão disponíveis em meu repositório GitHub.</strong></p>
<p>O post <a href="https://datauniverse.com.br/processamento-de-dados-em-lote-com-pyspark-e-docker/">Processamento de dados em lote com PySpark e Docker</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/processamento-de-dados-em-lote-com-pyspark-e-docker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Processo de ETL simples utilizando datalake MinIO</title>
		<link>https://datauniverse.com.br/processo-de-etl-simples-utilizando-datalake-minio/</link>
					<comments>https://datauniverse.com.br/processo-de-etl-simples-utilizando-datalake-minio/#respond</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Thu, 01 Feb 2024 02:27:40 +0000</pubDate>
				<category><![CDATA[Data Engineering]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://dataisle.co/?p=2052</guid>

					<description><![CDATA[<p>MinIO é um armazenamento de objetos de alto desempenho compatível com S3. Ele é projetado para cargas de trabalho de inteligência artificial/aprendizado de máquina em grande escala, data lakes e bancos de dados. É definido por software e pode ser executado em qualquer infraestrutura em nuvem ou local. Aqui irei organizar os arquivos na nuvem [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/processo-de-etl-simples-utilizando-datalake-minio/">Processo de ETL simples utilizando datalake MinIO</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow" open><summary>Detalhes do projeto</summary>
<ul class="wp-block-list">
<li><strong>Link do projeto no Github:</strong> <a href="https://github.com/cerqueiralex/etl-com-minio/" target="_blank" rel="noreferrer noopener">https://github.com/cerqueiralex/etl-com-minio/</a></li>



<li><strong>Tecnologias:</strong> Python, MinIO</li>



<li><strong>Categorias:</strong> Data Engineering, ETL</li>
</ul>
</details>



<p>MinIO é um armazenamento de objetos de alto desempenho compatível com S3. Ele é projetado para cargas de trabalho de inteligência artificial/aprendizado de máquina em grande escala, data lakes e bancos de dados. É definido por software e pode ser executado em qualquer infraestrutura em nuvem ou local.</p>



<p>Aqui irei organizar os arquivos na nuvem utilizando MiniO em máquina local, que possui os mesmos princípios do serviço S3 da Amazon AWS.</p>



<p>Site oficial: <a href="https://min.io">https://min.io</a></p>



<figure class="wp-block-image aligncenter size-full"><img loading="lazy" decoding="async" width="717" height="450" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-12.png" alt="" class="wp-image-2064" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-12.png 717w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-12-300x188.png 300w" sizes="(max-width: 717px) 100vw, 717px" /></figure>



<h2 class="wp-block-heading">Vantagens e desvantagens de utilizar MinIO como datalake</h2>



<p><strong>Vantagens</strong></p>



<ul class="wp-block-list">
<li>Muito bom na recuperação de objetos.</li>



<li>Boa interface de navegação</li>



<li>Compatibilidade com formatos diferentes de storage</li>



<li>Muito fácil criar e trabalhar com buckets a nível de S3</li>
</ul>



<p><strong>Desvantagens</strong></p>



<ul class="wp-block-list">
<li>Baixa documentação</li>



<li>Pequenos bugs entre as atualizações</li>



<li>Dificudade de ver os <a href="https://datauniverse.com.br/logs-logging/">logs</a></li>



<li>Pouco seguro se não for bem implementado</li>
</ul>



<h2 class="wp-block-heading">Acessando o Dashboard MinIO utilizando o Docker Localmente</h2>



<p>Não irei entrar no detalhe de como subir os containers docker aqui, porém através <a href="https://min.io/docs/minio/container/index.html" target="_blank" rel="noreferrer noopener">desta documentação</a> você consegue implantar um servidor MinIO de um único nó e uma única unidade no Docker ou Podman para desenvolvimento inicial e avaliação do Armazenamento de Objetos MinIO e sua camada de API compatível com S3.</p>



<p>Para instruções sobre implantação em ambientes de produção, consulte &#8220;<a href="https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-multi-node-multi-drive.html#deploy-minio-distributed">Implantação MinIO: Múltiplos Nós, Múltiplas Unidades</a>&#8220;.</p>



<p>O MinIO está configurado na URL: <a href="http://127.0.0.1:9001">http://127.0.0.1:9001</a> (ele será carregado automaticamente no browser quando o docker estiver up)</p>



<h2 class="wp-block-heading">Configurando a região</h2>



<p>Primeiro é necessário configurar a região do nosso servidor em settings > region. Aqui estarei utilizando a região sa-east-1 (south america) para fazer o processamento dos dados.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="480" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-7-1024x480.png" alt="" class="wp-image-2059" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-7-1024x480.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-7-300x140.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-7-768x360.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-7.png 1057w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Raw Policy e Access Keys</h2>



<p>Para poder fazer o ETL, o arquivo python (que pode estar rodando localmente na máquina) precisa se conectar com o banco do MinIO que pode estar localizado em qualquer servidor em qualquer lugar do mundo.</p>



<p>Para isso, é necessário gerar as access keys e para isso, é necessário criar a raw policy primeiro.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1040" height="492" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-8.png" alt="" class="wp-image-2060" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-8.png 1040w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-8-300x142.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-8-1024x484.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-8-768x363.png 768w" sizes="(max-width: 1040px) 100vw, 1040px" /></figure>



<p>Aqui gerei uma política de acesso completa de leitura e escrita, dessa forma posso gravar arquivos, sobrescrevê-los e fazer a leitura deles.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="475" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-9-1024x475.png" alt="" class="wp-image-2061" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-9-1024x475.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-9-300x139.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-9-768x357.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-9.png 1051w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Esse é o formato da raw policy gerada:</p>



<pre class="wp-block-code"><code>{
    "Version": "2012-10-17",
    "Statement": &#91;
        {
            "Effect": "Allow",
            "Action": &#91;
                "s3:*"
            ],
            "Resource": &#91;
                "arn:aws:s3:::*"
            ]
        }
    ]
}</code></pre>



<h3 class="wp-block-heading">Gerando as Access Keys</h3>



<p>Na área de access keys, gero uma chave para que eu possa conectar o ETL com este servidor Minio. </p>



<figure class="wp-block-image aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="477" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-10-1024x477.png" alt="" class="wp-image-2062" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-10-1024x477.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-10-300x140.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-10-768x358.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-10.png 1050w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="473" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-13-1024x473.png" alt="" class="wp-image-2065" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-13-1024x473.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-13-300x139.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-13-768x355.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-13.png 1052w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Assim como na AWS, ao gerar uma chave, você só pode visualizar a Secret key uma única vez, dessa forma é imperativo baixar o arquivo csv que possui a seguinte estrutura contendo as duas chaves:</p>



<pre class="wp-block-code"><code>{"url":"http://127.0.0.1:9000",<strong>"accessKey":"mnzf2Dw34eOEohXh","secretKey":"kXuPY6NVaHMySNct8INu1LB0lwNVLfYJ"</strong>,"api":"s3v4","path":"auto"}</code></pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="474" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-14-1024x474.png" alt="" class="wp-image-2066" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-14-1024x474.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-14-300x139.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-14-768x356.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-14.png 1047w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Por fim, é necessário ir até a access key que acabou de ser criada e aplicar a política de acesso nela, ou seja, estou atribuindo aquelas permissões à uma determinada chave, então quem tiver essa chave, terá permissões de leitura e escrita de arquivos no datalake.</p>



<h2 class="wp-block-heading">Extraindo os dados e conectando ao MinIO</h2>



<p>Beleza, agora que já tenho o ambiente e as chaves configuradas, basta criar um arquivo em python bem simples e conectá-lo ao nosso ambiente.</p>



<p>Para esse exemplo vou utilizar o pandaspara fazer a leitura dos arquivos e transformá-los em dataframes, e o boto3 que é uma biblioteca utilizada para fazer a conexão do cliente com o datalake. </p>



<p>Além disso, importo a classe <code>BytesIO</code> do módulo <code>io</code> em Python.</p>



<p><strong><code>io</code></strong> é um módulo em Python que fornece várias ferramentas para trabalhar com entrada/saída de dados (I/O). O nome &#8220;io&#8221; é uma abreviação de &#8220;input/output&#8221;.</p>



<p><code>BytesIO</code> é uma classe específica dentro do módulo <code>io</code>. Ela fornece uma interface para ler e escrever dados binários em memória, mas trata esses dados como se fossem provenientes de um fluxo de bytes, sem a necessidade de um arquivo físico.</p>



<p>A utilização típica do <code>BytesIO</code> é criar um objeto <code>BytesIO</code>, escrever dados binários nele e, em seguida, usá-lo onde seria esperado um objeto de arquivo (como, por exemplo, ao ler um arquivo binário).</p>



<pre class="wp-block-code"><code>!pip install pandas
!pip install boto3</code></pre>



<pre class="wp-block-code"><code>import pandas as pd
from io import BytesIO
import boto3
from io import StringIO </code></pre>



<p>Crio o cliente para conectar ao MinIO. Onde tenho [ACCESS KEY ID] e [SECRET ACCESS KEY] é preciso substituir pelas suas próprias chaves de acesso.</p>



<pre class="wp-block-code"><code>client = boto3.client('s3', 
    endpoint_url='http://seu-endpoint-aqui:9000',
    aws_access_key_id='&#91;ACCESS KEY ID]',
    aws_secret_access_key='&#91;SECRET ACCESS KEY]',
    aws_session_token=None,
    config=boto3.session.Config(signature_version='s3v4'),
    verify=False,
    region_name='sa-east-1'
)</code></pre>



<p>Aqui simplesmente carrego os dados com pandas. Estou utilizando uma base do kaggle &#8220;Most Subscribed 1000 Youtube Channels&#8221;</p>



<p><a href="https://www.kaggle.com/datasets/themrityunjaypathak/most-subscribed-1000-youtube-channels">https://www.kaggle.com/datasets/themrityunjaypathak/most-subscribed-1000-youtube-channels</a></p>



<pre class="wp-block-code"><code># Carregando os dados
file_path = 'topyoutube.csv'

df = pd.read_csv(file_path)

file_path</code></pre>



<p>Antes de fazer o upload do csv, preciso criá-lo e subir o csv na memória</p>



<pre class="wp-block-code"><code>csv_buffer = StringIO ()

df.to_csv(csv_buffer)</code></pre>



<h3 class="wp-block-heading">Escrita: carregando os objetos</h3>



<p>Depois que o csv estiver na memória através da função csv_buffer, posso uploadear ele para o datalake. Lembrando que é preciso substituir o &#8220;nome-do-bucket&#8221; pelo nome correto do seu bucket.</p>



<pre class="wp-block-code"><code>client.put_object (Body=csv_buffer.getvalue(), Bucket='nome-do-bucket', Key="diretorio/dataset.csv")</code></pre>



<p>Pronto! agora é possivel verificar o seu objeto no diretorio que foi criado dentro do bucket.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="471" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-16-1024x471.png" alt="" class="wp-image-2068" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-16-1024x471.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-16-300x138.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-16-768x353.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-16.png 1046w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading">Leitura: visualizando o objeto armazenado</h3>



<p>Agora vou fazer o processo inverso -> agora que o arquivo está no datalake, vou ler o arquivo. Para isso é necessário configurar um client de leitura.</p>



<pre class="wp-block-code"><code>obj = client.get_object(
    Bucket = 'nome-do-bucket',
    Key = "diretorio/dataset.csv"
).get("Body")

data = pd.read_csv(obj)
data.head()</code></pre>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="427" height="180" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-18.png" alt="" class="wp-image-2070" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-18.png 427w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-18-300x126.png 300w" sizes="(max-width: 427px) 100vw, 427px" /></figure>



<h2 class="wp-block-heading">Referências:</h2>



<ul class="wp-block-list">
<li><a href="https://min.io/" target="_blank" rel="noreferrer noopener">https://min.io/</a></li>



<li><a href="https://min.io/docs/minio/container/index.html" target="_blank" rel="noreferrer noopener">https://min.io/docs/minio/container/index.html</a></li>
</ul>
<p>O post <a href="https://datauniverse.com.br/processo-de-etl-simples-utilizando-datalake-minio/">Processo de ETL simples utilizando datalake MinIO</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/processo-de-etl-simples-utilizando-datalake-minio/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Automatizando Infraestrutura AWS EC2 via IaC com Terraform no Docker</title>
		<link>https://datauniverse.com.br/automatizando-infraestrutura-aws-ec2-via-iac-com-terraform-no-docker/</link>
					<comments>https://datauniverse.com.br/automatizando-infraestrutura-aws-ec2-via-iac-com-terraform-no-docker/#respond</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Fri, 05 Jan 2024 22:12:18 +0000</pubDate>
				<category><![CDATA[Data Engineering]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://dataisle.co/?p=2011</guid>

					<description><![CDATA[<p>Este artigo explora a implementação prática da integração entre DevOps e Infraestrutura como Código (IaC), com foco na automação da infraestrutura AWS EC2 utilizando a ferramenta Terraform. Destaco aqui a importância da IaC, tratando a infraestrutura como código de software demonstrando os benefícios dessa abordagem na agilidade, rastreabilidade e escalabilidade da infraestrutura em nuvem. IaC [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/automatizando-infraestrutura-aws-ec2-via-iac-com-terraform-no-docker/">Automatizando Infraestrutura AWS EC2 via IaC com Terraform no Docker</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow" open><summary>Detalhes do projeto</summary>
<ul class="wp-block-list">
<li><strong>Link do projeto no Github:</strong> <a href="https://github.com/cerqueiralex/iac-ec2-terraform-docker" target="_blank" rel="noreferrer noopener">https://github.com/cerqueiralex/iac-ec2-terraform-docker</a></li>



<li><strong>Tecnologias:</strong> Docker, Terraform, AWS EC2</li>



<li><strong>Categorias:</strong> Data Engineering, IaC</li>
</ul>
</details>



<p>Este artigo explora a implementação prática da integração entre DevOps e Infraestrutura como Código (IaC), com foco na automação da infraestrutura AWS EC2 utilizando a ferramenta Terraform. Destaco aqui a importância da IaC, tratando a infraestrutura como código de software demonstrando os benefícios dessa abordagem na agilidade, rastreabilidade e escalabilidade da infraestrutura em nuvem.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="994" height="625" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-6.png" alt="" class="wp-image-2072" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-6.png 994w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-6-300x189.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-6-768x483.png 768w" sizes="(max-width: 994px) 100vw, 994px" /></figure>



<p>IaC (Infraestrutura como código) é um método para gerenciar e provisionar infraestrutura de TI utilizando código de programação, em vez de fazê-lo manualmente através de interfaces web ou de linha de comando. Isso permite que a infraestrutura seja tratada como qualquer outra parte do código de aplicativo, o que facilita a automação, a reprodução e o controle de versão.</p>



<p>IaC é usado para automatizar o provisionamento de recursos de infraestrutura, como máquinas virtuais, containers, armazenamento, rede e outros, além de automatizar a configuração deles. IaC também pode ser usado para automatizar o escalonamento horizontal e vertical, assim como a implantação de aplicações.</p>



<p>IaC é especialmente útil em ambientes de nuvem, onde os recursos podem ser provisionados e escalados rapidamente e é amplamente utilizado em conjunto com DevOps e práticas de desenvolvimento ágil para tornar mais fácil e rápido para equipes de desenvolvimento implementar e gerenciar suas aplicações.</p>



<h2 class="wp-block-heading">1. Acessar o AWS IAM e criar as chaves de autenticação&nbsp;</h2>



<p>O AWS Identity and Access Management (IAM) é um serviço da Amazon Web Services (AWS) que oferece controle seguro de acesso aos recursos e serviços da AWS.</p>



<p>O IAM desempenha um papel fundamental na segurança da AWS, permitindo que os usuários concedam ou neguem acesso a recursos, implementem a autenticação de fatores múltiplos e integrem políticas de segurança personalizadas, mas principalmente, o AWS IAM serve para controlar e proteger o acesso aos serviços e recursos da AWS, contribuindo para a implementação de práticas robustas de segurança na nuvem.</p>



<p>Nesse sentido, para poder gerenciar os recursos AWS via IaC, <strong>é essencial possuirmos uma chave de acesso IAM para se conectar como administrador e gerenciar todos os recursos.</strong> Essas chaves de autenticação permitem que o Terraform e os scripts de automação acessem sua conta. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="448" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-1024x448.png" alt="" class="wp-image-2003" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-1024x448.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-300x131.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-768x336.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-1536x673.png 1536w, https://datauniverse.com.br/wp-content/uploads/2024/01/image.png 1859w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>É importante destacar que por questões de segurança, não é indicado gerar essas chaves de acesso no usuário root ou superadmin, pois ela será utilizada na configuração do IaC e qualquer um que tiver acesso terá controle total à infraestrutura, podendo fazer quaisquer alterações e gerar custos indevidos, assim como notifica a AWS na hora da criação das chaves.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="399" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-1-1024x399.png" alt="" class="wp-image-2004" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-1-1024x399.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-1-300x117.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-1-768x299.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-1.png 1202w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>A Chave é composta de 2 estruturas, é recomendado baixar o .csv pois a segunda estrutura só pode ser visualizada uma única vez.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="148" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-2-1024x148.png" alt="" class="wp-image-2005" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-2-1024x148.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-2-300x43.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-2-768x111.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-2.png 1198w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">2. Criando imagem e container Docker</h2>



<p>A estrutura de diretórios padrão para a criação do projeto deve conter o diretório raíz e dentro o dockerfile junto com o conector &#8220;main.tf&#8221; que será utilizado para passar os atributos da máquina EC2 para a AWS.</p>



<ul class="wp-block-list">
<li>diretório &#8220;terraformiac&#8221;
<ul class="wp-block-list">
<li>Dockerfile</li>



<li>main.tf</li>
</ul>
</li>
</ul>



<h3 class="wp-block-heading">2.1 Dockerfile</h3>



<p>Em seguida é necessário montar o Dockerfile que irá criar a imagem docker para rodar o Terraform e o AWS CLI</p>



<pre class="wp-block-code"><code># Usando a imagem oficial do Ubuntu como base (última versão)
FROM ubuntu:latest

# Atualizando os pacotes do sistema e instalar dependências necessárias
RUN apt-get update &amp;&amp; \
    apt-get install -y wget unzip curl

# Definir a versão do Terraform 
ENV TERRAFORM_VERSION=1.6.2

# Baixar e instalar Terraform
RUN wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip &amp;&amp; \
    unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip &amp;&amp; \
    mv terraform /usr/local/bin/ &amp;&amp; \
    rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip

# Criar a pasta /terraformiac dentro do container
RUN mkdir /terraformiac

# Copiar main.tf para a pasta /terraformiac no container
COPY main.tf /terraformiac/

# Criar a pasta Downloads e instalar o AWS CLI (para acessar a AWS)
RUN mkdir Downloads &amp;&amp; \
    cd Downloads &amp;&amp; \
    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" &amp;&amp; \
    unzip awscliv2.zip &amp;&amp; \
    ./aws/install

# Definir o comando padrão para execução quando o container for iniciado
CMD &#91;"/bin/bash"]
</code></pre>



<h3 class="wp-block-heading">2.2 Arquivo terraform &#8220;main.tf&#8221;</h3>



<p>Montando o arquivo terraform com os atributos da instância EC2. Estamos utilizando a imagem e instância t2.micro que está presente na camada gratuita da AWS. </p>



<p>É necessário também configurar a região de acordo com o projeto. Aqui está sendo utilizada a &#8220;us-east-2&#8221; que fica localizada em Ohio.</p>



<pre class="wp-block-code"><code>provider "aws" {
  region  = "us-east-2"  
}

#alterar imagem e instância de acordo com necessidade do projeto
resource "aws_instance" "tarefa1" {
  ami           = "ami-0a0d9cf81c479446a"  # AMI na AWS
  instance_type = "t2.micro"

#alterar tag de acordo com nome do projeto
  tags = {
    Name = "terraformiac"
  }
}
</code></pre>



<h3 class="wp-block-heading">2.3 Criando a imagem no Docker</h3>



<p>No terminal linux/mac, execute o comando abaixo para criar a imagem Docker</p>



<pre class="wp-block-code"><code>docker build -t terraform-image:terraformiac .</code></pre>



<p><strong>docker build</strong>: Este comando é utilizado para construir uma imagem Docker a partir de um Dockerfile.</p>



<p><strong>-t terraform-image:terraformiac</strong> : Esta parte etiqueta a imagem com um nome e uma tag opcional. Neste caso, a imagem será etiquetada como terraform-image com a tag <strong>terraformiac</strong> . Os dois pontos (:) separam o nome da imagem da tag.</p>



<p><code>. </code>: O ponto no final especifica o contexto de construção. O contexto de construção é o conjunto de arquivos em uma localização específica mencionada no Dockerfile. Neste caso, espera-se que o Dockerfile esteja no diretório atual (.).</p>



<p>Portanto, quando você executa este comando, o Docker procura por um Dockerfile no diretório atual e o utiliza para construir uma imagem chamada terraform-image com a tag <strong>terraformiac</strong> .</p>



<h3 class="wp-block-heading">2.4 Criando o container Docker</h3>



<p>Execute o comando abaixo para criar o container Docker </p>



<pre class="wp-block-code"><code>docker run -dit --name terraformiac terraform-image:terraformiac /bin/bash</code></pre>



<p><code>docker run -dit --name <strong>terraformiac</strong> terraform-image:<strong>terraformiac</strong> /bin/bash</code></p>



<p><code>docker run</code>: Este comando é utilizado para executar um contêiner a partir de uma imagem especificada.</p>



<p><code>-dit</code>:</p>



<ul class="wp-block-list">
<li><code>-d</code>: Modo destacado. Ele executa o contêiner em segundo plano, permitindo que você use o terminal para outros comandos.</li>



<li><code>-i</code>: Modo interativo. Mantém o STDIN aberto mesmo se não estiver conectado, permitindo interação com o contêiner.</li>



<li><code>-t</code>: Aloca um pseudo-TTY. Isso é frequentemente usado em conjunto com <code>-i</code> para simular um terminal real.</li>
</ul>



<p><code>--name <strong>terraformiac</strong> </code>: Atribui um nome ao contêiner em execução. Neste caso, o nome é definido como <strong>terraformiac</strong> .</p>



<p><code>terraform-image:<strong>terraformiac</strong> </code>: Especifica a imagem a ser usada para criar o contêiner. Refere-se à imagem terraform-image com a tag <strong>terraformiac</strong> .</p>



<p><code>/bin/bash</code>: Substitui o comando padrão especificado no Dockerfile e inicia um shell Bash interativo dentro do contêiner. Isso é útil para interagir com o contêiner quando estiver em execução.</p>



<p>Portanto, quando você executa este comando, o Docker criará um novo contêiner com base na imagem terraform-image com a tag <strong>terraformiac</strong> . O contêiner será executado em modo destacado e interativo, e você pode acessar seu shell usando /bin/bash. O contêiner é nomeado como <strong>terraformiac</strong> .</p>



<h3 class="wp-block-heading">2.5 Verficando as versões</h3>



<p>Para confirmar se tudo correu cde acordo, agora acessando o terminal docker, verifique as versões do Terraform e do AWS CLI com os comandos abaixo:</p>



<pre class="wp-block-code"><code>terraform version
aws --version</code></pre>



<h2 class="wp-block-heading">3. AWS&nbsp; CLI</h2>



<p>O <a href="https://docs.aws.amazon.com/cli/">AWS Command Line Interface (AWS CLI)</a> é uma ferramenta de linha de comando que permite aos usuários interagir e gerenciar recursos na Amazon Web Services (AWS) diretamente por meio do terminal.</p>



<p> Com suporte para uma ampla gama de operações, o AWS CLI simplifica tarefas como a criação de instâncias EC2, a configuração de buckets no Amazon S3 e a administração de serviços relacionados à nuvem. </p>



<p>Utilizando comandos intuitivos, os usuários podem automatizar processos, criar scripts e integrar operações da AWS em pipelines de desenvolvimento, proporcionando uma interface eficiente e flexível para a gestão de recursos na nuvem da AWS.</p>



<p>Por questões de segurança, é preferível configurar o AWS CLI manualmente, pois caso contrário você precisará colocar sua chave de segurança no arquivo Dockerfile, o que irá expor sua chave para qualquer um que tiver acesso à automação.</p>



<h3 class="wp-block-heading"><strong>3.1 Configurar o aws CLI via docker terminal</strong></h3>



<ol class="wp-block-list">
<li>Acessar o diretório do projeto com &#8220;cd&#8221;</li>



<li>usar o comando “aws configure” no terminal na pasta onde está o aws cli</li>



<li>digitar a primeira chave de acesso da instância</li>



<li>digitar a segunda chave de acesso</li>



<li>colocar o id da região ex: “us-east-2”</li>



<li>enter = padrão none</li>
</ol>



<h3 class="wp-block-heading">3.2 Testando conexão entre terraform e AWS</h3>



<p>Através do comando abaixo, ele deverá retornar por exemplo todos os buckets no terminal:</p>



<pre class="wp-block-code"><code>aws ec2 ls | awk ‘{print $NF}’</code></pre>



<p><strong><code>aws ec2 ls</code></strong>: Isso chama o AWS CLI para listar as instâncias EC2.</p>



<p><strong><code>|</code></strong>: O pipe <code>|</code> é usado para redirecionar a saída do comando anterior para o próximo comando.</p>



<p><strong><code>awk ‘{print $NF}’</code></strong>: É um comando <code>awk</code> usado para extrair e imprimir a última coluna (campo) de cada linha da saída anterior. O <code>$NF</code> representa o último campo de cada linha.</p>



<p>Então, o comando completo nos lista as instâncias EC2 e extrai o valor da última coluna para cada linha da saída.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="774" height="465" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-3.png" alt="" class="wp-image-2009" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-3.png 774w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-3-300x180.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-3-768x461.png 768w" sizes="(max-width: 774px) 100vw, 774px" /></figure>



<h2 class="wp-block-heading">4. Iniciar o Terraform</h2>



<p>Uma vez feita a conexão corretamente, basta iniciar o terraform através do comando</p>



<pre class="wp-block-code"><code>terraform init</code></pre>



<p class="has-small-font-size"><img loading="lazy" decoding="async" src="https://lh7-us.googleusercontent.com/YHBW9JLe1abllXykNzekME8COY8MEq1AtQYA-Hap81eNYbbhXkljV8Yr5uibQgT81A12SzIP9cuMdJ7hd0SWkG67QxVWZyx8_FP4MCVuqVqGkMLxfuqKEoIqTM_lgwIfatzN6B8oQb2AokrumBOboco" width="718" height="351"></p>



<p>Isso vai fazer com que ele crie todos os arquivos do terraform no diretório</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="490" height="115" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-4.png" alt="" class="wp-image-2010" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-4.png 490w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-4-300x70.png 300w" sizes="(max-width: 490px) 100vw, 490px" /></figure>



<p>por último, aplicar as configurações através do comando:</p>



<pre class="wp-block-code"><code>terraform apply</code></pre>



<p>Com esse comando você irá executar as configurações definidas no arquivo “main.tf”. Basicamente aqui ele irá mostrar todas as configurações de criação de uma nova instância de EC2</p>



<p><img loading="lazy" decoding="async" width="719" height="335" src="https://lh7-us.googleusercontent.com/RclTOGQEEavewhEdXNfg_UBjMvhUCCkcJp3ByJ_VO7DucknK59bgzDipMuprY6pxbCJGwqGoG7PBI46NwRUuFpHM6ZRUiU6XsyegOCWG7NnO-SGN6_9s7dlrr64FDWIkLK7bEUhA7ILHXS1audrannk"></p>



<p>Uma vez aplicadas as alterações, ele terá criado com sucesso as instâncias EC2 no painel AWS.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="433" src="https://datauniverse.com.br/wp-content/uploads/2024/01/image-5-1024x433.png" alt="" class="wp-image-2013" srcset="https://datauniverse.com.br/wp-content/uploads/2024/01/image-5-1024x433.png 1024w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-5-300x127.png 300w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-5-768x325.png 768w, https://datauniverse.com.br/wp-content/uploads/2024/01/image-5.png 1136w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Referências:</h2>



<ul class="wp-block-list">
<li>https://docs.aws.amazon.com/cli/</li>



<li>https://www.datascienceacademy.com.br/</li>



<li>https://docs.docker.com/</li>



<li>https://developer.hashicorp.com/terraform/docs</li>
</ul>
<p>O post <a href="https://datauniverse.com.br/automatizando-infraestrutura-aws-ec2-via-iac-com-terraform-no-docker/">Automatizando Infraestrutura AWS EC2 via IaC com Terraform no Docker</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/automatizando-infraestrutura-aws-ec2-via-iac-com-terraform-no-docker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Clusterização com K-means em Python utilizando Elbow Method</title>
		<link>https://datauniverse.com.br/clusterizacao-com-k-means-em-python-utilizando-elbow-method/</link>
					<comments>https://datauniverse.com.br/clusterizacao-com-k-means-em-python-utilizando-elbow-method/#respond</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Sun, 03 Sep 2023 18:35:34 +0000</pubDate>
				<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://alexandrepolselli.com.br/?p=1660</guid>

					<description><![CDATA[<p>Clustering, também conhecido como agrupamento, refere-se à aplicação de técnicas de machine learning destinadas a dividir um conjunto de dados em diversos clusters ou grupos distintos, tendo como critério principal a semelhança entre os dados. Em contraste com algoritmos de classificação e regressão, o clustering é uma técnica simples da aprendizagem não supervisionada, uma vez [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/clusterizacao-com-k-means-em-python-utilizando-elbow-method/">Clusterização com K-means em Python utilizando Elbow Method</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow" open><summary>Detalhes do projeto</summary>
<ul class="wp-block-list">
<li><strong>Link do projeto no Github:</strong> <a href="https://github.com/cerqueiralex/kmeans-elbow-method" target="_blank" rel="noreferrer noopener">https://github.com/cerqueiralex/kmeans-elbow-method</a></li>



<li><strong>Tecnologias:</strong> Python, Scikit Learn, Pandas, Numpy, Plotly, Matplotlib</li>



<li><strong>Categorias:</strong> Estatística</li>
</ul>
</details>



<p>Clustering, também conhecido como agrupamento, refere-se à aplicação de técnicas de machine learning destinadas a dividir um conjunto de dados em diversos clusters ou grupos distintos, tendo como critério principal a semelhança entre os dados. </p>



<p>Em contraste com algoritmos de classificação e regressão, o clustering é uma técnica simples da aprendizagem não supervisionada, uma vez que os algoritmos envolvidos precisam discernir as relações intrínsecas entre os dados, sem depender de rótulos prévios que indiquem a que categoria pertencem.</p>



<p>Por meio de clustering, é possível extrair informações valiosas e insights que muitas vezes não seriam perceptíveis por meio de abordagens de aprendizado supervisionado.</p>



<h2 class="wp-block-heading">K-means</h2>



<p>K-Means é um algoritmo de agrupamento iterativo que busca encontrar centróides ótimos para criar clusters em um conjunto de dados. Ele itera até que os centróides não mudem substancialmente, e nesse ponto, os clusters resultantes são considerados estáveis e representam grupos distintos com base nas semelhanças entre os dados.</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/kmeans.gif" alt="" class="wp-image-1664" style="width:750px;height:562px"/><figcaption class="wp-element-caption"><a href="http://shabal.in/visuals/kmeans/2.html" target="_blank" rel="noreferrer noopener">fonte: shabal</a></figcaption></figure>



<p>O algoritmo opera seguindo os seguintes passos:</p>



<p><strong>Inicialização:</strong> O algoritmo escolhe aleatoriamente K pontos a partir dos dados, onde K é o número de clusters predefinido como parâmetro. Esses pontos iniciais atuam como os centros dos clusters &#8220;provisórios&#8221; antes de qualquer ajuste.</p>



<p><strong>Atribuição de Clusters:</strong> Cada ponto de dado é avaliado para determinar a sua proximidade ao centróide mais próximo. Isso resulta na divisão dos dados em clusters, onde cada cluster é composto pelos pontos mais próximos ao centróide associado.</p>



<p><strong>Atualização dos Centróides:</strong> Os novos valores para os centróides são calculados como a média dos dados contidos em cada cluster. Isso significa que o centro de cada cluster é recalculado com base nos pontos que o compõem.</p>



<p><strong>Iteração: </strong>O processo de encontrar centróides e atualizar clusters é repetido. Os centróides são recalculados, os pontos são reatribuídos aos clusters com base na proximidade aos novos centróides e os centróides são novamente atualizados pela média dos pontos do cluster.</p>



<p><strong>Convergência:</strong> O algoritmo continua a iterar até que a posição dos centróides não mude mais. Isso indica que os centróides convergiram para suas posições finais e que os clusters estão estáveis.</p>



<p>Este processo é repetido até que os centróides se estabilizem, e os clusters alcancem uma configuração na qual não haja mais alterações significativas. </p>



<p>A abordagem que o algoritmo K-Means segue para resolver o problema é chamada Expectation-Maximization (Expectativa-Maximização). A etapa E é atribuir os pontos de dados ao cluster mais próximo. </p>



<p>A etapa M é calcular o centróide de cada cluster. Abaixo está uma quebra de como podemos resolver isso matematicamente:</p>



<p>A função é:</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-1.png" alt="" class="wp-image-1667"/><figcaption class="wp-element-caption"><a href="https://towardsdatascience.com/k-means-clustering-algorithm-applications-evaluation-methods-and-drawbacks-aa03e644b48a" target="_blank" rel="noreferrer noopener">fonte: Imad Dabbura</a></figcaption></figure>



<p>Onde wik=1 para o ponto de dados xi se ele pertencer ao cluster k; caso contrário, wik=0. Além disso, μk é o centróide do cluster de xi.</p>



<p>É um problema de minimização de duas partes. Primeiro, minimizamos J com relação a wik e tratamos μk como fixo. Em seguida, minimizamos J com relação a μk e tratamos wik como fixo. Tecnicamente falando, diferenciamos J com relação a wik primeiro e atualizamos as atribuições de cluster (etapa E). </p>



<p>Em seguida, diferenciamos J com relação a μk e recalculamos os centróides após as atribuições de cluster da etapa anterior (etapa M). Portanto, a etapa E é:</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-2.png" alt="" class="wp-image-1668"/><figcaption class="wp-element-caption"><a href="https://towardsdatascience.com/k-means-clustering-algorithm-applications-evaluation-methods-and-drawbacks-aa03e644b48a" target="_blank" rel="noreferrer noopener">fonte: Imad Dabbura</a></figcaption></figure>



<p>Em outras palavras, atribuimos o ponto de dados xi ao cluster mais próximo, julgado pela soma das distâncias quadradas do centróide do cluster.</p>



<p>E a etapa M é:</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-3.png" alt="" class="wp-image-1669" style="width:750px;height:116px"/><figcaption class="wp-element-caption"><a href="https://towardsdatascience.com/k-means-clustering-algorithm-applications-evaluation-methods-and-drawbacks-aa03e644b48a" target="_blank" rel="noreferrer noopener">fonte: Imad Dabbura</a></figcaption></figure>



<p>O que se traduz em recalcular o centróide de cada cluster para refletir as novas atribuições.</p>



<h2 class="wp-block-heading">Elbow method</h2>



<p>Simplesmente olhando para os dados em um scatterplot, em alguns casos é possível estimar a olho nu a quantidade de centróides ideal para ser aplicada no conjunto de dados como é possível observar na figura a seguir.</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-13.png" alt="" class="wp-image-1686" style="width:400px;height:450px"/><figcaption class="wp-element-caption"><a href="https://medium.com/turing-talks/clustering-conceitos-b%C3%A1sicos-principais-algoritmos-e-aplica%C3%A7%C3%A3o-ace572a062a9" target="_blank" rel="noreferrer noopener">fonte: turing talks</a></figcaption></figure>



<p>Aqui podemos estimar que o número ideal de centróides seria igual a 5, por causa dos grandes grupos, o que resultaria no seguinte agrupamento:</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-14.png" alt="" class="wp-image-1687"/><figcaption class="wp-element-caption"><a href="https://medium.com/turing-talks/clustering-conceitos-b%C3%A1sicos-principais-algoritmos-e-aplica%C3%A7%C3%A3o-ace572a062a9" target="_blank" rel="noreferrer noopener">fonte: turing talks</a></figcaption></figure>



<p>Porém como podemos saber o número ideal do ponto de vista matemático?</p>



<p>Um passo fundamental para qualquer algoritmo não supervisionado é determinar o número ideal de agrupamentos nos quais os dados podem ser divididos. </p>



<p>Como não temos um número pré-definido de agrupamentos no aprendizado não supervisionado, tendemos a utilizar algum método que nos ajude a decidir o melhor número de agrupamentos. No caso do agrupamento K-Means, usamos o Elbow-Method.</p>



<p>Ele leva esse nome justamente por se assemelhar a um &#8220;cotovelo&#8221; conforme é possível de se observar na figura abaixo.</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image.png" alt="" class="wp-image-1665"/></figure>



<h3 class="wp-block-heading">O que é o Elbow-Method no Agrupamento K-Means</h3>



<p>No algoritmo de agrupamento K-Means, inicializamos aleatoriamente k agrupamentos e ajustamos iterativamente esses k agrupamentos até que os k-centróides alcancem um estado de equilíbrio. No entanto, a coisa principal que fazemos antes de inicializar esses agrupamentos é determinar quantos agrupamentos devemos usar.</p>



<p>Neste método, para determinar o valor de k, iteramos continuamente de k=1 até k=n (onde n é o hiperparâmetro que escolhemos de acordo com nossos requisitos). Para cada valor de k, calculamos o valor da soma dos quadrados dentro do agrupamento (WCSS).</p>



<p>WCSS &#8211; É definido como a soma das distâncias quadradas entre os centróides e cada ponto.</p>



<p>Agora, para determinar o melhor número de agrupamentos (k), traçamos um gráfico de k versus o valor de WCSS correspondente.</p>



<p>Além disso, quando k=1, o WCSS tem o valor mais alto, mas, à medida que o valor de k aumenta, o valor do WCSS começa a diminuir. <strong>Escolhemos o valor de k observando no gráfico em que ponto ele começa a se assemelhar a uma linha reta.</strong></p>



<h2 class="wp-block-heading">Construindo uma visualização em Python</h2>



<p>Começamos importando as bibliotecas que iremos utilizar. A biblioteca do KMeans do Sklearn, pandas para tratar a base, numpy para os np arrays e matplotlib para a visualização final dos gráficos.</p>



<p><a href="https://github.com/cerqueiralex/kmeans-elbow-method" target="_blank" rel="noreferrer noopener">O link do github deste projeto está disponível aqui</a></p>



<pre class="wp-block-code"><code>from sklearn.cluster import KMeans
from sklearn import metrics
from scipy.spatial.distance import cdist
import numpy as np
import matplotlib.pyplot as plt</code></pre>



<p>O dataset utilizado é o <a href="https://www.kaggle.com/datasets/vjchoudhary7/customer-segmentation-tutorial-in-python?resource=download" target="_blank" rel="noreferrer noopener">mall_customers.csv</a> disponível no kaggle. Este conjunto de dados foi criado apenas para fins de aprendizado dos conceitos de segmentação de clientes, também conhecido como &#8220;análise de cesta de mercado&#8221;. </p>



<pre class="wp-block-code"><code>from google.colab import files
files.upload()
df = pd.read_csv ("Mall_Customers.csv")</code></pre>



<p>Usamos essa função para importar o dataset e defini-lo na variável &#8220;df&#8221;.</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/Sem-Titulo-2-1024x439.png" alt="" class="wp-image-1672"/></figure>



<p>Ao imprimir o dataset é possível verificar que ele possui 5 dimensões, mas só preciso utilizar 2 delas que são o salário anual (Annual Income) e o score de gastos (spending score). Então eu vou tratar o dataset aqui mesmo com o pandas.</p>



<pre class="wp-block-code"><code>df = df.drop(columns=&#91;'Gender','CustomerID','Age'])
print('Modified DataFrame:\n', df)</code></pre>



<p>Vamos montar agora o código que treina o modelo:</p>



<pre class="wp-block-code"><code>distortions = &#91;]
inertias = &#91;]
mapping1 = {}
mapping2 = {}
K = range(1, 10)

for k in K:
	# Construindo e treinando o modelo
	kmeanModel = KMeans(n_clusters=k).fit(X)
	kmeanModel.fit(X)

	distortions.append(sum(np.min(cdist(X, kmeanModel.cluster_centers_,
										'euclidean'), axis=1)) / X.shape&#91;0])
	inertias.append(kmeanModel.inertia_)

	mapping1&#91;k] = sum(np.min(cdist(X, kmeanModel.cluster_centers_,
								'euclidean'), axis=1)) / X.shape&#91;0]
	mapping2&#91;k] = kmeanModel.inertia_</code></pre>



<p>Aqui calculamos as métricas de distorção e inércia para diferentes valores de K (número de clusters) e armazenamos essas métricas em listas e dicionários.</p>



<p><code>distortions</code> e <code>inertias</code> são listas vazias que serão usadas para armazenar as métricas de distorção e inércia, respectivamente.</p>



<p><code>mapping1</code> e <code>mapping2</code> são dicionários vazios que serão usados para mapear os valores de K para suas métricas de distorção e inércia correspondentes.</p>



<p><code>K</code> é uma lista que contém valores de K de 1 a 9 (ou seja, de 1 a 9 clusters) que serão testados.</p>



<p>O loop <code>for k in K:</code> itera sobre os diferentes valores de K.</p>



<p>Dentro do loop, o modelo K-Means é construído e treinado com o número atual de clusters definido por <code>k</code>:</p>



<pre class="wp-block-code"><code>kmeanModel = KMeans(n_clusters=k).fit(X)
kmeanModel.fit(X)</code></pre>



<p>Isso cria uma instância do modelo K-Means com o número atual de clusters e o ajusta aos dados <code>X</code>.</p>



<p>A distorção é calculada para o valor de K atual com a fórmula:</p>



<pre class="wp-block-code"><code>sum(np.min(cdist(X, kmeanModel.cluster_centers_, 'euclidean'), axis=1)) / X.shape&#91;0]</code></pre>



<p>Essa fórmula calcula a média das distâncias euclidianas mínimas entre cada ponto de dados e os centros dos clusters mais próximos.</p>



<p>A inércia é calculada para o valor de K atual com <code>kmeanModel.inertia_</code>. A inércia é a soma das distâncias quadráticas entre os pontos de dados e os centros dos clusters.</p>



<p>As métricas de distorção e inércia calculadas são armazenadas nas listas <code>distortions</code> e <code>inertias</code>, respectivamente.</p>



<p>Os valores de K e suas métricas de distorção e inércia correspondentes são armazenados nos dicionários <code>mapping1</code> e <code>mapping2</code>, respectivamente, para análise posterior.</p>



<p>No final do loop, você terá listas contendo as métricas de distorção e inércia para diferentes valores de K, bem como dicionários que mapeiam os valores de K para essas métricas. Aqui queremos determinar o número ideal de clusters em uma análise de cluster K-Means.</p>



<p>Vamos tabular e visualizar os resultados agora utilizando os diferentes valores de distortion para o dicionário mapping1:</p>



<pre class="wp-block-code"><code>for key, val in mapping1.items():
	print(f'{key} : {val}')</code></pre>



<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-4.png" alt="" class="wp-image-1673" style="width:343px;height:183px"/></figure>



<p>Plotamos em um gráfico agora os dados acima:</p>



<pre class="wp-block-code"><code>plt.plot(K, distortions, 'bx-')
plt.xlabel('Values of K')
plt.ylabel('Distortion')
plt.title('The Elbow Method using Distortion')
plt.show()</code></pre>



<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-5.png" alt="" class="wp-image-1674" style="width:567px;height:455px"/></figure>



<p>Utilizando agora os diferentes valores de inércia para o dicionário mapping2:</p>



<pre class="wp-block-code"><code>for key, val in mapping2.items():
	print(f'{key} : {val}')</code></pre>



<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-6.png" alt="" class="wp-image-1675" style="width:313px;height:205px"/></figure>



<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/Sem-Titulo.png" alt="" class="wp-image-1670" style="width:569px;height:453px"/></figure>



<p>Para determinar o número ideal de clusters, devemos selecionar o valor de k no &#8220;cotovelo&#8221;, ou seja, o ponto após o qual a distorção/inércia começa a diminuir de maneira linear. Assim, para os dados fornecidos, concluímos que o número ideal de clusters para os dados é 5.</p>



<p>De forma resumida para o código a seguir,  iremos plotar imagens dos pontos de dados agrupados para diferentes valores de k. Para isso, aplicaremos o algoritmo K-Means no conjunto de dados, iterando em uma faixa de valores de k.</p>



<p>Na range, colocamos o número que conseguimos através do Elbow-Method que foi 5</p>



<pre class="wp-block-code"><code># Cria um range de valores para k
k_range = range(1, 6)

# Iniciamos uma lista vazia para armazenar os valores de inércia para cada K
inertia_values = &#91;]

# Treinamos e plotamos os dados para cada valor de k
for k in k_range:
	kmeans = KMeans(n_clusters=k, \
					init='k-means++', random_state=42)
	y_kmeans = kmeans.fit_predict(X)
	inertia_values.append(kmeans.inertia_)
 
#Gráfico Matplotlib
	plt.scatter(X&#91;:, 0], X&#91;:, 1], c=y_kmeans)
	plt.scatter(kmeans.cluster_centers_&#91;:, 0],\
				kmeans.cluster_centers_&#91;:, 1], \
				s=100, c='red')
	plt.title('K-means clustering (k={})'.format(k))
	plt.xlabel('Feature 1')
	plt.ylabel('Feature 2')
	plt.show()

# Plota os valores de inércia para cada k
plt.plot(k_range, inertia_values, 'bo-')
plt.title('Elbow Method')
plt.xlabel('Number of clusters (k)')
plt.ylabel('Inertia')
plt.show()</code></pre>



<h2 class="wp-block-heading">Resultado final:</h2>



<p>Aqui é possível visualizar o resultado final com a plotagem iterativa de todos os gráficos para cada valor de K e os respectivos centróides.</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-8.png" alt="" class="wp-image-1680"/></figure>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-9.png" alt="" class="wp-image-1681"/></figure>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-10.png" alt="" class="wp-image-1682"/></figure>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-11.png" alt="" class="wp-image-1683"/></figure>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/09/image-12.png" alt="" class="wp-image-1684"/></figure>



<h2 class="wp-block-heading">Conclusão</h2>



<p>Você é o proprietário de um shopping e deseja compreender os perfis dos seus clientes e quem pode ser facilmente convertido (Clientes-Alvo).</p>



<p>Utilizando o dataset de score de pontuação financeira, utilizamos o algoritmo do Elbow-Method para encontrar o número da referência ideal de centróides e aplicamos isso no algoritmo de aprendizado de máquina não supervisionado K-means para criar os clusters e identificar quais são os perfis de clientes de modo que isso possa ser transmitido à equipe de marketing e que a estratégia seja planejada de acordo.</p>



<h2 class="wp-block-heading">Referências</h2>



<ul class="wp-block-list">
<li>https://www.kaggle.com/datasets/vjchoudhary7/customer-segmentation-tutorial-in-python</li>



<li>http://shabal.in/visuals/kmeans/2.html</li>



<li>https://www.geeksforgeeks.org/elbow-method-for-optimal-value-of-k-in-kmeans/</li>



<li>https://en.wikipedia.org/wiki/Cluster_analysis</li>



<li>https://towardsdatascience.com/k-means-clustering-algorithm-applications-evaluation-methods-and-drawbacks-aa03e644b48a</li>



<li>https://medium.com/turing-talks/clustering-conceitos-b%C3%A1sicos-principais-algoritmos-e-aplica%C3%A7%C3%A3o-ace572a062a9</li>
</ul>
<p>O post <a href="https://datauniverse.com.br/clusterizacao-com-k-means-em-python-utilizando-elbow-method/">Clusterização com K-means em Python utilizando Elbow Method</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/clusterizacao-com-k-means-em-python-utilizando-elbow-method/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Análise de Sentimentos utilizada em processo seletivo (RH) utilizando ChatGPT em Python e Matplotlib</title>
		<link>https://datauniverse.com.br/analise-de-sentimentos-processo-seletivo-rh-utilizando-chatgpt-em-python-e-matplotlib/</link>
					<comments>https://datauniverse.com.br/analise-de-sentimentos-processo-seletivo-rh-utilizando-chatgpt-em-python-e-matplotlib/#respond</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Mon, 12 Jun 2023 04:26:08 +0000</pubDate>
				<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://alexandrepolselli.com.br/?p=1534</guid>

					<description><![CDATA[<p>Atualmente a maior parte dos processos seletivos das empresas (principalmente no setor de tecnologia) utiliza algum software para conduzir os processos e coletar feedbacks dos candidatos com a finalidade de entender quais foram as possíveis falhas e a partir disso como melhorar a abordagem ou alguma etapa específica da entrevista. Uma abordagem inovadora para aprimorar [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/analise-de-sentimentos-processo-seletivo-rh-utilizando-chatgpt-em-python-e-matplotlib/">Análise de Sentimentos utilizada em processo seletivo (RH) utilizando ChatGPT em Python e Matplotlib</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow" open><summary>Detalhes do projeto</summary>
<ul class="wp-block-list">
<li><strong>Link do projeto no Github:</strong> <a href="https://github.com/cerqueiralex/chatgpt-analise-de-sentimentos" target="_blank" rel="noreferrer noopener">https://github.com/cerqueiralex/chatgpt-analise-de-sentimentos</a></li>



<li><strong>Tecnologias:</strong> Python, OpenAI API, CSV, Matplotlib, Json</li>



<li><strong>Categorias:</strong> DataScience, Prompt Engineering</li>
</ul>
</details>



<p>Atualmente a maior parte dos processos seletivos das empresas (principalmente no setor de tecnologia) utiliza algum software para conduzir os processos e coletar feedbacks dos candidatos com a finalidade de entender quais foram as possíveis falhas e a partir disso como melhorar a abordagem ou alguma etapa específica da entrevista.</p>



<p>Uma abordagem inovadora para aprimorar esse processo é a análise de sentimentos. Por meio da análise automatizada de textos, como currículos, entrevistas e feedbacks, é possível obter insights valiosos sobre as opiniões e emoções dos candidatos, auxiliando as empresas a tomarem decisões mais informadas. </p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/06/image-17-1024x572.png" alt="" class="wp-image-1551"/><figcaption class="wp-element-caption">feedbacks de candidatos para processos seletivos</figcaption></figure>



<p>Neste artigo, apresento um projeto em Python para realizar a análise de sentimentos em um processo de recrutamento de RH para uma empresa de tecnologia que utiliza como motor o ChatGPT 3.5 e apresenta o resultado da análise em gráficos utilizando Matplotlib.</p>



<p>O resultado final pode ser um gráfico que mostra por exemplo as porcentagens de cada tipo de sentimento analisado no conjunto de dados.</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/06/image-12.png" alt="" class="wp-image-1542"/></figure>



<p>Claramente esse essa estrutura pode ser adaptada e utilizada em diversos contextos diferentes, mas aqui iremos escolher um foco que é o feedback para processos de recrutamento em setores de RH.</p>



<p>Neste projeto, a ideia de estrutura é que em algum momento do processo seletivo seja enviado um sistema para que os candidatos possam enviar o seu respectivo feedback (de preferência em modo anônimo) e então com esse feedback nós tratamos e subimos no python para gerar as análises.</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/06/image-9-1024x392.png" alt="" class="wp-image-1536" style="width:750px;height:287px"/></figure>



<h2 class="wp-block-heading">Open AI e ChatGPT</h2>



<p>Instalamos então nossas bibliotecas que serão utilizadas para o programa. Primeiramente o pacote da openai que irá importar o ChatGPT responsável pela análise de sentimentos.</p>



<pre class="wp-block-code"><code>!pip install openai
!pip install load_dotenv</code></pre>



<pre class="wp-block-code"><code>import openai

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # Ler o arquivo .env local.

openai.api_key  = ('SUA CHAVE DA API OPENAI AQUI')</code></pre>



<p>O código em questão é uma importação das bibliotecas <code>openai</code> e <code>dotenv</code> e faz uso da função <code>load_dotenv</code> para carregar variáveis de ambiente de um arquivo <code>.env</code> local.</p>



<p>A biblioteca <code>openai</code> é um pacote Python fornecido pela OpenAI, que permite interagir com os serviços e modelos oferecidos pela plataforma. A linha de código <code>openai.api_key = ('')</code> define a chave de API do OpenAI que será usada para autenticação e acesso aos recursos. É necessário substituir pela sua própria chave obviamente.</p>



<p>A biblioteca <code>dotenv</code> é utilizada para carregar variáveis de ambiente de um arquivo <code>.env</code>. O arquivo <code>.env</code> é um arquivo de configuração que contém informações sensíveis, como chaves de API, que não devem ser expostas diretamente no código pois a <strong>openai possui uma política automática de detecção de exposição de chaves api em diretórios públicos e se sua chave for exposta ela é cancelada automaticamente e você irá precisar gerar uma nova.</strong></p>



<p>A função <code>load_dotenv()</code> carrega as variáveis de ambiente do arquivo <code>.env</code> e as torna disponíveis para o programa. O uso do <code>_</code> antes de <code>load_dotenv()</code> é uma convenção comum para indicar que não estamos interessados no valor de retorno da função, apenas na sua execução.</p>



<p>Em resumo, o código importa as bibliotecas necessárias, carrega as variáveis de ambiente de um arquivo <code>.env</code> e define a chave de API do OpenAI para uso posterior nas interações com a plataforma.</p>



<pre class="wp-block-code"><code>def get_completion(prompt, model="gpt-3.5-turbo"):
    messages = &#91;{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=0, # Este é o grau de aleatoriedade da saída do modelo.
    )
    return response.choices&#91;0].message&#91;"content"]</code></pre>



<p>Aqui definimos uma função chamada <code>get_completion</code> em Python. Essa função recebe dois parâmetros: <code>prompt</code> e <code>model</code>. O valor padrão para o parâmetro <code>model</code> é &#8220;gpt-3.5-turbo&#8221;.</p>



<p>De forma resumida, a função <code>get_completion</code> recebe um prompt e um modelo como entrada, envia o prompt para o modelo usando a API de Chat Completion da OpenAI e retorna a resposta gerada pelo modelo.</p>



<p>Dentro da função, é criada uma lista chamada <code>messages</code> contendo um dicionário. O dicionário representa uma mensagem de usuário no formato esperado pela API de Chat Completion da OpenAI. O valor da chave &#8220;role&#8221; é definido como &#8220;user&#8221; e o valor da chave &#8220;content&#8221; é definido como o valor do parâmetro <code>prompt</code> recebido pela função.</p>



<p>Em seguida, é feita uma chamada à API de Chat Completion da OpenAI usando a função <code>openai.ChatCompletion.create()</code>. O modelo especificado é o valor do parâmetro <code>model</code>. A lista <code>messages</code> é passada como valor para o parâmetro <code>messages</code>, e o parâmetro <code>temperature</code> é definido como 0, que significa que a saída do modelo será mais determinística, com menos aleatoriedade.</p>



<p>A resposta da API é armazenada na variável <code>response</code>. Através dessa resposta, é possível acessar as escolhas feitas pelo modelo usando <code>response.choices</code>. No código, é retornado o conteúdo da primeira mensagem da primeira escolha, que é acessado através de <code>response.choices[0].message["content"]</code>.</p>



<h2 class="wp-block-heading">Carregando o arquivo com o feedback dos candidatos</h2>



<p>Como vamos trabalhar com o feedback dos candidatos, nesse caso aqui pensei num formato simples que carrega um csv e posteriormente trata esse csv para transformá-lo em um json para ser utilizado em ferramentas de data science.</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/06/image-15.png" alt="" class="wp-image-1547"/></figure>



<p>Esse é um exemplo de conjunto de dados fictício que deixa as emoções e sentimentos em relação ao processo bem evidentes.</p>



<pre class="wp-block-code"><code>import csv</code></pre>



<pre class="wp-block-code"><code>nome_arquivo = 'arquivo_com_os_feedbacks.csv'

# Abre o arquivo CSV e cria o objeto leitor
with open(nome_arquivo, 'r') as arquivo_csv:
    leitor = csv.reader(arquivo_csv)

    # Transforma os dados do leitor em uma lista
    reviews = list(leitor)</code></pre>



<p>Primeiro, é definida uma variável <code>nome_arquivo</code> que contém o nome do arquivo CSV a ser lido.</p>



<p>O código lê um arquivo CSV, percorre suas linhas e armazena os dados em uma lista chamada <code>reviews</code>.</p>



<p>Utilizamos a declaração <code>with open(nome_arquivo, 'r') as arquivo_csv</code> para abrir o arquivo CSV no modo de leitura (<code>'r'</code>). Essa forma de abrir o arquivo dentro do bloco <code>with</code> garante que o arquivo será fechado corretamente após o uso, mesmo em caso de exceção.</p>



<p>Dentro do bloco <code>with</code>, é criado um objeto leitor de CSV usando a função <code>csv.reader()</code>, passando o arquivo CSV aberto como argumento. Esse objeto leitor permite percorrer as linhas do arquivo CSV.</p>



<p>O próximo passo é converter os dados do objeto leitor em uma lista. Isso é feito utilizando a função <code>list()</code>, que recebe o objeto leitor como argumento. Ao converter o objeto leitor em uma lista, obtemos uma lista de listas, onde cada lista interna representa uma linha do arquivo CSV.</p>



<pre class="wp-block-code"><code>#JSON Formatting
prompt = f"""
Identify the following items from each item in the reviews list:
- The ID for each respective review, starting with 0
- Sentiment (very positive, positive, neutral, negative or very negative)
- Is the reviewer expressing anger? (true or false)
- A list of emotions that the writer of the review is expressing

The reviews list is delimited with triple backticks.
Format your response as a JSON object with "ID, "Sentiment", "Anger" and "Emotions" as the keys.
If the information isn't present, use "unknown" as the value.
Make your response as short as possible.
Format the Anger value as a boolean.
Dont write more than 5 emotions

Reviews list: '''{reviews}'''
"""
response = get_completion(prompt)
print(response)</code></pre>



<p>Agora colocamos o motor do ChatGPT para brilhar!</p>



<p>Como é possível ver na prompt, eu utilizei algumas requisições simples, mas é possível solicitar diversas outras análises e tratamentos para serem gerados com os feedbacks.</p>



<p>Nesse caso vou definir um ID para cada feedback para formatar um objeto json, o sentimento identificado pelo ChatGPT, se a review está expressando raiva (retorna de forma boolean) e uma lista de palavras chave que forem identificadas como emoção.</p>



<p>Esse é o resultado de um arquivo fictício que alimentei para testar o comportamento do modelo em todas as 6 variações de sentimentos que defini:</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/06/image-10-1024x637.png" alt="" class="wp-image-1539"/></figure>



<h2 class="wp-block-heading">Visualização dos resultados</h2>



<pre class="wp-block-code"><code>import matplotlib.pyplot as plt
import json as js</code></pre>



<p>Vamos utilizar o pacote Matplotlib para gerar os gráficos e o json para adequar os dados para o Matplotlib </p>



<pre class="wp-block-code"><code>data_json = js.loads(response)</code></pre>



<p>Realizamos a conversão de uma string JSON em um objeto Python utilizando a função <code>loads()</code> do módulo <code>json</code>.</p>



<p>O código converte uma string JSON em um objeto Python, permitindo que os dados do JSON sejam manipulados e acessados facilmente no programa Python.</p>



<pre class="wp-block-code"><code># Inicializar o dicionário para armazenar as contagens
xyz = {}

# Calcular a quantidade de cada tipo de valor dentro da chave 'Sentiment'
for item in data_json.values():
    sentiment = item&#91;'Sentiment']
    if sentiment in xyz:
        xyz&#91;sentiment] += 1
    else:
        xyz&#91;sentiment] = 1

print(xyz)</code></pre>



<p>Fazemos a contagem da quantidade de cada tipo de valor dentro da chave &#8216;Sentiment&#8217; em um dicionário <code>data_json</code> e armazena os resultados no dicionário <code>xyz</code>.</p>



<p>Depois percorremos os valores de um dicionário <code>data_json</code>, conta a quantidade de cada tipo de valor dentro da chave &#8216;Sentiment&#8217; e armazena os resultados em um novo dicionário <code>xyz</code>.</p>



<pre class="wp-block-code"><code># Preparar os dados para o gráfico de pizza
labels = list(xyz.keys())
values = list(xyz.values())

# Criar o gráfico de pizza
fig, ax = plt.subplots()
ax.pie(values, labels=labels, autopct='%1.1f%%', startangle=90)

# Ajustar aspectos visuais
ax.axis('equal')  # Torna o gráfico circular
plt.title('Distribuição dos Valores')
plt.legend()

# Exibir o gráfico
plt.show()
</code></pre>



<p>O resultado final aqui é uma visualização simples da porcentagem de cada tipo de sentimento. Podemos gerar outras análises também.</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/06/image-11.png" alt="" class="wp-image-1540"/></figure>



<p>Para uma análise mais granular dos resultados, utilizamos o json gerado lá atras que nos trás os outputs do nosso modelo de sentimentos do GPT e quais emoções ele captou de cada feedback. </p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/06/image-13.png" alt="" class="wp-image-1544"/></figure>



<h2 class="wp-block-heading">Repositório Github</h2>



<p>O código completo está disponível no seguinte repositório do Github: </p>



<p><a href="https://github.com/cerqueiralex/chatgpt-analise-de-sentimentos">https://github.com/cerqueiralex/chatgpt-analise-de-sentimentos</a></p>
<p>O post <a href="https://datauniverse.com.br/analise-de-sentimentos-processo-seletivo-rh-utilizando-chatgpt-em-python-e-matplotlib/">Análise de Sentimentos utilizada em processo seletivo (RH) utilizando ChatGPT em Python e Matplotlib</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/analise-de-sentimentos-processo-seletivo-rh-utilizando-chatgpt-em-python-e-matplotlib/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Criando um chatbot automatizado para retirada de pedidos com API do Chatgpt 3.5 turbo em Python</title>
		<link>https://datauniverse.com.br/criando-um-chatbot-automatizado-para-retirada-de-pedidos-com-api-do-chatgpt-3-5-turbo-em-python/</link>
					<comments>https://datauniverse.com.br/criando-um-chatbot-automatizado-para-retirada-de-pedidos-com-api-do-chatgpt-3-5-turbo-em-python/#comments</comments>
		
		<dc:creator><![CDATA[Alexandre Polselli]]></dc:creator>
		<pubDate>Wed, 17 May 2023 22:46:23 +0000</pubDate>
				<category><![CDATA[Inteligência Artificial]]></category>
		<category><![CDATA[Projetos]]></category>
		<guid isPermaLink="false">https://alexandrepolselli.com.br/?p=1457</guid>

					<description><![CDATA[<p>Uma das coisas empolgantes sobre um LLM (large language model) como o ChatGPT é que você pode usá-lo para construir um chatbot personalizado com uma interface conversacional e desenvolver uma conversa completa de ponta a ponta se aproveitando de todo o poder e aprendizado que o ChatGPT já possui em sua disposição. Os chatbots são [&#8230;]</p>
<p>O post <a href="https://datauniverse.com.br/criando-um-chatbot-automatizado-para-retirada-de-pedidos-com-api-do-chatgpt-3-5-turbo-em-python/">Criando um chatbot automatizado para retirada de pedidos com API do Chatgpt 3.5 turbo em Python</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow" open><summary>Detalhes do projeto</summary>
<ul class="wp-block-list">
<li><strong>Link do projeto no Github:</strong> <a href="https://github.com/cerqueiralex/chatgpt-chatbot/" target="_blank" rel="noreferrer noopener">https://github.com/cerqueiralex/chatgpt-chatbot/</a></li>



<li><strong>Tecnologias:</strong> Python, OpenAI API, ChatGPT, OS</li>



<li><strong>Categorias:</strong> Data Science, Prompt Engineering</li>
</ul>
</details>



<p>Uma das coisas empolgantes sobre um LLM (large language model) como o ChatGPT é que você pode usá-lo para construir um chatbot personalizado com uma interface conversacional e desenvolver uma conversa completa de ponta a ponta se aproveitando de todo o poder e aprendizado que o ChatGPT já possui em sua disposição.</p>



<p>Os chatbots são comumente usados para lidar com consultas de atendimento ao cliente, responder perguntas frequentes, realizar tarefas de agendamento ou fornecer informações detalhadas sobre um produto ou serviço. Eles são programados para responder de maneira a simular a conversação humana e são especialmente úteis para lidar com interações repetitivas, liberando tempo para que os humanos lidem com tarefas mais complexas.</p>



<p>Existem dois tipos principais de chatbots:</p>



<p><strong>Chatbots baseados em regras:</strong> Esses chatbots respondem a consultas específicas e seguem um conjunto pré-definido de regras. Eles são limitados em termos de capacidade de compreensão e não conseguem lidar com perguntas fora das regras pré-definidas.</p>



<p><strong>Chatbots baseados em Inteligência Artificial:</strong> Esses chatbots utilizam técnicas de Processamento de Linguagem Natural(PLN) e Aprendizado de Máquina (Machine Learning) para entender melhor a intenção do usuário e fornecer respostas mais naturais e contextualmente relevantes. </p>



<p>Modelos de linguagem como GPT-3 e GPT-4 da OpenAI são exemplos de tecnologia usada para construir chatbots baseados em Inteligência Artificial. O ChatGPT é um chatbot baseado em IA.Esses bots são capazes de aprender com as interações passadas, melhorando assim a qualidade das respostas ao longo do tempo. </p>



<p>Eles podem gerenciar uma variedade de perguntas e até mesmo participar de conversas mais complexas com os usuários.</p>



<p>A ideia desse projeto aqui é construir um modelo exemplo de chatbot personalizado, talvez para desempenhar o papel de um agente de atendimento ao cliente utilizando IA ou para fazer pedidos em um restaurante.</p>



<p>Claramente para ser colocado em prática, é necessário muito mais customização e configuração do modelo, mas aqui irei construir um conceito básico que pode ser escalado para algo maior ou completamente diferente dependendo do contexto de cada projeto ou empresa.</p>



<h2 class="wp-block-heading">Criando um processo de ponta a ponta</h2>



<p>Antes de partir para a ação e para a modelagem precisamos definir um processo bem claro de como irá funcionar o fluxo de recebimento das mensagens e dos inputs dos usuários. E para isso é importante entender o comportamento base do modelo e como ele recebe as mensagens e como você pode utilizar os outputs para comunicar aos sistemas internos e fazer um ETL desse fluxo.</p>



<p>Esse é um exemplo de fluxo utilizado em um projeto de um serviço de agendado de consultas médicas com o objetivo de reduzir o tempo de espera dos pacientes e facilitar o trabalho dos profissionais de saúde.</p>



<p>Por meio de um assistente virtual, os pacientes poderão marcar suas consultas de acordo com suas preferências de horário e especialistas médicos.</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/05/image-20-1024x429.png" alt="" class="wp-image-1469"/><figcaption class="wp-element-caption">Este fluxo foi criado por desenvolvedores da consultoria CI&amp;T (referência ao final deste artigo).créditos da imagem: <a href="https://www.linkedin.com/in/isaacsilva98/" target="_blank" rel="noreferrer noopener">https://www.linkedin.com/in/isaacsilva98/</a></figcaption></figure>



<p>Inicialmente temos a ação do usuário de começar a conversa e me seguida recebe a prompt do usuário; baseado nessa prompt ele irá fazer perguntas até avançar para a etapa de conclusão do agendamento do pedido, enquanto ele não alcançar essa etapa (false) ele retorna para as perguntas até conseguir as informações que precisa.</p>



<p>Uma vez adquiridas as respostas necessárias ele parte para a ação de agendamento do pedido e grava isso no banco de dados passando então as informações do agendamento para o paciente e encerrando o chat. </p>



<p>Esse processo inteiro não será abordado neste artigo, porém serve como base para que cada empresa estruture um fluxo completo de acordo com sua arquitetura e necessidades.</p>



<h2 class="wp-block-heading">Instalando as dependências</h2>



<p>Primeiro, configuraremos o pacote Python OpenAI. Modelos de chat como o ChatGPT são na verdade treinados para receber uma série de mensagens como entrada e retornar uma mensagem gerada pelo modelo como saída. </p>



<p>E, embora o formato de chat seja projetado para tornar as conversas de várias iterações como esta fácil, também é igualmente útil para tarefas de uma única volta sem qualquer conversa.</p>



<p>Dependendo do programa que estiver utilizando para rodar o python, pode ser necessário instalar os pacotes antes de importar. </p>



<pre class="wp-block-code"><code>!pip install openai
!pip install load_dotenv</code></pre>



<figure class="wp-block-image size-large is-style-default"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/05/image-12-1024x657.png" alt="" class="wp-image-1458"/><figcaption class="wp-element-caption">Instalação dos pacotes com sucesso</figcaption></figure>



<p>Em seguida iremos importar os pacotes da openai e dotenv e inserir a chave da API da open AI, caso ainda não possua uma pode ser criada em: <a href="https://platform.openai.com/account/api-keys" target="_blank" rel="noreferrer noopener">https://platform.openai.com/account/api-keys</a></p>



<p>Eu estou utilizando uma chave gratuita e utilizando o modelo do chatgpt 3.5 turbo que é o que está disponível atualmente de forma gratuita. Para modelos 4 ou posterior é necessário pagar por uma licença.</p>



<pre class="wp-block-code"><code>import openai
import os

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file

openai.api_key  = ('INSIRA AQUI SUA CHAVE API OPENAI')</code></pre>



<h2 class="wp-block-heading">Criando os objetos do modelo</h2>



<p>Em seguida iremos criar duas funções, a get_completion e get_completion_from_messages.</p>



<p>Se você observar, fornecemos um prompt, mas, na verdade, dentro da função, o que estamos fazendo é inserir esse prompt em algo que se parece com uma mensagem do usuário.</p>



<p>E isso ocorre porque o modelo ChatGPT é um modelo de chat, o que significa que ele é treinado para receber uma série de mensagens como entrada e retornar uma mensagem gerada pelo modelo como saída.</p>



<p>Portanto, a mensagem do usuário é meio que a entrada, e a mensagem do assistente é a saída.</p>



<pre class="wp-block-code"><code>def get_completion(prompt, model="gpt-3.5-turbo"):
    messages = &#91;{"role": "user", "content": prompt}]
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=0, # this is the degree of randomness of the model's output
    )
    return response.choices&#91;0].message&#91;"content"]

def get_completion_from_messages(messages, model="gpt-3.5-turbo", temperature=0):
    response = openai.ChatCompletion.create(
        model=model,
        messages=messages,
        temperature=temperature, # this is the degree of randomness of the model's output
    )
#     print(str(response.choices&#91;0].message))
    return response.choices&#91;0].message&#91;"content"]</code></pre>



<p>A função <code>get_completion</code> é definida com dois parâmetros: <strong><code>prompt</code> e <code>model</code>.</strong> O parâmetro <code><strong>prompt</strong></code> representa o texto de entrada ou prompt fornecido pelo usuário. O parâmetro <code>model</code> é opcional e representa o modelo a ser usado para gerar a conclusão. Por padrão, é definido como &#8220;gpt-3.5-turbo&#8221;.</p>



<p>Dentro da função, uma lista <code><strong>messages</strong></code> é criada. Essa lista conterá as mensagens da conversa para a conclusão baseada em chat. Neste caso, a conversa consiste em uma única mensagem do usuário. A mensagem é representada como um dicionário com duas chaves: &#8220;role&#8221; e &#8220;content&#8221;. &#8220;role&#8221; especifica o papel da mensagem (neste caso, &#8220;user&#8221;), e &#8220;content&#8221; contém o texto real da mensagem, que é o <code>prompt</code> fornecido.</p>



<p>O método <code>openai.ChatCompletion.create()</code> é chamado para gerar a conclusão. Ele recebe vários argumentos:</p>



<p><code>model</code>: Especifica o modelo a ser usado para gerar a conclusão. É definido com o valor do parâmetro <code>model</code> passado para a função.</p>



<p><code>messages</code>: Especifica as mensagens da conversa para a conclusão. É definido como a lista <code>messages</code> criada no passo anterior.</p>



<p><code>temperature</code>: Especifica o grau de aleatoriedade na saída do modelo. Um valor de 0 faz com que a saída seja mais determinística, ou seja, mais previsível.</p>



<p>A resposta da API de conclusão de chat é armazenada na variável <code>response</code>.</p>



<p>Por fim, a função retorna o conteúdo da conclusão gerada pelo modelo. Ela acessa o conteúdo da primeira escolha da resposta usando <code>response.choices[0].message["content"]</code>. Cada escolha representa uma possível conclusão diferente, e neste caso, estamos pegando o conteúdo da primeira escolha como saída.</p>



<p>A segunda função, <code>get_completion_from_messages</code>, é semelhante à primeira, mas recebe a lista <code>messages</code> diretamente como parâmetro, em vez do <code>prompt</code>. Além disso, possui um parâmetro adicional <code>temperature</code>, que permite controlar o grau de aleatoriedade na saída do modelo. O restante do código é muito semelhante ao da primeira função, onde a resposta da API é armazenada na variável <code>response</code>, e o conteúdo da primeira escolha é retornado como saída.</p>



<p>Essas funções são usadas para interagir com um modelo de geração de texto baseado em chat da OpenAI, onde uma lista de mensagens é passada para o modelo, e ele retorna uma resposta gerada com base nessas mensagens.</p>



<p>Repare que utilizamos um parâmetro da variável response que é o <strong>temperature=0</strong>; A temperatura é um parâmetro que controla a &#8220;criatividade&#8221; ou aleatoriedade do texto gerado pelo GPT-3. Uma temperatura mais alta (por exemplo, 0,7) resulta em uma saída mais diversificada e criativa, enquanto uma temperatura mais baixa (por exemplo, 0,2) torna a saída mais determinística e focada.</p>



<p>Na prática, a temperatura afeta a distribuição de probabilidade sobre os possíveis tokens em cada etapa do processo de geração. Uma temperatura de 0 tornaria o modelo completamente determinístico, sempre escolhendo o token mais provável.</p>



<h2 class="wp-block-heading">Interface e automação do Orderbot</h2>



<p>Podemos automatizar a coleta de prompts do usuário e respostas do assistente para construir um OrderBot. O OrderBot irá receber pedidos em uma pizzaria.</p>



<p>Este chatbot será chamado de OrderBot, e iremos automatizar a coleta de prompts do usuário e respostas do assistente.</p>



<pre class="wp-block-code"><code>def collect_messages(_):
    prompt = inp.value_input
    inp.value = ''
    context.append({'role':'user', 'content':f"{prompt}"})
    response = get_completion_from_messages(context) 
    context.append({'role':'assistant', 'content':f"{response}"})
    panels.append(
        pn.Row('User:', pn.pane.Markdown(prompt, width=600)))
    panels.append(
        pn.Row('Assistant:', pn.pane.Markdown(response, width=600, style={'background-color': '#F6F6F6'})))
 
    return pn.Column(*panels)
</code></pre>



<p>Aqui iremos criar uma UI para simular a aplicação do painel do chatbot para o usuário, o que na prática seria construído e personalizado para cada empresa.</p>



<p>criamos dentro da variável context a prompt do sistema que funciona como o famoso &#8220;act as&#8221;  do chatgpt informando que ele dever´se comportar como um serviço automatizado e coleta de pedidos de uma pizzaria e seu nome é &#8220;Orderbot&#8221;</p>



<p>Passamos também para o modelo todas as informações e preços do menu da nossa pizzaria (aqui é importante a formatação dos preços corretamente com pontos no lugar de vírgulas)</p>



<pre class="wp-block-code"><code>import panel as pn  # GUI
pn.extension()

panels = &#91;] # collect display 

context = &#91; {'role':'system', 'content':"""
Você é o OrderBot, um serviço automatizado para coletar pedidos em uma pizzaria.\ 
Primeiro, você saúda o cliente e em seguida coleta o pedido.\
Depois, você pergunta se é para retirada ou entrega.\
Você aguarda para coletar o pedido completo,\ 
Você faz um resumo e verifica se o cliente deseja adicionar mais alguma coisa.\ 
Se for para entrega, você pede o endereço.\ 
Por fim, você coleta o pagamento.

Certifique-se de esclarecer todas as opções, extras e tamanhos para identificar exclusivamente o item do menu.\ 
Você responde de uma forma curta e amigável, como em uma conversa.\

O menu inclui:\

Pizza de pepperoni: R$ 12.95, R$ 10.00, R$ 7.00\
Pizza de queijo: R$ 10.95, R$ 9.25, R$ 6.50\
Pizza de berinjela: R$ 11.95, R$ 9.75, R$ 6.75\
Batatas fritas: R$ 4.50, R$ 3.50\
Salada grega: R$ 7.25\
Coberturas:\

Queijo extra: R$ 2.00\
Cogumelos: R$ 1.50\
Linguiça: R$ 3.00\
Bacon canadense: R$ 3.50\
Molho AI: R$ 1.50\
Pimentões: R$ 1.00\
Bebidas:\

Coca-Cola: R$ 3.00, R$ 2.00, R$ 1.00\
Sprite: R$ 3.00, R$ 2.00, R$ 1.00\
Água em garrafa: R$ 5.00\
"""} ]  # accumulate messages


inp = pn.widgets.TextInput(value="Hi", placeholder='Enter text here…')
button_conversation = pn.widgets.Button(name="Chat!")

interactive_conversation = pn.bind(collect_messages, button_conversation)

dashboard = pn.Column(
    inp,
    pn.Row(button_conversation),
    pn.panel(interactive_conversation, loading_indicator=True, height=300),
)

dashboard</code></pre>



<h2 class="wp-block-heading">Testando o modelo</h2>



<p>O resultado final é um chatbot simples, porém poderoso! ele é capaz de entender contextos complexos e diferentes inputs de usuário e seguir com o pedido até o final.</p>



<p>Ele começa gerando uma interface vazia e com uma frase de introdução inicial que inicia a conversa com o cliente. Você então escreve qualquer coisa e ele irá te guiar automaticamente até o final do pedido.</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/05/image-16.png" alt="" class="wp-image-1463"/></figure>



<p>Essa é uma simulação que eu fiz com ele pedido uma pizza de pepperoni do tamanho grande com molho extra e acabei não pedindo nenhuma bebida.</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/05/image-13.png" alt="" class="wp-image-1460"/></figure>



<p>Ao concluir o pedido, o modelo traz um resumo com todas as informações do pedido, o endereço e o valor total incluindo ou não a taxa de entrega.</p>



<p>É interessante testar como que o modelo se comporta com diferentes tipos de inputs de usuário, por exemplo, quando ele me pergunta o tipo do pagamento eu devolvo com uma pergunta, se pode ser em dinheiro.</p>



<figure class="wp-block-image aligncenter size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/05/image-14.png" alt="" class="wp-image-1461"/></figure>



<h2 class="wp-block-heading">Contextos não relacionados</h2>



<p>O mais interessante é que ao programar o chatgpt para seguir essa função, ele é extremamente eficiente em se manter alinhado ao seu objetivo e mesmo fazendo diversas perguntas complexas, diferentes e que não possuem contexto com o objetivo para o qual programamos, ele sempre tenta puxar o usuário de volta para o tópico central.</p>



<p>Isso é super importante pois torna o modelo de fato estável para ser utilizado em aplicações empresariais diversas e não causar problemas.</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/05/image-19.png" alt="" class="wp-image-1468"/></figure>



<h2 class="wp-block-heading">Comunicação com os sistemas e APIs internas</h2>



<p>E para comunicar os resultados do pedido nós criamos através do seguinte código um resumo em .json que pode ser computado e enviado para o sistema de pedidos.</p>



<p>Nesse caso estamos usando uma temperatura mais baixa =&#8221;0&#8243; para tornar o sistemas mais &#8220;previsível&#8221; tratando-se de uma comunicação direta com o usuário para evitar erros de entendimento ou comunicação que poder complicar o processo com os clientes.</p>



<pre class="wp-block-code"><code>messages =  context.copy()
messages.append(
{'role':'system', 'content':'create a json summary of the previous food order. Itemize the price for each item\
 The fields should be 1) pizza, include size 2) list of toppings 3) list of drinks, include size   4) list of sides include size  5)total price '},    
)
 #The fields should be 1) pizza, price 2) list of toppings 3) list of drinks, include size include price  4) list of sides include size include price, 5)total price '},    

response = get_completion_from_messages(messages, temperature=0)
print(response)</code></pre>



<p>O resultado final é um .json estruturado e criado pelo próprio poder do chatgpt:</p>



<figure class="wp-block-image size-full"><img decoding="async" src="https://alexandrepolselli.com.br/wp-content/uploads/2023/05/image-15.png" alt="" class="wp-image-1462"/></figure>



<p>Um dos maiores poderes do chatgpt é a capacidade de interpretar, escrever e gerar códigos em diversas linguagens de programação. Nesse caso o output pode ser gerado em diversos formatos como csv, json, xml etc.. dependendo de cada contexto.</p>



<h2 class="wp-block-heading">Deixando o modelo mais robusto</h2>



<p>Uma dica é que para criar um sistema mais robusto podemos utilizar a biblioteca <a href="https://python.langchain.com/en/latest/index.html" target="_blank" rel="noreferrer noopener">langchain</a> que permite manipular banco de dados e fazer com que o chatgpt aprenda com seus dados e não extrapole as respostas para temas, contextos ou produtos externos de outras empresas que poderiam gerar ruído na sua conversação.</p>



<p>LangChain é um framework para desenvolvimento de aplicativos alimentados por modelos de linguagem. Acreditamos que os aplicativos mais poderosos e diferenciados não apenas utilizarão um modelo de linguagem, mas também serão: </p>



<ul class="wp-block-list">
<li>Conscientes dos dados: conectar um modelo de linguagem a outras fontes de dados</li>



<li>Agentes: permitir que um modelo de linguagem interaja com seu ambiente</li>
</ul>



<p>O framework LangChain é projetado com base nesses princípios. </p>



<h2 class="wp-block-heading">Referências e recomendações de leitura:</h2>



<ul class="wp-block-list">
<li><a href="https://writings.stephenwolfram.com/2023/02/what-is-chatgpt-doing-and-why-does-it-work/" target="_blank" rel="noreferrer noopener">https://writings.stephenwolfram.com/2023/02/what-is-chatgpt-doing-and-why-does-it-work/</a></li>



<li><a href="https://community.openai.com/t/cheat-sheet-mastering-temperature-and-top-p-in-chatgpt-api-a-few-tips-and-tricks-on-controlling-the-creativity-deterministic-output-of-prompt-responses/172683" target="_blank" rel="noreferrer noopener">https://community.openai.com/t/cheat-sheet-mastering-temperature-and-top-p-in-chatgpt-api-a-few-tips-and-tricks-on-controlling-the-creativity-deterministic-output-of-prompt-responses/172683</a></li>



<li><a href="https://www.deeplearning.ai" target="_blank" rel="noreferrer noopener">https://www.deeplearning.ai</a></li>



<li>Projeto de serviço de consultas médicas: <a href="https://www.linkedin.com/in/isaacsilva98/" target="_blank" rel="noreferrer noopener">https://www.linkedin.com/in/isaacsilva98/</a></li>



<li><a href="https://python.langchain.com/en/latest/index.html" target="_blank" rel="noreferrer noopener">https://python.langchain.com/en/latest/index.html</a></li>



<li><a href="https://www.datascienceacademy.com.br/" target="_blank" rel="noreferrer noopener">https://www.datascienceacademy.com.br/</a></li>
</ul>
<p>O post <a href="https://datauniverse.com.br/criando-um-chatbot-automatizado-para-retirada-de-pedidos-com-api-do-chatgpt-3-5-turbo-em-python/">Criando um chatbot automatizado para retirada de pedidos com API do Chatgpt 3.5 turbo em Python</a> apareceu primeiro em <a href="https://datauniverse.com.br">Data Universe</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://datauniverse.com.br/criando-um-chatbot-automatizado-para-retirada-de-pedidos-com-api-do-chatgpt-3-5-turbo-em-python/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
