散点图.png 横坐标:面积大小
总坐标:总人口
图例:暂时看不出是什么总而言之看起来是类型,一种类型一个颜色

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib as mpl
  4. import matplotlib.pyplot as plt
  5. import seaborn as sns
  6. %matplotlib inline
  1. # 定义数据
  2. x1 = np.random.randn(10)
  3. x2 = x1 + x1**2 - 10
  4. # 确定画布 - 当只有一张图时不需要此步骤
  5. plt.figure(figsize = (8, 4))
  6. # 绘图
  7. plt.scatter(x1, x2 # 横坐标,纵坐标
  8. , s = 50 # 数据点尺寸大小
  9. , c = 'r' # 数据点颜色
  10. , label = 'Positive')
  11. # 装饰图形
  12. plt.legend() # 显示图例
  13. plt.show() # 显示图形

output_3_0.png

  1. # 增加标签列y
  2. x = np.random.randn(10, 2) # 10行2列的数据集
  3. y = np.array([0, 0, 1, 1, 0, 1, 0, 1, 0, 0])
  4. plt.figure(figsize = (8, 4))
  5. plt.scatter(x[:, 0], x[:, 1]
  6. , s = 50
  7. , c = y # 分类可视化
  8. , label = ['Zero', 'One'] # 无法显示理想的结果
  9. #, label = ['Zero', 'Zero', 'One', 'One', 'Zero', 'One', 'Zero', 'One', 'Zero', 'Zero'] 也无法显示理想的结果
  10. )
  11. plt.legend()
  1. <matplotlib.legend.Legend at 0x10fc64c2710>

output_4_1.png

  1. x[:, 0]
  1. array([ 1.31449649, -2.09365277, -0.90142206, -0.80960202, 0.46194326,
  2. -0.79169922, 0.74378866, 0.63288047, -0.51673112, 0.22944999])
  1. x[:, 1]
  1. array([ 0.1774639 , 0.41847597, -0.00806844, -1.84772107, -0.56667279,
  2. 1.38507805, -1.20056857, 0.65070988, -0.45736285, -0.35242212])
  1. y
  1. array([0, 0, 1, 1, 0, 1, 0, 1, 0, 0])

【核心知识点】可视化分类标签时的图例

如果我们希望显示多种颜色的散点图,并且这个颜色是我们的标签y所代表的分类,那我们无法让散点图显示分别代表不同颜色的图例

  1. colors = ['red', 'black'] # 建立颜色列表
  2. labels = ['Zero', 'One'] # 建立标签的类型列表
  3. for i in range(x.shape[1]):
  4. plt.scatter(x[y == i, 0], # 布尔索引取值
  5. x[y == i, 1],
  6. c = colors[i],
  7. label = labels[i])
  8. # 两次作图都在同一张画布上
  9. # 在标签中存在几种类别,我们就要循环几次,一次画一个颜色的点
  10. plt.legend()
  1. <matplotlib.legend.Legend at 0x10fc6537da0>

output_9_1.png

  1. for i in ([y == 1, 0]):
  2. print(i)
  1. [False False True True False True False True False False]
  2. 0

复杂图像绘制

需要找到三种元素:

  1. 绘图用数据x1和x2
  2. 标签的列表
  3. 标签对应的颜色

1. 开始认识绘图所需要的数据

  1. # 导入数据
  2. midwest = pd.read_csv("midwest_filter.csv")
  1. # 探索数据
  1. midwest.info()
  1. <class 'pandas.core.frame.DataFrame'>
  2. RangeIndex: 332 entries, 0 to 331
  3. Data columns (total 29 columns):
  4. PID 332 non-null int64
  5. county 332 non-null object
  6. state 332 non-null object
  7. area 332 non-null float64
  8. poptotal 332 non-null int64
  9. popdensity 332 non-null float64
  10. popwhite 332 non-null int64
  11. popblack 332 non-null int64
  12. popamerindian 332 non-null int64
  13. popasian 332 non-null int64
  14. popother 332 non-null int64
  15. percwhite 332 non-null float64
  16. percblack 332 non-null float64
  17. percamerindan 332 non-null float64
  18. percasian 332 non-null float64
  19. percother 332 non-null float64
  20. popadults 332 non-null int64
  21. perchsd 332 non-null float64
  22. percollege 332 non-null float64
  23. percprof 332 non-null float64
  24. poppovertyknown 332 non-null int64
  25. percpovertyknown 332 non-null float64
  26. percbelowpoverty 332 non-null float64
  27. percchildbelowpovert 332 non-null float64
  28. percadultpoverty 332 non-null float64
  29. percelderlypoverty 332 non-null float64
  30. inmetro 332 non-null int64
  31. category 332 non-null object
  32. dot_size 332 non-null float64
  33. dtypes: float64(16), int64(10), object(3)
  34. memory usage: 75.3+ KB
  1. midwest.head()
PID county state area poptotal popdensity popwhite popblack popamerindian popasian … percprof poppovertyknown percpovertyknown percbelowpoverty percchildbelowpovert percadultpoverty percelderlypoverty inmetro category dot_size
0 561 ADAMS IL 0.052 66090 1270.961540 63917 1702 98 249 … 4.355859 63628 96.274777 13.151443 18.011717 11.009776 12.443812 0 AAR 250.944411
1 562 ALEXANDER IL 0.014 10626 759.000000 7054 3496 19 48 … 2.870315 10529 99.087145 32.244278 45.826514 27.385647 25.228976 0 LHR 185.781260
2 563 BOND IL 0.022 14991 681.409091 14477 429 35 16 … 4.488572 14235 94.956974 12.068844 14.036061 10.852090 12.697410 0 AAR 175.905385
3 564 BOONE IL 0.017 30806 1812.117650 29344 127 46 150 … 4.197800 30337 98.477569 7.209019 11.179536 5.536013 6.217047 1 ALU 319.823487
4 565 BROWN IL 0.018 5836 324.222222 5264 547 14 5 … 3.367680 4815 82.505140 13.520249 13.022889 11.143211 19.200000 0 AAR 130.442161

5 rows × 29 columns

  1. midwest.columns
  1. Index(['PID', 'county', 'state', 'area', 'poptotal', 'popdensity', 'popwhite',
  2. 'popblack', 'popamerindian', 'popasian', 'popother', 'percwhite',
  3. 'percblack', 'percamerindan', 'percasian', 'percother', 'popadults',
  4. 'perchsd', 'percollege', 'percprof', 'poppovertyknown',
  5. 'percpovertyknown', 'percbelowpoverty', 'percchildbelowpovert',
  6. 'percadultpoverty', 'percelderlypoverty', 'inmetro', 'category',
  7. 'dot_size'],
  8. dtype='object')

2. 准备标签的列表和颜色

标签

  1. # 提取标签中的类别
  2. # set(midwest['category'])
  3. categories = np.unique(midwest['category'])
  4. categories # 这就是我们要使用的标签的类别
  1. array(['AAR', 'AAU', 'AHR', 'ALR', 'ALU', 'HAR', 'HAU', 'HHR', 'HLR',
  2. 'HLU', 'LAR', 'LAU', 'LHR', 'LHU'], dtype=object)
  1. len(categories)
  1. 14

颜色

接下来要创造和标签的类别一样多的颜色

如果只有三四个类别,或许还可以自己写

然而面对十几个,或者二十个分类,我们需要让Matplotlib来自动生成颜色

plt.cm.tab10()

colormap cm.光带名(),将光带作为函数调用

用于创建颜色的十号光谱,在matplotlib中,有众多光谱选择:https://matplotlib.org/tutorials/colors/colormaps.html

在plt.cm.tab10()中输入任意浮点数,来提取出一种颜色

光谱tab10中总共只有十种颜色,如果输入的浮点数比较接近,会返回类似的颜色

这种颜色会以元祖的形式返回,表示为四个浮点数组成的RGBA色彩空间或者三个浮点数组成的RGB色彩空间中的随机色彩

  1. color1 = plt.cm.tab10(5.2)
  2. x1 = np.random.randn(10)
  3. x2 = x1 + x1**2 - 10
  4. plt.scatter(x1, x2, s = 50, c = color1)
  1. 'c' argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with 'x' & 'y'. Please use a 2-D array with a single row if you really want to specify the same RGB or RGBA value for all points.
  2. <matplotlib.collections.PathCollection at 0x10fc6678da0>

output_23_2.png

‘c’参数看起来像一个单一的RGB或RGBA数字序列,应避免使用它,因为如果其长度与’x’和’y’匹配,则值映射将具有优先级。如果您确实要为所有点指定相同的RGB或RGBA值,请使用二维数组与一行。

  1. color1 # 一维元组
  1. (0.09019607843137255, 0.7450980392156863, 0.8117647058823529, 1.0)
  1. np.array(color1) # 一维数组,此时对象不分行列;升维前的准备
  1. array([0.09019608, 0.74509804, 0.81176471, 1. ])
  1. np.array(color1).reshape(1, -1) # reshape():改变数组结构,此处用来增维,输入(1, -1)是让行上的维度为1,(-1, 1)是让列上的维度为1
  2. # 一行四列
  1. array([[0.09019608, 0.74509804, 0.81176471, 1. ]])
  1. np.array(color1).reshape(-1, 1)
  2. # 一列四行
  1. array([[0.09019608],
  2. [0.74509804],
  3. [0.81176471],
  4. [1. ]])
  1. color1 = plt.cm.tab10(5.2)
  2. x1 = np.random.randn(10)
  3. x2 = x1 + x1**2 - 10
  4. plt.scatter(x1, x2, s = 50, c = np.array(color1).reshape(1, -1))
  1. <matplotlib.collections.PathCollection at 0x10fc66ea780>

output_29_1.png

3. 生成图像

  1. midwest.head()
PID county state area poptotal popdensity popwhite popblack popamerindian popasian … percprof poppovertyknown percpovertyknown percbelowpoverty percchildbelowpovert percadultpoverty percelderlypoverty inmetro category dot_size
0 561 ADAMS IL 0.052 66090 1270.961540 63917 1702 98 249 … 4.355859 63628 96.274777 13.151443 18.011717 11.009776 12.443812 0 AAR 250.944411
1 562 ALEXANDER IL 0.014 10626 759.000000 7054 3496 19 48 … 2.870315 10529 99.087145 32.244278 45.826514 27.385647 25.228976 0 LHR 185.781260
2 563 BOND IL 0.022 14991 681.409091 14477 429 35 16 … 4.488572 14235 94.956974 12.068844 14.036061 10.852090 12.697410 0 AAR 175.905385
3 564 BOONE IL 0.017 30806 1812.117650 29344 127 46 150 … 4.197800 30337 98.477569 7.209019 11.179536 5.536013 6.217047 1 ALU 319.823487
4 565 BROWN IL 0.018 5836 324.222222 5264 547 14 5 … 3.367680 4815 82.505140 13.520249 13.022889 11.143211 19.200000 0 AAR 130.442161

5 rows × 29 columns

方法一

  1. plt.figure(figsize = (16, 10))
  2. # 循环次数 = 标签数 = 颜色数 = 需要生成的小数的个数
  3. for i in range(len(categories)):
  4. plt.scatter(midwest.loc[midwest['category'] == categories[i], 'area'],
  5. midwest.loc[midwest['category'] == categories[i], 'poptotal'],
  6. s = 20,
  7. c = np.array(plt.cm.tab10(i / len(categories))).reshape(1, -1),
  8. label = categories[i])
  9. plt.legend()
  1. <matplotlib.legend.Legend at 0x10fc670ce10>

output_33_1.png

方法二

  1. # 列表推导式生成颜色列表,然后用索引将颜色依次取出
  2. colors = [plt.cm.tab10(i/float(len(categories) - 1)) for i in range(len(categories))]
  3. '''
  4. 等同于:
  5. colors = []
  6. for i in range(len(categories)):
  7. colors.append(plt.cm.tab10(i/float(len(categories) - 1)))
  8. '''
  9. plt.figure(figsize = (16, 10))
  10. for i in range(len(categories)):
  11. plt.scatter(midwest.loc[midwest['category'] == categories[i], 'area'],
  12. midwest.loc[midwest['category'] == categories[i], 'poptotal'],
  13. s = 20,
  14. c = np.array(colors[i]).reshape(1, -1),
  15. label = categories[i])
  16. plt.legend()
  1. <matplotlib.legend.Legend at 0x10fc6b5df98>

output_35_1.png

  1. colors # 一个列表,包含14个元组
  1. [(0.12156862745098039, 0.4666666666666667, 0.7058823529411765, 1.0),
  2. (0.12156862745098039, 0.4666666666666667, 0.7058823529411765, 1.0),
  3. (1.0, 0.4980392156862745, 0.054901960784313725, 1.0),
  4. (0.17254901960784313, 0.6274509803921569, 0.17254901960784313, 1.0),
  5. (0.8392156862745098, 0.15294117647058825, 0.1568627450980392, 1.0),
  6. (0.8392156862745098, 0.15294117647058825, 0.1568627450980392, 1.0),
  7. (0.5803921568627451, 0.403921568627451, 0.7411764705882353, 1.0),
  8. (0.5490196078431373, 0.33725490196078434, 0.29411764705882354, 1.0),
  9. (0.8901960784313725, 0.4666666666666667, 0.7607843137254902, 1.0),
  10. (0.8901960784313725, 0.4666666666666667, 0.7607843137254902, 1.0),
  11. (0.4980392156862745, 0.4980392156862745, 0.4980392156862745, 1.0),
  12. (0.7372549019607844, 0.7411764705882353, 0.13333333333333333, 1.0),
  13. (0.09019607843137255, 0.7450980392156863, 0.8117647058823529, 1.0),
  14. (0.09019607843137255, 0.7450980392156863, 0.8117647058823529, 1.0)]

参考

  1. # 预设图像的各种属性
  2. large = 22; med = 16; small = 12
  3. params = {'legend.fontsize': med, # 图例的字体大小
  4. 'figure.figsize': (16, 10), # 图像的画布大小
  5. 'axes.labelsize': med, # 标签的字体大小
  6. 'axes.titlesize': med, # 子图上的标题字体大小
  7. 'xtick.labelsize': med, # x轴上的标尺的字体大小
  8. 'ytick.labelsize': med, # y轴上的标尺的字体大小
  9. 'figure.titlesize': large} # 整个画布的标题字体大小
  10. plt.rcParams.update(params) # 设定各种默认风格
  11. plt.style.use('seaborn-whitegrid') # 设定整体风格
  12. sns.set_style("white") # 设定整体背景风格
  13. # Prepare Data
  14. # Create as many colors as there are unique midwest['category']
  15. categories = np.unique(midwest['category'])
  16. colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
  17. # Draw Plot for Each Category
  18. plt.figure(figsize=(16, 10) # 绘图尺寸
  19. , dpi= 80 # 图像分辨率
  20. , facecolor='w' # 图像的背景颜色,设置为白色,默认也是白色
  21. , edgecolor='k' # 图像的边框颜色,设置为黑色,默认也是黑色
  22. )
  23. for i, category in enumerate(categories):
  24. plt.scatter('area', 'poptotal',
  25. data=midwest.loc[midwest.category==category, :],
  26. s=20, c=np.array(colors[i]).reshape(1, -1), label=str(category))
  27. # Decorations
  28. # plt.gca() 获取当前子图;若当前没有子图,则创建子图
  29. plt.gca().set(xlim=(0.0, 0.12), ylim=(0, 90000), # 控制横纵坐标的范围
  30. xlabel='Area', ylabel='Population')
  31. plt.xticks(fontsize=12); plt.yticks(fontsize=12)
  32. plt.title("Scatterplot of Midwest Area vs Population", fontsize=22)
  33. plt.legend(fontsize=12, loc =0)
  34. plt.show()

output_38_0.png

探索数据

异常值

  1. midwest[midwest['area'] > 0.1]
PID county state area poptotal popdensity popwhite popblack popamerindian popasian … percprof poppovertyknown percpovertyknown percbelowpoverty percchildbelowpovert percadultpoverty percelderlypoverty inmetro category dot_size
196 1248 MARQUETTE MI 0.11 70887 644.427273 68027 1170 943 538 … 6.799415 66398 93.667386 12.608814 14.26216 11.84465 12.523891 0 HAR 171.19829

1 rows × 29 columns

标签含义探索

  1. midwest['category'].value_counts()
  1. AAR 186
  2. LAR 30
  3. LHR 27
  4. AAU 21
  5. AHR 16
  6. ALU 14
  7. ALR 11
  8. HLU 10
  9. HAR 6
  10. HAU 3
  11. LAU 3
  12. LHU 2
  13. HLR 2
  14. HHR 1
  15. Name: category, dtype: int64
  1. midwest['c1'] = midwest['category'].apply(lambda x : x[0])
  2. midwest['c2'] = midwest['category'].apply(lambda x : x[1])
  3. midwest['c3'] = midwest['category'].apply(lambda x : x[2])
  4. midwest.head()
PID county state area poptotal popdensity popwhite popblack popamerindian popasian … percbelowpoverty percchildbelowpovert percadultpoverty percelderlypoverty inmetro category dot_size c1 c2 c3
0 561 ADAMS IL 0.052 66090 1270.961540 63917 1702 98 249 … 13.151443 18.011717 11.009776 12.443812 0 AAR 250.944411 A A R
1 562 ALEXANDER IL 0.014 10626 759.000000 7054 3496 19 48 … 32.244278 45.826514 27.385647 25.228976 0 LHR 185.781260 L H R
2 563 BOND IL 0.022 14991 681.409091 14477 429 35 16 … 12.068844 14.036061 10.852090 12.697410 0 AAR 175.905385 A A R
3 564 BOONE IL 0.017 30806 1812.117650 29344 127 46 150 … 7.209019 11.179536 5.536013 6.217047 1 ALU 319.823487 A L U
4 565 BROWN IL 0.018 5836 324.222222 5264 547 14 5 … 13.520249 13.022889 11.143211 19.200000 0 AAR 130.442161 A A R

5 rows × 32 columns

猜测

  1. midwest['c1'].value_counts() # Averaage/High/Low
  1. A 248
  2. L 62
  3. H 22
  4. Name: c1, dtype: int64
  1. midwest['c2'].value_counts() # Averaage/High/Low
  1. A 249
  2. H 46
  3. L 37
  4. Name: c2, dtype: int64
  1. midwest['c3'].value_counts() # Rural/Urban
  1. R 279
  2. U 53
  3. Name: c3, dtype: int64

机器学习检验猜测:逻辑回归探索数据集

数据预处理

  1. from sklearn.preprocessing import OrdinalEncoder as OE
  2. data = midwest.copy()
  3. data.iloc[:, -3:].head()
c1 c2 c3
0 A A R
1 L H R
2 A A R
3 A L U
4 A A R
  1. data.iloc[:, -3:] = OE().fit_transform(data.iloc[:, -3:])
  2. data.iloc[:, -3:].head()
  3. # Low = 2
  4. # Average = 0
  5. # High = 1
  6. # Rural = 0
  7. # Urban = 1
c1 c2 c3
0 0.0 0.0 0.0
1 2.0 1.0 0.0
2 0.0 0.0 0.0
3 0.0 2.0 1.0
4 0.0 0.0 0.0
  1. data.info()
  1. <class 'pandas.core.frame.DataFrame'>
  2. RangeIndex: 332 entries, 0 to 331
  3. Data columns (total 32 columns):
  4. PID 332 non-null int64
  5. county 332 non-null object
  6. state 332 non-null object
  7. area 332 non-null float64
  8. poptotal 332 non-null int64
  9. popdensity 332 non-null float64
  10. popwhite 332 non-null int64
  11. popblack 332 non-null int64
  12. popamerindian 332 non-null int64
  13. popasian 332 non-null int64
  14. popother 332 non-null int64
  15. percwhite 332 non-null float64
  16. percblack 332 non-null float64
  17. percamerindan 332 non-null float64
  18. percasian 332 non-null float64
  19. percother 332 non-null float64
  20. popadults 332 non-null int64
  21. perchsd 332 non-null float64
  22. percollege 332 non-null float64
  23. percprof 332 non-null float64
  24. poppovertyknown 332 non-null int64
  25. percpovertyknown 332 non-null float64
  26. percbelowpoverty 332 non-null float64
  27. percchildbelowpovert 332 non-null float64
  28. percadultpoverty 332 non-null float64
  29. percelderlypoverty 332 non-null float64
  30. inmetro 332 non-null int64
  31. category 332 non-null object
  32. dot_size 332 non-null float64
  33. c1 332 non-null float64
  34. c2 332 non-null float64
  35. c3 332 non-null float64
  36. dtypes: float64(19), int64(10), object(3)
  37. memory usage: 83.1+ KB
  1. data.columns = ["城市ID","郡","州","面积","总人口","人口密度","白人人口","非裔人口","美洲印第安人人口","亚洲人口","其他人种人口"
  2. ,"白人所占比例","非裔所占比例","美洲印第安人所占比例","亚洲人所占比例","其他人种比例"
  3. ,"成年人口","具有高中文凭的比率","大学文凭比例","有工作的人群比例"
  4. ,"已知贫困人口","已知贫困人口的比例","贫困线以下的人的比例","贫困线以下的儿童所占比例","贫困的成年人所占的比例","贫困的老年人所占的比例"
  5. ,"是否拥有地铁","标签","点的尺寸","c1","c2","c3"]
  1. # 去掉所有类型为'Object'的列
  2. data = data.loc[:, data.dtypes.values != 'O']
  3. data.head()
城市ID 面积 总人口 人口密度 白人人口 非裔人口 美洲印第安人人口 亚洲人口 其他人种人口 白人所占比例 … 已知贫困人口的比例 贫困线以下的人的比例 贫困线以下的儿童所占比例 贫困的成年人所占的比例 贫困的老年人所占的比例 是否拥有地铁 点的尺寸 c1 c2 c3
0 561 0.052 66090 1270.961540 63917 1702 98 249 124 96.712059 … 96.274777 13.151443 18.011717 11.009776 12.443812 0 250.944411 0.0 0.0 0.0
1 562 0.014 10626 759.000000 7054 3496 19 48 9 66.384340 … 99.087145 32.244278 45.826514 27.385647 25.228976 0 185.781260 2.0 1.0 0.0
2 563 0.022 14991 681.409091 14477 429 35 16 34 96.571276 … 94.956974 12.068844 14.036061 10.852090 12.697410 0 175.905385 0.0 0.0 0.0
3 564 0.017 30806 1812.117650 29344 127 46 150 1139 95.254171 … 98.477569 7.209019 11.179536 5.536013 6.217047 1 319.823487 0.0 2.0 1.0
4 565 0.018 5836 324.222222 5264 547 14 5 6 90.198766 … 82.505140 13.520249 13.022889 11.143211 19.200000 0 130.442161 0.0 0.0 0.0

5 rows × 29 columns

  1. # 将所有整数类型的列转换为浮点数类型
  2. for i in range(data.loc[:, data.dtypes.values == 'int64'].shape[1]):
  3. data.loc[i, data.dtypes.values == 'int64'] = data.loc[i, data.dtypes.values == 'int64'].apply(lambda x : float(x))
  1. data.info()
  1. <class 'pandas.core.frame.DataFrame'>
  2. RangeIndex: 332 entries, 0 to 331
  3. Data columns (total 29 columns):
  4. 城市ID 332 non-null float64
  5. 面积 332 non-null float64
  6. 总人口 332 non-null float64
  7. 人口密度 332 non-null float64
  8. 白人人口 332 non-null float64
  9. 非裔人口 332 non-null float64
  10. 美洲印第安人人口 332 non-null float64
  11. 亚洲人口 332 non-null float64
  12. 其他人种人口 332 non-null float64
  13. 白人所占比例 332 non-null float64
  14. 非裔所占比例 332 non-null float64
  15. 美洲印第安人所占比例 332 non-null float64
  16. 亚洲人所占比例 332 non-null float64
  17. 其他人种比例 332 non-null float64
  18. 成年人口 332 non-null float64
  19. 具有高中文凭的比率 332 non-null float64
  20. 大学文凭比例 332 non-null float64
  21. 有工作的人群比例 332 non-null float64
  22. 已知贫困人口 332 non-null float64
  23. 已知贫困人口的比例 332 non-null float64
  24. 贫困线以下的人的比例 332 non-null float64
  25. 贫困线以下的儿童所占比例 332 non-null float64
  26. 贫困的成年人所占的比例 332 non-null float64
  27. 贫困的老年人所占的比例 332 non-null float64
  28. 是否拥有地铁 332 non-null float64
  29. 点的尺寸 332 non-null float64
  30. c1 332 non-null float64
  31. c2 332 non-null float64
  32. c3 332 non-null float64
  33. dtypes: float64(29)
  34. memory usage: 75.3 KB

构建训练集和测试集

  1. 筛选列作为特征矩阵
  2. 其他列作为目标向量
  3. 分训练集和测试集
  4. 数据标准化(线性模型的核心需求)
  1. X = data.iloc[:, 1:-3]
  2. X.head()
面积 总人口 人口密度 白人人口 非裔人口 美洲印第安人人口 亚洲人口 其他人种人口 白人所占比例 非裔所占比例 … 大学文凭比例 有工作的人群比例 已知贫困人口 已知贫困人口的比例 贫困线以下的人的比例 贫困线以下的儿童所占比例 贫困的成年人所占的比例 贫困的老年人所占的比例 是否拥有地铁 点的尺寸
0 0.052 66090.0 1270.961540 63917.0 1702.0 98.0 249.0 124.0 96.712059 2.575276 … 19.631392 4.355859 63628.0 96.274777 13.151443 18.011717 11.009776 12.443812 0.0 250.944411
1 0.014 10626.0 759.000000 7054.0 3496.0 19.0 48.0 9.0 66.384340 32.900433 … 11.243308 2.870315 10529.0 99.087145 32.244278 45.826514 27.385647 25.228976 0.0 185.781260
2 0.022 14991.0 681.409091 14477.0 429.0 35.0 16.0 34.0 96.571276 2.861717 … 17.033819 4.488572 14235.0 94.956974 12.068844 14.036061 10.852090 12.697410 0.0 175.905385
3 0.017 30806.0 1812.117650 29344.0 127.0 46.0 150.0 1139.0 95.254171 0.412257 … 17.278954 4.197800 30337.0 98.477569 7.209019 11.179536 5.536013 6.217047 1.0 319.823487
4 0.018 5836.0 324.222222 5264.0 547.0 14.0 5.0 6.0 90.198766 9.372858 … 14.475999 3.367680 4815.0 82.505140 13.520249 13.022889 11.143211 19.200000 0.0 130.442161

5 rows × 25 columns

  1. Y = data.iloc[:, -3:]
  2. Y.head()
c1 c2 c3
0 0.0 0.0 0.0
1 2.0 1.0 0.0
2 0.0 0.0 0.0
3 0.0 2.0 1.0
4 0.0 0.0 0.0
  1. from sklearn.model_selection import train_test_split as TTS
  2. Xtrain, Xtest, Ytrain, Ytest = TTS(X, Y, test_size = 0.3, random_state = 420)
  1. Xtrain.head()
面积 总人口 人口密度 白人人口 非裔人口 美洲印第安人人口 亚洲人口 其他人种人口 白人所占比例 非裔所占比例 … 大学文凭比例 有工作的人群比例 已知贫困人口 已知贫困人口的比例 贫困线以下的人的比例 贫困线以下的儿童所占比例 贫困的成年人所占的比例 贫困的老年人所占的比例 是否拥有地铁 点的尺寸
276 0.041 15682.0 382.487805 15001.0 375.0 125.0 56.0 125.0 95.657442 2.391277 … 12.427492 2.390578 14534.0 92.679505 14.435118 22.300831 13.310056 10.186757 0.0 137.858283
156 0.030 23265.0 775.500000 23127.0 2.0 50.0 41.0 45.0 99.406834 0.008597 … 16.583835 5.166100 22974.0 98.749194 7.704361 8.136567 6.168723 11.040340 0.0 187.881402
35 0.036 61067.0 1696.305560 51991.0 6342.0 109.0 2178.0 447.0 85.137636 10.385314 … 36.643665 14.089892 54230.0 88.804100 28.371750 26.392211 32.458483 13.815301 0.0 305.082769
161 0.031 18185.0 586.612903 17895.0 23.0 211.0 24.0 32.0 98.405279 0.126478 … 19.039803 5.014362 17942.0 98.663734 13.214803 18.758142 12.037542 9.681284 0.0 163.839599
321 0.079 14181.0 179.506329 11962.0 18.0 2167.0 15.0 19.0 84.352302 0.126930 … 17.947917 4.041667 13897.0 97.997320 20.544002 29.073570 19.195368 14.179318 0.0 112.022528

5 rows × 25 columns

  1. for i in [Xtrain, Xtest, Ytrain, Ytest]:
  2. i.index = range(i.shape[0])
  3. # Xtrain = Xtrain.reset_index().drop(index) 无法改变原数据
  4. Xtrain.head()
面积 总人口 人口密度 白人人口 非裔人口 美洲印第安人人口 亚洲人口 其他人种人口 白人所占比例 非裔所占比例 … 大学文凭比例 有工作的人群比例 已知贫困人口 已知贫困人口的比例 贫困线以下的人的比例 贫困线以下的儿童所占比例 贫困的成年人所占的比例 贫困的老年人所占的比例 是否拥有地铁 点的尺寸
0 0.041 15682.0 382.487805 15001.0 375.0 125.0 56.0 125.0 95.657442 2.391277 … 12.427492 2.390578 14534.0 92.679505 14.435118 22.300831 13.310056 10.186757 0.0 137.858283
1 0.030 23265.0 775.500000 23127.0 2.0 50.0 41.0 45.0 99.406834 0.008597 … 16.583835 5.166100 22974.0 98.749194 7.704361 8.136567 6.168723 11.040340 0.0 187.881402
2 0.036 61067.0 1696.305560 51991.0 6342.0 109.0 2178.0 447.0 85.137636 10.385314 … 36.643665 14.089892 54230.0 88.804100 28.371750 26.392211 32.458483 13.815301 0.0 305.082769
3 0.031 18185.0 586.612903 17895.0 23.0 211.0 24.0 32.0 98.405279 0.126478 … 19.039803 5.014362 17942.0 98.663734 13.214803 18.758142 12.037542 9.681284 0.0 163.839599
4 0.079 14181.0 179.506329 11962.0 18.0 2167.0 15.0 19.0 84.352302 0.126930 … 17.947917 4.041667 13897.0 97.997320 20.544002 29.073570 19.195368 14.179318 0.0 112.022528

5 rows × 25 columns

  1. Xtrain.iloc[:, [*range(23), -1]].head()
面积 总人口 人口密度 白人人口 非裔人口 美洲印第安人人口 亚洲人口 其他人种人口 白人所占比例 非裔所占比例 … 具有高中文凭的比率 大学文凭比例 有工作的人群比例 已知贫困人口 已知贫困人口的比例 贫困线以下的人的比例 贫困线以下的儿童所占比例 贫困的成年人所占的比例 贫困的老年人所占的比例 点的尺寸
0 0.041 15682.0 382.487805 15001.0 375.0 125.0 56.0 125.0 95.657442 2.391277 … 66.980137 12.427492 2.390578 14534.0 92.679505 14.435118 22.300831 13.310056 10.186757 137.858283
1 0.030 23265.0 775.500000 23127.0 2.0 50.0 41.0 45.0 99.406834 0.008597 … 77.877321 16.583835 5.166100 22974.0 98.749194 7.704361 8.136567 6.168723 11.040340 187.881402
2 0.036 61067.0 1696.305560 51991.0 6342.0 109.0 2178.0 447.0 85.137636 10.385314 … 78.767251 36.643665 14.089892 54230.0 88.804100 28.371750 26.392211 32.458483 13.815301 305.082769
3 0.031 18185.0 586.612903 17895.0 23.0 211.0 24.0 32.0 98.405279 0.126478 … 76.380796 19.039803 5.014362 17942.0 98.663734 13.214803 18.758142 12.037542 9.681284 163.839599
4 0.079 14181.0 179.506329 11962.0 18.0 2167.0 15.0 19.0 84.352302 0.126930 … 73.739583 17.947917 4.041667 13897.0 97.997320 20.544002 29.073570 19.195368 14.179318 112.022528

5 rows × 24 columns

  1. # 标准化数据集
  2. from sklearn.preprocessing import StandardScaler
  3. ss = StandardScaler() # 实例化
  4. ss = ss.fit(Xtrain.iloc[:, [*range(23), -1]]) # 以训练集为标准的均值和方差
  5. Xtrain_ = Xtrain.copy()
  6. Xtest_ = Xtest.copy()
  7. Xtrain_.iloc[:, [*range(23), -1]] = ss.transform(Xtrain.iloc[:, [*range(23), -1]])
  8. Xtest_.iloc[:, [*range(23), -1]] = ss.transform(Xtest.iloc[:, [*range(23), -1]])
  1. Xtrain_.head()
面积 总人口 人口密度 白人人口 非裔人口 美洲印第安人人口 亚洲人口 其他人种人口 白人所占比例 非裔所占比例 … 大学文凭比例 有工作的人群比例 已知贫困人口 已知贫困人口的比例 贫困线以下的人的比例 贫困线以下的儿童所占比例 贫困的成年人所占的比例 贫困的老年人所占的比例 是否拥有地铁 点的尺寸
0 0.616975 -0.781589 -0.817515 -0.806262 -0.109249 -0.024001 -0.298458 -0.020924 -0.560519 0.359059 … -0.879865 -0.848804 -0.824188 -1.455058 0.342460 0.839258 0.428156 -0.582661 0.0 -0.817515
1 -0.141464 -0.374282 -0.347133 -0.350269 -0.486592 -0.330845 -0.368263 -0.341073 0.588691 -0.457448 … -0.002157 0.773189 -0.351151 0.550676 -1.033914 -1.207832 -0.982892 -0.331241 0.0 -0.347133
2 0.272230 1.656180 0.754945 1.269442 5.927225 -0.089461 9.576664 1.267678 -3.784901 3.098491 … 4.233941 5.988182 1.400655 -2.735690 3.192365 1.430564 4.211672 0.486112 0.0 0.754945
3 -0.072515 -0.647145 -0.573205 -0.643865 -0.465347 0.327847 -0.447376 -0.393097 0.281709 -0.417052 … 0.516478 0.684514 -0.633180 0.522436 0.092918 0.327251 0.176721 -0.731545 0.0 -0.573205
4 3.237036 -0.862212 -1.060456 -0.976797 -0.470405 8.330347 -0.489259 -0.445122 -4.025610 -0.416897 … 0.285901 0.116079 -0.859890 0.302219 1.591667 1.818087 1.591028 0.593332 0.0 -1.060456

5 rows × 25 columns

  1. from sklearn.linear_model import LogisticRegression as logiR
  2. import pandas as pd
  3. for i in range(3): # c1,c2,c3分别建模
  4. # 实例化:
  5. logi = logiR(solver = 'newton-cg' # 本例用牛顿法结果更准确
  6. , max_iter = 100**20 # 使用牛顿法所需要的迭代次数
  7. , multi_class = 'multinomial' # 由于c1和c2是三分类(L/A/H)
  8. )
  9. # 开始建模:
  10. logi.fit(Xtrain_, Ytrain.iloc[:, i].ravel())
  11. print(Y.columns[i])
  12. print('\tTrain:{}'.format(logi.score(Xtrain_, Ytrain.iloc[:, i].ravel()))) # 模型的学习能力,以准确率衡量
  13. print('\tTest:{}'.format(logi.score(Xtest_, Ytest.iloc[:, i].ravel()))) # 模型的泛化能力
  14. coeff = pd.DataFrame(logi.coef_).T
  15. if i != 2:
  16. coeff['mean'] = abs(coeff).mean(axis = 1)
  17. coeff['name'] = Xtrain.columns
  18. coeff.columns = ['Average', 'High', 'Low', 'mean', 'name']
  19. coeff = coeff.sort_values(by = 'mean', ascending = False).head()
  20. else:
  21. coeff['name'] = Xtrain.columns
  22. coeff.columns = ['coef', 'name']
  23. coeff = coeff.sort_values(by = 'coef', ascending = False).head()
  24. print(coeff)
  25. print('\t')
  1. c1
  2. Train:0.9956896551724138
  3. Test:0.97
  4. Average High Low mean name
  5. 14 1.274035 2.189743 -3.463778 2.309186 具有高中文凭的比率
  6. 15 -0.656186 1.390281 -0.734095 0.926854 大学文凭比例
  7. 16 -0.363926 0.899042 -0.535116 0.599361 有工作的人群比例
  8. 21 0.180958 -0.662631 0.481673 0.441754 贫困的成年人所占的比例
  9. 19 0.231073 -0.534413 0.303341 0.356275 贫困线以下的人的比例
  10. c2
  11. Train:0.978448275862069
  12. Test:0.97
  13. Average High Low mean name
  14. 20 0.248239 1.652407 -1.900646 1.267097 贫困线以下的儿童所占比例
  15. 21 -0.249106 1.694901 -1.445795 1.129934 贫困的成年人所占的比例
  16. 19 0.054842 1.639717 -1.694559 1.129706 贫困线以下的人的比例
  17. 22 -0.105854 0.797378 -0.691524 0.531585 贫困的老年人所占的比例
  18. 12 -0.552268 0.258467 0.293801 0.368178 其他人种比例
  19. c3
  20. Train:1.0
  21. Test:1.0
  22. coef name
  23. 23 2.981752 是否拥有地铁
  24. 3 0.104570 白人人口
  25. 17 0.104304 已知贫困人口
  26. 1 0.096218 总人口
  27. 8 0.072634 白人所占比例

mpy.flatten() 与 numpy.ravel()的区别

  1. 要实现的功能是一致的(将多维数组降位一维)
  2. 于返回拷贝(copy)还是返回视图(view)
    1. py.flatten()返回一份拷贝,对拷贝所做的修改不会影响(reflects)原始矩阵
    2. py.ravel()返回的是视图,会影响原始矩阵
  1. # 实际上不用.ravel()降维也可以。以 i = 0 为例:
  2. from sklearn.linear_model import LogisticRegression as logiR
  3. import pandas as pd
  4. # 实例化:
  5. logi = logiR(solver = 'newton-cg' # 本例用牛顿法结果更准确
  6. , max_iter = 100 ** 20 # 使用牛顿法所需要的迭代次数
  7. , multi_class = 'multinomial' # 由于本例是三分类(A/H/L)
  8. )
  9. # 开始建模:
  10. logi.fit(Xtrain_, Ytrain.iloc[:, 0])
  11. print(Y.columns[0])
  12. print('\tTrain:{}'.format(logi.score(Xtrain_, Ytrain.iloc[:, 0]))) # 模型的学习能力
  13. print('\tTest:{}'.format(logi.score(Xtest_, Ytest.iloc[:, 0]))) # 模型的泛化能力
  14. print(logi.coef_.shape) # 25个特征;三分类(L/A/H)一对一:L vs A, L vs H, A vs H
  1. c1
  2. Train:0.9956896551724138
  3. Test:0.97
  4. (3, 25)

解读

  1. midwest['category'].value_counts()
  1. AAR 186
  2. LAR 30
  3. LHR 27
  4. AAU 21
  5. AHR 16
  6. ALU 14
  7. ALR 11
  8. HLU 10
  9. HAR 6
  10. HAU 3
  11. LAU 3
  12. LHU 2
  13. HLR 2
  14. HHR 1
  15. Name: category, dtype: int64
  1. plt.figure(figsize = (8, 6))
  2. plt.scatter(data['具有高中文凭的比率'], data['贫困线以下的儿童所占比例'])
  1. <matplotlib.collections.PathCollection at 0x10fc7943dd8>

output_72_1.png

  1. plt.figure(figsize = (8, 6))
  2. categories = np.unique(midwest['category'])
  3. colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
  4. for i, category in enumerate(categories):
  5. plt.scatter('area', 'poptotal',
  6. data=midwest.loc[midwest.category==category, :],
  7. s=20, c=np.array(colors[i]).reshape(1, -1),
  8. label=str(category))
  9. plt.legend(fontsize = 12)
  1. <matplotlib.legend.Legend at 0x10fc8aca9e8>

output_73_1.png

  1. 中西部大部分地区教育情况和贫困情况处于平均水平
  2. 蓝绿色的数据点代表教育水平低和贫困水平高,主要分布在图的左下且较为集中,人少地方也小,符合预期
    1. 有蓝绿色的数据点位于图的右上,人多且穷,需要重点观察,可以提取出来深入研究
    2. 假设LH的乡村多于LH的城市
  3. 浅粉色的数据点代表教育水平高和贫困水平低,在图上的分布显示地狭人稠
    1. 假设HL的城市多余HL的乡村
  4. 异常点:教育水平高,贫困水平也高(读书无用);教育水平低,贫困水平也低(读书更没用了)
    1. 图例上只有HHR,没有HHU
    2. 图例上没有LLU和LLR

由于只取了十种颜色(tab10),所以省略了一些信息,需要更多的颜色显示图例,才能看出城市(U)和乡村(R)的区别

  1. plt.figure(figsize = (10, 8))
  2. categories = np.unique(midwest['category'])
  3. colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
  4. for i, category in enumerate(categories):
  5. plt.scatter('area', 'poptotal',
  6. data=midwest.loc[midwest.category==category, :],
  7. s=20, c=np.array(colors[i]).reshape(1, -1),
  8. label=str(category))
  9. plt.scatter('area', 'poptotal',
  10. data=midwest.loc[midwest.category == 'LHU', :],
  11. s = 150,
  12. facecolors = 'None', # 点的填充颜色,None代表透明
  13. edgecolors = 'red', # 点的边框颜色
  14. label = 'Selected Urban')
  15. plt.scatter('area', 'poptotal',
  16. data=midwest.loc[midwest.category == 'LHR', :],
  17. s = 150,
  18. facecolors = 'None', # 点的填充颜色,None代表透明
  19. edgecolors = 'y', # 点的边框颜色
  20. label = 'Selected Rural')
  21. plt.legend(fontsize = 12)
  1. <matplotlib.legend.Legend at 0x10fca1ebd30>

output_75_1.png

教育水平低且贫困水平高的地区,多数是乡村;核心问题是乡村

  1. plt.figure(figsize = (10, 8))
  2. categories = np.unique(midwest['category'])
  3. colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
  4. for i, category in enumerate(categories):
  5. plt.scatter('area', 'poptotal',
  6. data=midwest.loc[midwest.category==category, :],
  7. s=20, c=np.array(colors[i]).reshape(1, -1),
  8. label=str(category))
  9. plt.scatter('area', 'poptotal',
  10. data=midwest.loc[midwest.category == 'HLU', :],
  11. s = 150,
  12. facecolors = 'None', # 点的填充颜色,None代表透明
  13. edgecolors = 'red', # 点的边框颜色
  14. label = 'Selected Urban')
  15. plt.scatter('area', 'poptotal',
  16. data=midwest.loc[midwest.category == 'HLR', :],
  17. s = 150,
  18. facecolors = 'None', # 点的填充颜色,None代表透明
  19. edgecolors = 'y', # 点的边框颜色
  20. label = 'Selected Rural')
  21. plt.legend(fontsize = 12)
  1. <matplotlib.legend.Legend at 0x10fca296438>

output_77_1.png

  1. plt.figure(figsize = (10, 8))
  2. categories = np.unique(midwest['category'])
  3. colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
  4. for i, category in enumerate(categories):
  5. plt.scatter('area', 'poptotal',
  6. data=midwest.loc[midwest.category==category, :],
  7. s=20, c=np.array(colors[i]).reshape(1, -1),
  8. label=str(category))
  9. plt.scatter('area', 'poptotal',
  10. data=midwest.loc[midwest.category == 'HHR', :],
  11. s = 150,
  12. facecolors = 'None', # 点的填充颜色,None代表透明
  13. edgecolors = 'red', # 点的边框颜色
  14. label = 'Selected Urban')
  15. plt.legend(fontsize = 12)
  1. <matplotlib.legend.Legend at 0x10fca31b668>

output_78_1.png

只有一个点教育水平高,贫困水平也高

  1. midwest[midwest['category'] == 'HHR']
PID county state area poptotal popdensity popwhite popblack popamerindian popasian … percbelowpoverty percchildbelowpovert percadultpoverty percelderlypoverty inmetro category dot_size c1 c2 c3
47 615 MCDONOUGH IL 0.034 35244 1036.58824 32992 1254 65 802 … 19.05208 16.009317 22.403382 12.884384 0 HHR 221.113063 H H R

1 rows × 32 columns