개발사항은 다음에서 확인 가능. 데이터분석,과학을 위해 내가 좋아하는 분야로 공부해보면 어떨까해서...시작!
https://github.com/yeongjinHwang/riotAPI_dataAnalysis
GitHub - yeongjinHwang/riotAPI_dataAnalysis: 롤api를 활용하여 데이터분석해볼까?
롤api를 활용하여 데이터분석해볼까? Contribute to yeongjinHwang/riotAPI_dataAnalysis development by creating an account on GitHub.
github.com
1. developer api key 발급
: 기본적으로 1초마다 요청 20개, 2분마다 요청 100개
: 요금제에 따라 추가 요청 가능할 것으로 보임
: riot ad login 후 발급 가능
: https://developer.riotgames.com/
2. api doc 확인하기
: https://developer.riotgames.com/apis
Riot Developer Portal
developer.riotgames.com
3. 우선 최상위 플레이어들의 정보를 가져오기
import config
import requests
api_key = config.api_key
header = {"X-Riot-Token" : api_key}
# 마스터 이상의 소환사 목록을 가져오는 함수
def league_v4_tier_info(tier):
queue = "RANKED_SOLO_5x5"
url = f"https://kr.api.riotgames.com/lol/league/v4/{tier}leagues/by-queue/{queue}"
requests.get(url, headers=header)
response = requests.get(url, headers=header)
if response.status_code == 200:
return response.json()
else:
print(f"Error fetching data: {response.status_code}")
return None
: config.py에서 api_key라는 변수로 api key를 저장해둠(깃허브에 계속 업로드할 것인데 config.py는 제외하고...api key는 공개장소에 업로드하면 안되고 따로 분리하려고 이렇게 했습니다.)
: master, grandmaster, challenger player의 info를 가져오는 함수를 생성(솔로랭크 기준, tier를 변수로 url에 넣으면
마스터, 그랜드마스터,챌린저는 해당 url이 따로있기에 함수로 만들어뒀음.
: 해당으로 json을 불러오면
summonerId: 소환사의 고유 ID.
rank: 소환사의 현재 랭크 (예: Master, Grandmaster, Challenger).
leaguePoints: 소환사의 리그 포인트 (LP).
wins: 해당 시즌의 승리 수.
losses: 해당 시즌의 패배 수.
veteran: 해당 소환사가 오랫동안 상위 티어에 머물렀는지 여부 (True/False).
inactive: 소환사가 비활성 상태인지 여부 (True/False).
freshBlood: 소환사가 해당 티어에 처음 진입했는지 여부 (True/False).
해당 정보를 불러올 수 있는데 여기서 가져오고자 하는 summonerId, rank, leaguePoints, wins, losses만 들고오도록 하자.
(참고로 마스터, 그랜드마스터, 챌린저는 1티어뿐만 있으며 티어명만 다르기에 구분 불가능하여 추가로 작성해줌 나는 1,2,3,4티어만 가져오고 싶은게 아니라 마스터,그랜드마스터,챌린저라는 이름도 중요하게 보려고...)
master_plus = ["challenger", "grandmaster", "master"]
master_plus_play = {}
player_json = []
for tier in master_plus:
tier_data = league_v4_tier_info(tier)
if tier_data:
for entry in tier_data['entries']:
entry['tier'] = tier.capitalize() # 티어 정보를 추가
player_json.extend(tier_data['entries'])
sorted_entries = sorted(player_json, key=lambda x: x['leaguePoints'], reverse=True)
for index, entry in enumerate(sorted_entries, start=1):
master_plus_play[index] = {
"Name": entry["summonerId"],
"Rank": entry["tier"] + entry["rank"],
"LP": entry["leaguePoints"],
"wins": entry["wins"],
"losses": entry["losses"]
}
print(master_plus_play)
: 다음으로 추가하였다. 여기서 티어정보를 넣는것이 핵심이다.
(왜냐하면 master->grandmaster와 같은 티어 변동은 00시기준으로 되기에, LP가 낮아도 현재 00시 이전에는 티어변동 전으로 되기에 sorted하면 문제가 생긴다. 이를 한 번에 해결하기 위해 티어정보도 추가로 작성해주고 나중에 00시 업데이트 기준으로 어떤 유저가 티어가 상승될 것이고 어떤 유저가 하락될 것인지 판별할 수 있다.)
: 여기서 문제는 summonerId로 가져올 경우 소환사 id로 표시된다. 우리가 알아볼 수 있는 닉네임으로 변경하는 코드 추가
--> 해당은 league v4 최신으로 변동됨에 따라 해당 endpoint 대신 다른 endpoint(summoner)를 통해 가져올 수 있다.
--> 그러나 riot id하나당 하나의 닉네임을 가져오기에 시간적인 문제와 api request 제한이 있으므로 pass
print(master_plus_play[12])
다음을 통해 가져와보면
{'Name': '비공개', 'Rank': 'Challenger', 'LP': 1479, 'wins': 122, 'losses': 69}|
1번 index부터 사용했기에 12등의 결과가 매우 잘나오는 것을 확인
4. 00시 이후 티어변동 user check
: 앞서 말했듯이 현재 점수기반으로 sort를 했지만 00시에 티어가 변동된다.
: 따라서 00시 이후 어떤 user가 티어가 변동되는지 확인해주는 것을 추가하며 현재 lp(점수)기반으로 몇 점부터 티어의 커트라인인지 확인한다.
: ++ 챌린저는 300등까지, 그랜드마스터는 1000등까지이다.
: 시각적으로 이해하기 쉽도록 챌린저 하위50명, 그랜드마스터 상위 50명_하위50명, 마스터 상위 50명의 그래프
def cross_player_view():
"""
마스터 이상의 소환사 상하위 50명씩 figure
Args :
None
Returns :
None
"""
# 챌린저 하위 50명, 그랜드마스터 상위 50명, 그랜드마스터 하위 50명, 마스터 상위 50명 필터링
challenger_bottom_50 = [entry["LP"] for entry in master_plus_play.values() if entry["Rank"] == "Challenger"][-50:]
grandmaster_top_50 = [entry["LP"] for entry in master_plus_play.values() if entry["Rank"] == "Grandmaster"][:50]
grandmaster_bottom_50 = [entry["LP"] for entry in master_plus_play.values() if entry["Rank"] == "Grandmaster"][-50:]
master_top_50 = [entry["LP"] for entry in master_plus_play.values() if entry["Rank"] == "Master"][:50]
# 그래프 생성
plt.figure(figsize=(14, 8))
plt.plot(challenger_bottom_50, label="Challenger (Bottom 50)", color="red", marker="o")
plt.plot(grandmaster_top_50, label="Grandmaster (Top 50)", color="blue", marker="x")
plt.plot(grandmaster_bottom_50, label="Grandmaster (Bottom 50)", color="purple", marker="x")
plt.plot(master_top_50, label="Master (Top 50)", color="green", marker="s")
plt.xlabel("Rank")
plt.ylabel("LP")
plt.title("LP Distribution of Selected Challenger, Grandmaster, and Master Players")
plt.legend()
plt.grid(True)
plt.show()
: 다음과 같이 그랜드마스터 상위 player가 챌린저 하위 player보다 점수가 높을경우 00시에 update된다(300등까지 챌린저)
: 마스터와 그랜드마스터 티어변동도 동일한 원리이다.
def update_tiers(master_plus_play):
"""
LP 기준으로 등급 변동을 반영
Args :
master_plus_play : 마스터이상 player info
Returns :
updated_master_plus_play : 등급이 변동된 player info
"""
updated_master_plus_play = {}
for index, (key, entry) in enumerate(master_plus_play.items(), start=1):
previous_rank = entry["Rank"]
if index <= 300: new_rank = "Challenger"
elif index <= 1000: new_rank = "Grandmaster"
else: new_rank = "Master"
# 등급 변동 체크
if new_rank != previous_rank:
if previous_rank == "Challenger" and new_rank == "Grandmaster": new_rank += " down"
elif previous_rank == "Grandmaster" and new_rank == "Challenger": new_rank += " up"
elif previous_rank == "Grandmaster" and new_rank == "Master": new_rank += " down"
elif previous_rank == "Master" and new_rank == "Grandmaster": new_rank += " up"
updated_master_plus_play[key] = {
"Name": entry["Name"],
"Rank": new_rank,
"LP": entry["LP"],
"wins": entry["wins"],
"losses": entry["losses"]
}
return updated_master_plus_play
updated_master_plus_play = update_tiers(master_plus_play)
for index, (key, entry) in enumerate(updated_master_plus_play.items(), start=1):
if "down" in entry["Rank"] or "up" in entry["Rank"] : print(updated_master_plus_play[index])
{'Name': '비공개', 'Rank': 'Challenger up', 'LP': 1003, 'wins': 111, 'losses': 75}
{'Name': '비공개', 'Rank': 'Challenger up', 'LP': 1002, 'wins': 237, 'losses': 198}
{'Name': '비공개', 'Rank': 'Challenger up', 'LP': 988, 'wins': 97, 'losses': 60}
{'Name': '비공개', 'Rank': 'Challenger up', 'LP': 987, 'wins': 131, 'losses': 96}
{'Name': '비공개', 'Rank': 'Challenger up', 'LP': 969, 'wins': 119, 'losses': 82}
: 다음과 같이 00시 이후 티어가 변동되는 사항을 저장한다. 만약 떨어지면 down, 상승하면 up을 추가한다.
: down or up을 통해 티어변동 유저를 식별할 수 있다. (너무 많아서 5개만 우선 보이게 지웠습니다.)
이것을 어차피 풀스택으로 하려면 api로 생성해야되기에 fastapi 채택후 구조 변경
📦riotAPI_dataAnalysis
┣ 📂config
┃ ┣ 📜settings.py
┃ ┗ 📜__init__.py
┣ 📂routers
┃ ┣ 📜best_user_info.py
┃ ┣ 📜root.py
┃ ┗ 📜__init__.py
┣ 📜info.txt
┣ 📜main.py
┣ 📜README.md
┣ 📜requirements.txt
┗ 📜__init__.py
: settings에서 공개하지말아야할 ip, portnum, api_key를 관리
: 추가로 cross_tier 폴더를 생성했으며 여기서 위의 cross_tier png를 저장한다.
: 00시 기준으로 api test했으며 티어 업데이트 제대로 된 것을 확인!
5. fast api test
: postman 사용하여 확인
frontend는 gpt한테 맡기기로 했다...
gpt에게 물어보고 url등만 수정해서 table만 우선 api post로 받아와서 보이게 하였다.
6. winning rate 추가
: tier update를 무조건 확인하기 때문에 해당 함수에 winning rate 추가
def update_tiers(master_plus_play):
updated_master_plus_play = {}
for index, (key, entry) in enumerate(master_plus_play.items(), start=1):
previous_rank = entry["Rank"]
if index <= 300:
new_rank = "Challenger"
elif index <= 1000:
new_rank = "Grandmaster"
else:
new_rank = "Master"
if new_rank != previous_rank:
if previous_rank == "Challenger" and new_rank == "Grandmaster":
new_rank += " down"
elif previous_rank == "Grandmaster" and new_rank == "Challenger":
new_rank += " up"
elif previous_rank == "Grandmaster" and new_rank == "Master":
new_rank += " down"
elif previous_rank == "Master" and new_rank == "Grandmaster":
new_rank += " up"
updated_master_plus_play[key] = {
"Name": entry["Name"],
"Rank": new_rank,
"LP": entry["LP"],
"wins": entry["wins"],
"losses": entry["losses"],
"winning_rate": str(round(entry["wins"]*100/(entry["wins"]+entry["losses"]),2))+"%"
}
return updated_master_plus_play
encode된 user name을 decode하고, 분석을 도입하려 했으나, API 호출 제한으로 인해 불가능,
따라서 다른 게임에 대한 dataset을 구해보고, 그 게임으로 분석하도록하겠다...
'Project > Data_Analysis' 카테고리의 다른 글
분석 1차(승리 예측) (0) | 2024.12.05 |
---|---|
데이터셋 확보 및 진행 (1) | 2024.12.05 |