1.导入数据
import os
import pandas as pd
import matplotlib.pyplot as plt
os.chdir("/Users/liyili2/Downloads/datas/")
data=pd.read_csv(r"courses.csv")
2.将时间列字段转化为index。然后进行重采样操作。
index=pd.to_datetime(data['创建时间'])
df=pd.DataFrame(data=data.values,columns=data.columns,index=index)
df=df.drop("创建时间",axis=1)
df_w=df.resample('W').sum()
3.课程学习人数和学习时间。人均学习时间计算。
# 每次做单独分析时,最好复制一份整理好的数据,减少对原数据集影响
df_A = df.copy()
# 计算平均学习时间并添加列
df_A['平均学习时间'] = df_A['学习时间']/df_A['学习人数']
df_A.head() # 预览
df_A.sort_values(by='平均学习时间',ascending=False)
df_A['平均学习时间/人数']=df_A['平均学习时间']/df_A['学习人数']
df_A=df_A.sort_values(by='平均学习时间/人数',ascending=False)
plt.scatter(df_A["平均学习时间"], df_A["学习人数"])
plt.xlabel('Average Study Time')
plt.ylabel("Number of Users")
4.对课程进行分类操作
导入 jieba 分词模块
from jieba import analyse
a = []
for i in df_A['课程名称']:
# 使用 jieba 分词并使用 TF-IDF 算法抽取两个关键词,仅返回英文、名词、动词、动名词
a.append(analyse.extract_tags(i, topK=2, withWeight=False,
allowPOS=('eng', 'n', 'vn', 'v')))
keywords = pd.DataFrame(a, columns=['关键词 1', '关键词 2'])
keywords.head()
df_B=df_A.copy()
# 复制一份数据集用于聚类
df_B = df_A.copy()
# 重置索引方便数据集拼接
df_B = df_B.reset_index()
# 将复制数据集与关键词数据集拼接,并删掉时间列
df_merged = pd.concat(
[df_B, keywords], axis=1).drop("创建时间", axis=1)
# 预览合并后数据集
df_merged.head()
#为了方便聚类,我们这里针对关键词进行独热编码处理:
# 针对关键词进行独热编码处理
onehot = pd.get_dummies(df_merged[['关键词 1', '关键词 2']])
# 预览
onehot.head()
from sklearn.decomposition import PCA
# 将特征缩小至 5 维
pca = PCA(n_components=5)
# 返回降维后的值
feature_pca = pca.fit_transform(onehot)
feature_pca.shape
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# 建立模型
score = []
# 依次轮廓系数
for i in range(10):
model = KMeans(n_clusters=i+2)
model.fit(feature_pca)
score.append(silhouette_score(feature_pca, model.labels_))
# 轮廓系数绘图
plt.figure(figsize=(20,16))
plt.plot(range(2, 12, 1), score)
#从轮廓系数反映的图像来看,我们可以定 K=6,即将课程聚为 6 类。
# 执行聚类
model = KMeans(n_clusters=6)
model.fit(feature_pca)
# 将类别列添加到数据集中
courses_ts_final = pd.concat(
[df_merged, pd.Series(model.labels_, name='类别')], axis=1)
# 依照类别排序并预览数据
courses_ts_final.sort_values(by='类别',ascending=False)