机器学习入门简单案例
一、NBA球员数据分析
1. 获取数据
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
data = pd.read_csv('nba_2017_nba_players_with_salary.csv')
data.head()
# 查看数据基本统计信息
data.describe()
2. 效率值相关性分析
#获取部分数据
data_cor = data.loc[:, ['RPM', 'AGE', 'SALARY_MILLIONS', 'ORB', 'DRB', 'TRB','AST', 'STL', 'BLK', 'TOV', 'PF', 'POINTS', 'GP', 'MPG', 'ORPM', 'DRPM']]
data_cor.head()
# 调用corr(),输出一个相关系数矩阵,显示 DataFrame中每两列之间的相关系数。
corr = data_cor.corr()
corr
# 绘制热力图
plt.figure(figsize=(20,8))
sns.heatmap(corr,square=True,linewidths=0.1,annot=True, fmt=".2f")
plt.show()
3. 衍生变量的一些可视化实践
以年龄为例
def age_cut(df):
if df['AGE'] <= 24:
return "young"
elif df.['AGE'] >=30:
return "old"
else:
return "best"
#使用apply对年龄进行划分
#apply() 方法可以将一个函数应用到 DataFrame 的每一行或每一列
#data["age_cut"] = data.apply(lambda x:age_cut(x),axis=1)
data["age_cut"] = data.apply(age_cut,axis=1)
data.head()
# 基于年龄段对球员薪水和效率值进行分析
plt.figure(figsize=(20,8))
plt.title("RPM and Salary")
x1 = data.loc[data.age_cut == "old"].SALARY_MILLIONS
y1 = data.loc[data.age_cut == "old"].RPM
plt.plot(x1, y1, "^")
x2 = data.loc[data.age_cut == "best"].SALARY_MILLIONS
y2 = data.loc[data.age_cut == "best"].RPM
plt.plot(x2, y2, "^")
x3 = data.loc[data.age_cut == "young"].SALARY_MILLIONS
y3 = data.loc[data.age_cut == "young"].RPM
plt.plot(x3, y3, ".")
plt.show()
multi_data = data.loc[:, ['RPM','POINTS','TRB','AST','STL','BLK','age_cut']]
sns.pairplot(multi_data, hue="age_cut")
4. 球队数据分析
#球队薪资排行
data_team = data.groupby(by='TEAM').agg({
"SALARY_MILLIONS" : np.mean})
data_team.sort_values(by="SALARY_MILLIONS",ascending=False).head()
#按照分球队分年龄段,上榜球员降序排列,如上榜球员相同,则按效率值降序排列
#agg()可以对 DataFrame 或 Series 的列应用一个或多个函数,返回一个聚合后的 DataFrame 或 Series。
data_rpm = data.groupby(by=['TEAM','age_cut']).agg({
"SALARY_MILLIONS":np.mean,"RPM":np.mean, "PLAYER":np.size})
data_rpm.head(10)
data_rpm.sort_values(by=['PLAYER','RPM'],ascending=False)
5. 球队综合实力排行
#as_index: 默认为 True,这意味着分组键将成为结果的索引。如果设置为 False,则分组键将作为常规列出现在结果中。
data_rpm1 = data.groupby(by=['TEAM'], as_index=False).agg({
'SALARY_MILLIONS':np.mean,'RPM':np.mean,
'PLAYER':np.size,'POINTS':np.mean,'eFG%':np.mean,
'MPG':np.mean,'AGE':np.mean})
data_rpm1.head(10)
利用箱线图和小提琴图进行数据分析
#isin() 用于检查 DataFrame 或 Series 中的元素是否包含在给定的值集合中。
data["TEAM"].isin(['GS', 'CLE', 'SA', 'LAC', 'OKC', 'UTAH', 'CHA', 'TOR', 'NO', 'BOS']).head(10)
plt.figure(figsize=(20,13))
#获取数据
data_team2 = data[data["TEAM"].isin(['GS', 'CLE', 'SA', 'LAC', 'OKC', 'UTAH', 'CHA', 'TOR', 'NO', 'BOS'])]
#绘制箱线图
plt.subplot(3,1,1)
sns.boxplot(x="TEAM", y="SALARY_MILLIONS", data = data_team2)
plt.subplot(3,1,2)
sns.boxplot(x="TEAM", y="AGE", data = data_team2)
plt.subplot(3,1,3)
sns.boxplot(x="TEAM", y="MPG", data = data_team2)
# 绘制小提琴图
plt.figure(figsize=(20, 10))
plt.subplot(3,1,1)
sns.violinplot(x="TEAM", y="3P%", data=data_team2)
plt.subplot(3,1,2)
sns.violinplot(x="TEAM", y="eFG%", data=data_team2)
plt.subplot(3,1,3)
sns.violinplot(x="TEAM", y="POINTS", data=data_team2)
二、租房数据分析
1. 读取数据
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
data = pd.read_csv('链家北京租房数据.csv')
print(data.shape)
data.head()
2. 数据预处理
重复值处理
#重复数据检测
#duplicated()返回一个布尔值的同形状 Series
data.duplicated()
#删除重复数据
data = data.drop_duplicates()
data.shape
空值处理
# 删除缺失数据
data = data.dropna()
data.shape
3. 数据转换类型
data["面积(㎡)"].values
将面积( m 2 m^2 m2)一列的数据转换为float类型
# 创建一个空数组
data_new = np.array([])
# 取出“⾯积”⼀列数据,将每个数据末尾的中⽂字符去除 fild_data.info()
data_area = data["面积(㎡)"].values
for i in data_area:
data_new = np.append(data_new,np.array(i[:-2]))
# 通过astype()⽅法将str类型转换为float64类型
data_area = data_new.astype(np.float64)
# ⽤新的数据替换
data.loc[:,"面积(㎡)"] = data_area
data
将“房间"替换成"室、“卫"替换成"厅”
# 获取户型一列数据
housetype_data = data["户型"]
temp_list = np.array([])
# 通过replace()方法进行替换
for i in housetype_data:
temp_list=np.append(temp_list,i.replace('房间','室'))
temp_list
data['户型'] = temp_list
data
4. 房源数量、位置分析
data['区域'].unique()
# 创建⼀个DataFrame对象
new_df = pd.DataFrame({
"区域":data['区域'].unique(),"数量":[0]*13})
new_df
# 按"区域"列将data进⾏分组,并统计每个分组的数量
groupby_area = data.groupby('区域').count()
new_df['数量']=groupby_area.values
new_df
area_new = new_df.sort_values(['数量'],ascending=False)
area_new
area_x = area_new.loc[:,'区域']
area_y = area_new.loc[:,'数量']
# 绘制柱形图
plt.figure(figsize=(18,9))
plt.bar(area_x,area_y,width=0.7)
# 将y轴坐标延长到2500
plt.ylim(0,1800)
plt.title("北京地区各区域小区数量")
plt.xlabel("区域")
plt.ylabel("数量")
for x, y in enumerate(area_y):
plt.text(x,y + 30,'%s' % y,ha='center')
plt.show()
5. 户型数量分析
#定义函数、用于计算各户型的数量
def all_house(arr):
key = np.unique(arr)
result = {
}
for i in key:
#在 NumPy 中,你可以使用布尔数组(也就是包含 True 和 False 的数组)作为索引来选择数组中的元素。
#得到一个布尔数组 mask,它的长度与 arr 相同。
#在这个布尔数组中,如果 arr 中的相应元素等于 k,那么该位置上的值就是 True;否则,该位置上的值就是 False。
mask = (i == arr)
#当你接着执行 arr[mask] 时,你实际上是在用布尔数组 mask 来索引 arr。
#在这种情况下,只有当 mask 中的值为 True 时,arr 中的相应元素才会被选中。
arr_new = arr[mask]
v = arr_new.size
result[i] = v
return result
# 获取户型数据
house_array = data['户型']
house_info = all_house(house_array)
house_info
# 使用字典推导式将户型数量大于50的元素筛选出来。使用items获取键值对视图
# items() 方法返回的对象是一个迭代器,你可以通过循环来遍历它,但不能直接通过索引访问。
house_type = dict((key,value) for key,value in house_info.items() if value > 50)
house_type
# 转换成DataFrame对象
# keys()、values()返回字典中所有值的视图
show_house = pd.DataFrame({
'户型':list(house_type.keys()),'数量':[x for x in house_type.values()]})
show_house
house_y = show_house['户型']
house_x = show_house['数量']
plt.figure(figsize = (20,8))
plt.barh(house_y,house_x)
# 把x轴坐标延⻓到2500
plt.xlim(0,2500)
plt.xlabel("数量")
plt.ylabel("户型种类")
plt.title("北京地区各户型房屋数量")
for x, y in enumerate(house_x):
plt.text(y + 30, x , '%s' % y)
plt.show()
6. 平均租金分析
df_all = pd.DataFrame({
'区域':data['区域'].unique(),'房租总金额':[0] * 13,'总面积(㎡)':[0] * 13})
df_all
#计算各区域的总价格和总面积
#sum_price = data.groupby('区域')['价格(元/月)'].sum()
sum_price = data['价格(元/月)'].groupby(data['区域']).sum()
sum_area = data['面积(㎡)'].groupby(data['区域']).sum()
df_all['房租总金额'] = sum_price.values
df_all['总面积(㎡)'] = sum_area.values
df_all
print(df_all.dtypes)
总面积是object类型,所以需要转换为数值类型才能够进行数学运算。
# 将 '总面积(㎡)' 列转换为数值类型
# errors='coerce'将无法转换的值替换为 NaN
df_all["总面积(㎡)"] = pd.to_numeric(df_all["总面积(㎡)"], errors='coerce')
# 计算各个区域每平方米的房租
df_all["每平米租金(元)"] = round(df_all["房租总金额"] / df_all["总面积(㎡)"], 2)
df_all
# 合并new_df与df_all
df_merge = pd.merge(new_df,df_all)
df_merge
y_house = df_merge['数量']
x = df_merge['区域']
y_price = df_merge['每平米租金(元)']
fig = plt.figure(figsize = (20,8))
ax1 = fig.add_subplot(111)
ax1.bar(x,y_house,label = '数量')
ax1.set_ylabel('数量')
ax1.legend(loc = 2)
#创建一个新的轴 (ax2),它与现有的轴 (ax1) 共享同一个 x 轴,但拥有独立的 y 轴
ax2 = ax1.twinx()
ax2.plot(x,y_price,'or-',label = '价格') #'or-'显示那个⼩红圆点
ax2.set_ylabel('价格')
ax2.set_ylim([0, 200])
# for i,(_x,_y) in enumerate(zip(range(13),y_price)):
# plt.text(_x,_y,y_price[i])
# for x,(_x,y) in enumerate(zip(x,y_price)):
# plt.text(x,y,'%s' % y)
for x,y in enumerate(y_price):
plt.text(x,y,'%s' % y)
ax2.legend(loc = 1)
plt.show()
7. 面积区间分析
area_max = data['面积(㎡)'].max()
area_min = data['面积(㎡)'].min()
print(area_max,area_min)
#cut()将连续的数值数据分割成离散的区间
area_divide = [1, 30, 50, 70, 90, 120, 140, 160, 1200]
area_cut = pd.cut(list(data['面积(㎡)']),area_divide)
area_cut
#describe显示各个区间出现的次数( counts表示)以及频率(freps表示)
area_cut_data = area_cut.describe()
area_cut_data
area_percentage = (area_cut_data['freqs'].values) * 100
labels = ['30平米以下', '30-50平米', '50-70平米', '70-90平米','90-120平米','120-140平米','140-160平米','160平米以上']
plt.figure(figsize = (20,8))
plt.pie(area_percentage,labels=labels,autopct='%.2f %%',radius=0.8)
plt.legend(loc=1)
plt.show()