python - 在函数中返回 None:TypeError:“NoneType”类型的对象没有 len()
问题描述
我正在尝试从每个主题中打印我的主题和文本LDA
。但是打印主题后的 None 会破坏我的脚本。我可以打印我的主题,但不能打印文本。
import pandas
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
n_top_words = 5
n_components = 5
def print_top_words(model, feature_names, n_top_words):
for topic_idx, topic in enumerate(model.components_):
message = "Topic #%d: " % topic_idx
message += " ".join([feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1]])
return message
text = pandas.read_csv('text.csv', encoding = 'utf-8')
text_list = text.values.tolist()
tf_vectorizer = CountVectorizer()
tf = tf_vectorizer.fit_transform(text_list)
lda = LatentDirichletAllocation(n_components=n_components, learning_method='batch', max_iter=25, random_state=0)
doc_distr = lda.fit_transform(tf)
tf_feature_names = tf_vectorizer.get_feature_names()
print (print_top_words(lda, tf_feature_names, n_top_words))
doc_distr = lda.fit_transform(tf)
topics = print_top_words(lda, tf_feature_names, n_top_words)
for i in range(len(topics)):
print ("Topic {}:".format(i))
docs = np.argsort(doc_distr[:, i])[::-1]
for j in docs[:10]:
print (" ".join(text_list[j].split(",")[:2]))
我的输出:
Topic 0: no order mail received back
Topic 1: cancel order wishes possible wish
Topic 2: keep current informed delivery order
Topic 3: faulty wooden box present side
Topic 4: delivered received be produced urgent
Topic 5: good waiting day response share
随后出现此错误:
File "lda.py", line 41, in <module>
for i in range(len(topics)):
TypeError: object of type 'NoneType' has no len()
解决方案
您的功能有(至少)四个问题print_top_words()
。
第一个 - 导致您当前的问题 - 如果model.components_
为空,则 for 循环的主体将不会执行,然后您的函数将(隐式)返回None
。
第二个更微妙:如果model.components_
不为空,函数将只返回第一条消息,然后返回并退出 - 这正是return
语句的定义:返回一个值(或者None
如果没有指定值)并退出功能。
第三个问题是(当model.components_
不为空时),函数返回一个字符串,其中调用代码显然需要一个列表。这是一个微妙的错误,因为字符串有一个长度,所以 for 循环range(len(topics))
似乎可以工作,但len(topics)
肯定不是您期望的值。
最后,这个函数的名字很糟糕,因为它没有“打印”任何东西——与前三个问题相比,这似乎微不足道,而且它不会阻止代码确实工作(假设前三个问题已修复),但是对代码的推理本身就足够困难,因此正确的命名很重要,因为它大大减少了认知负担并使维护/调试更容易。
长话短说:想想你真正想要这个函数做什么并适当地修复它。我不会在这里发布“更正”的版本,因为我不确定您要做什么,但上述说明应该会有所帮助。
注意:另外,您使用完全相同的参数调用doc_distr = lda.fit_transform(tf)
andprint_top_words(lda, tf_feature_names, n_top_words)
两次,这要么完全没用,而且纯粹浪费处理器周期(在最好的情况下),或者如果您从第二次调用中得到不同的结果,则可能会产生另一个错误的气味.
推荐阅读
- sql - 在 SQL Unpivot 中包含列名
- c# - ASP.NET Core react - 将 Okta 选项从 ASP.NET Core 传递到 ReactJS 应用程序
- python - 任意进程的python进程间互斥锁
- android - Presigned APK 在 AOSP 构建中丢失签名
- python - 在 altair 中设置单个点标记的大小
- powershell - Powershell 多字符串读取控制台
- git - 对于 Git,相同的提交哈希值意味着相同的存储库是绝对正确的吗?
- tensorflow - TensorFlow Transform 调试和迭代开发最佳实践?
- android - 如何在 MAC OSX Yosemite 10 中修复“AVD 的模拟器进程被杀死”
- sql - 子查询作为嵌套 SQL 列表的元素